diff --git a/CHANGELOG.md b/CHANGELOG.md index 0659d1725b..eb17588328 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ The minor version will be incremented upon a breaking change and the patch versi - client: Add a helper struct `DynSigner` to simplify use of `Client where >` with Solana clap CLI utils that loads `Signer` as `Box` ([#2550](https://github.com/coral-xyz/anchor/pull/2550)). - lang: Allow CPI calls matching an interface without pinning program ID ([#2559](https://github.com/coral-xyz/anchor/pull/2559)). - cli, lang: Add IDL generation through compilation. `anchor build` still uses parsing method to generate IDLs, use `anchor idl build` to generate IDLs with the build method ([#2011](https://github.com/coral-xyz/anchor/pull/2011)). +- avm: Add support for the `.anchorversion` file to facilitate switching between different versions of the `anchor-cli` ([#2553](https://github.com/coral-xyz/anchor/pull/2553)). ### Fixes diff --git a/avm/src/lib.rs b/avm/src/lib.rs index b26239b740..88a572e3dd 100644 --- a/avm/src/lib.rs +++ b/avm/src/lib.rs @@ -45,10 +45,15 @@ pub fn version_binary_path(version: &Version) -> PathBuf { } /// Update the current version to a new version -pub fn use_version(version: &Version) -> Result<()> { +pub fn use_version(opt_version: Option) -> Result<()> { + let version = match opt_version { + Some(version) => version, + None => read_anchorversion_file()?, + }; + let installed_versions = read_installed_versions(); // Make sure the requested version is installed - if !installed_versions.contains(version) { + if !installed_versions.contains(&version) { if let Ok(current) = current_version() { println!("Version {version} is not installed, staying on version {current}."); } else { @@ -118,7 +123,7 @@ pub fn install_version(version: &Version, force: bool) -> Result<()> { current_version_file.write_all(version.to_string().as_bytes())?; } - use_version(version) + use_version(Some(version.clone())) } /// Remove an installed version of anchor-cli @@ -134,6 +139,14 @@ pub fn uninstall_version(version: &Version) -> Result<()> { Ok(()) } +/// Read version from .anchorversion +pub fn read_anchorversion_file() -> Result { + fs::read_to_string(".anchorversion") + .map_err(|e| anyhow!(".anchorversion file not found: {e}")) + .map(|content| Version::parse(content.trim()))? + .map_err(|e| anyhow!("Unable to parse version: {e}")) +} + /// Ensure the users home directory is setup with the paths required by AVM. pub fn ensure_paths() { let home_dir = AVM_HOME.to_path_buf(); @@ -237,9 +250,31 @@ pub fn read_installed_versions() -> Vec { mod tests { use crate::*; use semver::Version; + use std::env; use std::fs; use std::io::Write; + #[test] + fn test_read_anchorversion() { + ensure_paths(); + let mut dir = env::current_dir().unwrap(); + dir.push(".anchorversion"); + let mut file_created = fs::File::create(&dir).unwrap(); + let test_version = "0.26.0"; + file_created.write(test_version.as_bytes()).unwrap(); + + let version = read_anchorversion_file(); + match version { + Ok(v) => { + assert_eq!(v.to_string(), test_version); + } + Err(_e) => { + assert!(false); + } + } + fs::remove_file(&dir).unwrap(); + } + #[test] fn test_ensure_paths() { ensure_paths(); diff --git a/avm/src/main.rs b/avm/src/main.rs index 37e2906305..f0d8cb682e 100644 --- a/avm/src/main.rs +++ b/avm/src/main.rs @@ -15,8 +15,8 @@ pub struct Cli { pub enum Commands { #[clap(about = "Use a specific version of Anchor")] Use { - #[clap(value_parser = parse_version)] - version: Version, + #[clap(value_parser = parse_version, required = false)] + version: Option, }, #[clap(about = "Install a version of Anchor")] Install { @@ -48,7 +48,7 @@ fn parse_version(version: &str) -> Result { } pub fn entry(opts: Cli) -> Result<()> { match opts.command { - Commands::Use { version } => avm::use_version(&version), + Commands::Use { version } => avm::use_version(version), Commands::Install { version, force } => avm::install_version(&version, force), Commands::Uninstall { version } => avm::uninstall_version(&version), Commands::List {} => avm::list_versions(),