LockfileBuilder

Struct LockfileBuilder 

Source
pub struct LockfileBuilder<'a> { /* private fields */ }
Expand description

Manages lockfile operations including entry creation, updates, and cleanup.

Implementations§

Source§

impl<'a> LockfileBuilder<'a>

Source

pub fn new(manifest: &'a Manifest) -> Self

Create a new lockfile builder with the given manifest.

Source

pub fn add_or_update_lockfile_entry( &self, lockfile: &mut LockFile, _name: &str, entry: LockedResource, )

Add or update a lockfile entry with deterministic merging for duplicates.

This method handles deduplication by using (name, source, tool) tuples as the unique key. When duplicates are found, it uses a deterministic merge strategy to ensure consistent lockfile generation across runs, regardless of processing order.

§Merge Strategy (deterministic, order-independent)

When merging duplicate entries:

  1. Prefer direct manifest dependencies (has manifest_alias) over transitive dependencies
  2. Prefer install=true over install=false (prefer dependencies that create files)
  3. Otherwise, keep the existing entry (first-wins for same priority)

This ensures that even with non-deterministic HashMap iteration order, the same logical dependency structure produces the same lockfile.

§Arguments
  • lockfile - The mutable lockfile to update
  • name - The name of the dependency (for documentation purposes)
  • entry - The locked resource entry to add or update
§Examples
let mut lockfile = LockFile::new();
let entry = LockedResource {
    name: "my-agent".to_string(),
    source: Some("community".to_string()),
    tool: "claude-code".to_string(),
    // ... other fields
};

resolver.add_or_update_lockfile_entry(&mut lockfile, "my-agent", entry);

// Later updates use deterministic merge strategy
let updated_entry = LockedResource {
    name: "my-agent".to_string(),
    source: Some("community".to_string()),
    tool: "claude-code".to_string(),
    // ... updated fields
};
resolver.add_or_update_lockfile_entry(&mut lockfile, "my-agent", updated_entry);
Source

pub fn remove_stale_manifest_entries(&self, lockfile: &mut LockFile)

Removes stale lockfile entries that are no longer in the manifest.

This method removes lockfile entries for direct manifest dependencies that have been commented out or removed from the manifest. This must be called BEFORE remove_manifest_entries_for_update() to ensure stale entries don’t cause conflicts during resolution.

A manifest-level entry is identified by:

  • manifest_alias.is_none() - Direct dependency with no pattern expansion
  • manifest_alias.is_some() - Pattern-expanded dependency (alias must be in manifest)

For each stale entry found, this also removes its transitive children to maintain lockfile consistency.

§Arguments
  • lockfile - The mutable lockfile to clean
§Examples

If a user comments out an agent in agpm.toml:

# [agents]
# example = { source = "community", path = "agents/example.md", version = "v1.0.0" }

This function will remove the “example” agent from the lockfile and all its transitive dependencies before the update process begins.

Source

pub fn remove_manifest_entries_for_update( &self, lockfile: &mut LockFile, manifest_keys: &HashSet<String>, )

Removes lockfile entries for manifest dependencies that will be re-resolved.

This method removes old entries for direct manifest dependencies before updating, which handles the case where a dependency’s source or resource type changes. This prevents duplicate entries with the same name but different sources.

Pattern-expanded and transitive dependencies are preserved because:

  • Pattern expansions will be re-added during resolution with (name, source) matching
  • Transitive dependencies aren’t manifest keys and won’t be removed
§Arguments
  • lockfile - The mutable lockfile to clean
  • manifest_keys - Set of manifest dependency keys being updated

Auto Trait Implementations§

§

impl<'a> Freeze for LockfileBuilder<'a>

§

impl<'a> RefUnwindSafe for LockfileBuilder<'a>

§

impl<'a> Send for LockfileBuilder<'a>

§

impl<'a> Sync for LockfileBuilder<'a>

§

impl<'a> Unpin for LockfileBuilder<'a>

§

impl<'a> UnwindSafe for LockfileBuilder<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Pointable for T

Source§

const ALIGN: usize

The alignment of pointer.
Source§

type Init = T

The type for initializers.
Source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
Source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
Source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
Source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,