Update Command
Relevant source files
The following files were used as context for generating this wiki page:
The update command in cargo-cooldown is the primary mechanism for refreshing a project's dependency lockfile while enforcing security cooldown periods. Unlike guard-style commands (such as check or build) that merely validate the existing Cargo.lock, the update command actively invokes Cargo's resolution engine to find the newest valid graph and then applies the cooldown logic to "cool" any freshly published versions before they are committed to the workspace.
Sources: README.md:46-49, src/main.rs:480-482
This command operates using a specific isolation strategy to prevent speculative Cargo resolutions from polluting the user-visible workspace until they have been fully validated and cooled. It effectively acts as a wrapper that sequences cargo update followed by the cargo-cooldown pinning flow.
Sources: src/main.rs:25-27, src/main.rs:518-522
Execution Flow and Architecture
The update command follows a multi-stage execution pipeline designed to ensure that the final Cargo.lock is both valid for Cargo and compliant with the project's cooldown policy.
1. Argument Normalization and Command Detection
When the user runs cargo cooldown update, the CLI entry point normalizes arguments and identifies the update subcommand. It distinguishes this from other commands to trigger the specific update-style isolation logic.
Sources: src/main.rs:163-165, src/main.rs:276-281
2. Isolated Workspace Preparation
To prevent intermediate or invalid lockfile states from appearing in the main project directory, the system creates an IsolatedWorkspace. This involves creating a temporary directory and mirroring the necessary manifest files.
Sources: src/main.rs:523-524, src/isolation.rs
3. Initial Cargo Update
Inside the isolated environment, the tool runs a standard cargo update using the arguments forwarded by the user. This establishes the "newest" possible dependency graph as the baseline for the cooling process.
Sources: src/main.rs:498-508, src/main.rs:530-535
4. Cooldown Pinning Flow
The pinning flow (the "cooling" pass) identifies registry packages in the updated lockfile that are too fresh. It repeatedly reads metadata and identifies packages that exceed the allowed cooldown_minutes. It then selects older compatible releases and rewrites the lockfile in bounded batches.
Sources: src/executor.rs:56-65, src/executor.rs:104-125
5. Lockfile Publication
If the cooling process succeeds (or if enforcement is set to cargo_compatible and fresh versions are accepted), the final validated Cargo.lock is moved from the isolated temporary directory back to the real workspace root.
Sources: src/main.rs:563-564, src/executor.rs:806-815
Execution Logic Flowchart
This diagram illustrates the sequence of operations during an update command execution.
Sources: src/main.rs:518-568, src/executor.rs:104-180
Key Components and Functions
The implementation of the update command spans several critical functions and modules:
| Component | Function | Description |
|---|---|---|
main.rs | run_update_with_cooldown_isolation | Orchestrates the creation of the isolated workspace, the initial Cargo run, and the subsequent pinning flow. |
executor.rs | run_pinning_flow_with_snapshot | The main execution loop that iterates until the dependency graph is stable and cooled. |
executor.rs | attempt_cooldown_batch_solver | Attempts to cool multiple fresh crates simultaneously via a single validated lockfile rewrite. |
isolation.rs | IsolatedWorkspace::create | Handles the technical details of setting up a temporary environment for the update. |
Sources: src/main.rs:518-568, src/executor.rs:56-80, src/executor.rs:770-785
Batch Solver and Local Dependency Resolution
A significant part of the update command's logic resides in the CooldownBatchSolver. This component tries to resolve groups of fresh dependencies together to avoid the overhead of calling Cargo individually for every package.
Sources: src/executor.rs:770-848
Configuration Impacts on Update Behavior
The outcome of the update command is heavily influenced by the enforcement and lockfile_baseline settings.
| Configuration | Effect on update |
|---|---|
enforcement = "strict" | If the pinning flow cannot find a version for a crate that is "cool," the command fails and restores the original lockfile. |
enforcement = "cargo_compatible" | If a fresh version is required by the graph and cannot be cooled, the tool warns the user but accepts the fresh version. |
lockfile_baseline = "floor" | Uses versions in the pre-update Cargo.lock as a minimum floor, preventing update from downgrading beyond the original state. |
lockfile_baseline = "ignore" | Allows update to downgrade dependencies below their pre-update versions if necessary to meet cooldown requirements. |
Sources: README.md:68-83, src/executor.rs:1497-1510
Summary of Data Flow
During an update, data flows from the existing Cargo.lock (the baseline), through the Cargo resolver (the updated state), and finally through the cooldown resolver (the cooled state).
- Baseline Capture:
executor::capture_initial_lockfilerecords the state before any changes. - Speculative Update: Cargo generates a new resolution in the isolated workspace.
- Cooling: The
executoridentifies fresh versions in the speculative update by checking theirpubtimeagainst thecooldown_minutessetting. - Verification: Every proposed cooling change is verified by running
cargo metadata --lockedto ensure the resulting graph is valid. - Finalization: The validated, cooled lockfile is written to the project root.
Sources: src/main.rs:518-568, src/executor.rs:104-180, src/executor.rs:1356-1400
The update command is a critical part of the cargo-cooldown workflow, providing a safe way to keep dependencies current without immediate exposure to zero-day supply chain risks associated with freshly published packages. By using isolated workspaces and batch validation, it balances security enforcement with the complexity of Cargo's version resolution.
Sources: README.md:126-130