refactor: Remove Context from operations - #770
Open
adamspofford-dfinity wants to merge 4 commits into
Open
Conversation
`operations::deploy` and `operations::settings` were the only things in `icp` reaching for `Context`, and `Context` is the bag that also holds the identity loader, the keyring, the global directories and the password prompt. Nothing app-scoped can leave this crate while an operation can still reach all of that. `icp::host::Host` is that surface instead: the project loader, the id and artifact stores, the builder, the syncer, network resolution, and the environment/canister-id resolution methods that used to hang off `Context`. `Context` now holds a `Host` beside its own app-side fields. `deploy` takes `(&Host, &Agent, &PackageCache, ...)` — the agent and the package cache resolved by the command — so the operations layer no longer knows that identities exist. `Context::update_custom_domains` becomes `network::Access::publish_friendly_domains`. The project side collects every environment's `friendly name -> canister id` entries; the network side decides which of them a running gateway serves, and where the file goes. That was the one project-to-app call inside `deploy`. Two intended behavior changes fall out: - The identity is unlocked before the build rather than after, so a deploy aimed at a network that is not running fails before spending time on a build. - `icp deploy` builds one agent for the whole run and reuses it for the URLs printed at the end rather than building a second one, so a network with `root-key: fetch` is fetched, and warned about, once. To keep the first of those from costing an error message, `resolve_targets` now checks the names it was given while that is still a question about the project alone: a canister-name typo is reported as such instead of being pre-empted by whatever an unreachable network had to say.
Follow-ups to the Host extraction:
- `deploy` takes a `LazyAgent` and resolves it only once the build has
succeeded. Resolving it up front meant a deploy with a broken build
unlocked the identity's key — a password prompt, for an encrypted one —
and, on a stopped managed network, reported the network error in place
of the build error.
- `Access::publish_friendly_domains` is handed the means to collect the
project's friendly-name mappings rather than a finished collection, and
asks only once it knows there is something to write and which network
is being served. A `canister create`/`delete` against a stopped network
no longer does an id-store read per environment for nothing.
- That method is now required rather than defaulting to a no-op: a second
implementor, or a decorator over `Access`, would otherwise silently
stop publishing friendly domains with no compile error.
- `Context::telemetry_data` is gone in favour of the `Host`'s. The two
were separate fields the design assumed aliased one `Arc`, which the
`Context { host: Host { .. }, ..Context::mocked() }` pattern in the
tests quietly breaks.
`CanisterMigrationError::ValidationFailed` interpolated `{source}` into its
display while also reporting it as a source, so the cause printed twice in
every chain. Its three sibling variants already left the cause to the chain;
this one was the exception.
Predates this stack; it is fixed at the base so the rest of the stack carries
the fix.
Twenty-three error variants interpolated `{source}` into their own display
while also reporting it as a source, so every chain printed the cause twice —
once inside the wrapping message and once beneath it:
Error: failed to get available subnets: canister rejected the call
Caused by:
canister rejected the call
Each message keeps the context it adds, naming the operation that failed, and
the cause is left to the chain that already reports it. Nothing is lost: these
all reach the user through the anyhow chain, which prints every source below
the top line.
Predate this stack, so they are fixed at its base and the rest of the stack
carries the fix.
Contributor
There was a problem hiding this comment.
🟡 Changes recommended
Agent creation currently precedes the local --no-create validation, causing unnecessary prompts or network failures.
Once you've addressed the issues Copilot identified, you can request another Copilot review.
Pull request overview
Refactors operations to use a project-scoped Host instead of the broader CLI Context.
Changes:
- Introduces
Hostand migrates project, environment, network, build, and ID-store access. - Adds lazy agent creation for deploys and relocates friendly-domain publishing.
- Simplifies operation error displays while preserving error sources.
File summaries
| File | Description |
|---|---|
crates/icp/src/operations/token/balance.rs |
Simplifies parse error display. |
crates/icp/src/operations/token/approve.rs |
Simplifies parse error display. |
crates/icp/src/operations/token/allowance.rs |
Simplifies parse error display. |
crates/icp/src/operations/settings.rs |
Migrates settings operations to Host. |
crates/icp/src/operations/proxy.rs |
Simplifies proxy error displays. |
crates/icp/src/operations/proxy_management.rs |
Simplifies log-fetch error displays. |
crates/icp/src/operations/deploy.rs |
Migrates deployment to Host and lazy agents. |
crates/icp/src/operations/create.rs |
Simplifies creation error displays. |
crates/icp/src/operations/canister_migration.rs |
Simplifies validation error display. |
crates/icp/src/network/mod.rs |
Adds friendly-domain publishing abstraction. |
crates/icp/src/lib.rs |
Exposes the new host module. |
crates/icp/src/host.rs |
Defines project-scoped operation resources. |
crates/icp/src/context/tests.rs |
Updates context tests for nested Host. |
crates/icp/src/context/mod.rs |
Removes project resources from Context. |
crates/icp/src/context/init.rs |
Initializes the new Host. |
crates/icp/src/agent.rs |
Adds lazy agent creation. |
crates/icp-cli/src/options.rs |
Updates selection imports. |
crates/icp-cli/src/main.rs |
Reads telemetry through Host. |
crates/icp-cli/src/complete.rs |
Loads projects through Host. |
crates/icp-cli/src/commands/sync.rs |
Migrates sync command dependencies. |
crates/icp-cli/src/commands/project/show.rs |
Loads projects through Host. |
crates/icp-cli/src/commands/project/bundle.rs |
Migrates bundle resources. |
crates/icp-cli/src/commands/network/stop.rs |
Migrates network access. |
crates/icp-cli/src/commands/network/status.rs |
Migrates network access. |
crates/icp-cli/src/commands/network/start.rs |
Migrates network and ID access. |
crates/icp-cli/src/commands/network/ping.rs |
Migrates network access. |
crates/icp-cli/src/commands/network/list.rs |
Loads projects through Host. |
crates/icp-cli/src/commands/environment/list.rs |
Loads projects through Host. |
crates/icp-cli/src/commands/deploy.rs |
Constructs and reuses a lazy agent. |
crates/icp-cli/src/commands/canister/status.rs |
Migrates environment access. |
crates/icp-cli/src/commands/canister/settings/update.rs |
Migrates project access. |
crates/icp-cli/src/commands/canister/settings/sync.rs |
Migrates canister and ID access. |
crates/icp-cli/src/commands/canister/migrate_id.rs |
Updates selection import. |
crates/icp-cli/src/commands/canister/list.rs |
Migrates environment access. |
crates/icp-cli/src/commands/canister/link.rs |
Migrates ID-store operations. |
crates/icp-cli/src/commands/canister/install.rs |
Migrates artifact access. |
crates/icp-cli/src/commands/canister/delete.rs |
Migrates ID and domain updates. |
crates/icp-cli/src/commands/canister/create.rs |
Migrates creation dependencies. |
crates/icp-cli/src/commands/canister/call.rs |
Migrates environment and artifact access. |
crates/icp-cli/src/commands/build.rs |
Migrates build resources. |
crates/icp-cli/src/commands/args.rs |
Updates selection imports. |
Review details
- Files reviewed: 41/41 changed files
- Comments generated: 1
- Review effort level: Balanced
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
|
|
||
| // Everything from here on talks to the network, so this is where the agent | ||
| // gets made — and where the identity it speaks for gets unlocked. | ||
| let agent = agent.get().await?; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stack created with GitHub Stacks CLI • Give Feedback 💬