diff --git a/CHANGELOG.md b/CHANGELOG.md index 55e6e868d5..91cc6a6a51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ # UNRELEASED +=== fix: dfx extension install can no longer create a corrupt cache directory + +Running `dfx cache delete && dfx extension install nns` would previously +create a cache directory containing only an `extensions` subdirectory. +dfx only looks for the existence of a cache version subdirectory to +determine whether it has been installed. The end result was that later +commands would fail when the cache did not contain expected files. + === feat: Read dfx canister install argument from a file Enables passing large arguments that cannot be passed directly in the command line using the `--argument-file` flag. For example `dfx canister install --argument-file ./my/argument/file.txt my_canister_name`. diff --git a/e2e/tests-dfx/extension.bash b/e2e/tests-dfx/extension.bash index f5688d51ef..bf2c627940 100644 --- a/e2e/tests-dfx/extension.bash +++ b/e2e/tests-dfx/extension.bash @@ -13,6 +13,12 @@ teardown() { standard_teardown } +@test "extension install with an empty cache does not create a corrupt cache" { + dfx cache delete + dfx extension install nns --version 0.2.1 + dfx_start +} + @test "install extension from official registry" { assert_command_fail dfx snsx diff --git a/src/dfx/src/commands/extension/install.rs b/src/dfx/src/commands/extension/install.rs index 6435915951..2d548894f6 100644 --- a/src/dfx/src/commands/extension/install.rs +++ b/src/dfx/src/commands/extension/install.rs @@ -5,6 +5,7 @@ use clap::Parser; use clap::Subcommand; use dfx_core::error::extension::ExtensionError; use semver::Version; +use crate::config::cache::DiskBasedCache; #[derive(Parser)] pub struct InstallOpts { @@ -19,6 +20,9 @@ pub struct InstallOpts { } pub fn exec(env: &dyn Environment, opts: InstallOpts) -> DfxResult<()> { + // creating an `extensions` directory in an otherwise empty cache directory would + // cause the cache to be considered "installed" and later commands would fail + DiskBasedCache::install(&env.get_cache().version_str())?; let spinner = env.new_spinner(format!("Installing extension: {}", opts.name).into()); let mgr = env.new_extension_manager()?; let effective_extension_name = opts.install_as.clone().unwrap_or_else(|| opts.name.clone());