From 0c306c2f13525d4f46e24316744cdb1928f50c71 Mon Sep 17 00:00:00 2001 From: Shawaz <65177277+shawazi@users.noreply.github.com> Date: Wed, 25 Sep 2024 19:12:31 -0400 Subject: [PATCH 01/18] docs: Add `avm` to system path (#3272) --- docs/src/pages/docs/installation.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/docs/src/pages/docs/installation.md b/docs/src/pages/docs/installation.md index eaf48a14ed..f840317b2e 100644 --- a/docs/src/pages/docs/installation.md +++ b/docs/src/pages/docs/installation.md @@ -41,6 +41,27 @@ On Linux systems you may need to install additional dependencies if cargo instal sudo apt-get update && sudo apt-get upgrade && sudo apt-get install -y pkg-config build-essential libudev-dev libssl-dev ``` +If you're using `bash`, add `avm` to PATH for `bash`, then reload the shell: + +```shell +echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.bashrc +source ~/.bashrc +``` + +If you're using `fish`, add `avm` to PATH for `fish`, then reload the shell: + +```shell +echo "set -gx PATH \$PATH \$HOME/.cargo/bin" >> ~/.config/fish/config.fish +source ~/.config/fish/config.fish +``` + +If you're using `zsh`, add `avm` to PATH for `zsh`, then reload the shell: + +```shell +echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.zshrc +source ~/.zshrc +``` + Install the latest version of the CLI using `avm`, and then set it to be the version to use. ```shell From ef542f5679d0d2148e756e706fe0d28565252398 Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Thu, 26 Sep 2024 01:18:37 +0200 Subject: [PATCH 02/18] cli: Build IDL if there is only one program when using the `idl build` command (#3275) --- CHANGELOG.md | 1 + cli/src/lib.rs | 15 ++++++++++----- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2607fadbd1..6ecd0cc142 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -51,6 +51,7 @@ The minor version will be incremented upon a breaking change and the patch versi - cli: Add completions command to generate shell completions via the clap_complete crate ([#3251](https://github.com/coral-xyz/anchor/pull/3251)). - cli: Always convert IDLs ([#3265](https://github.com/coral-xyz/anchor/pull/3265)). - cli: Check whether the `idl-build` feature exists when using the `idl build` command ([#3273](https://github.com/coral-xyz/anchor/pull/3273)). +- cli: Build IDL if there is only one program when using the `idl build` command ([#3275](https://github.com/coral-xyz/anchor/pull/3275)). ### Fixes diff --git a/cli/src/lib.rs b/cli/src/lib.rs index ce1a93c8a6..3a24b2972a 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -2728,11 +2728,16 @@ fn idl_build( Some(name) => cfg.get_program(&name)?.path, None => { let current_dir = std::env::current_dir()?; - cfg.read_all_programs()? - .into_iter() - .find(|program| program.path == current_dir) - .ok_or_else(|| anyhow!("Not in a program directory"))? - .path + let programs = cfg.read_all_programs()?; + if programs.len() == 1 { + programs.into_iter().next().unwrap().path + } else { + programs + .into_iter() + .find(|program| program.path == current_dir) + .ok_or_else(|| anyhow!("Not in a program directory"))? + .path + } } }; std::env::set_current_dir(program_path)?; From cf81636805088441e0d676ecbfc61e840947628f Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Fri, 27 Sep 2024 01:43:00 +0200 Subject: [PATCH 03/18] cli: Add short alias for `idl build` command (#3283) --- CHANGELOG.md | 1 + cli/src/lib.rs | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ecd0cc142..ab67f89b95 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ The minor version will be incremented upon a breaking change and the patch versi - cli: Always convert IDLs ([#3265](https://github.com/coral-xyz/anchor/pull/3265)). - cli: Check whether the `idl-build` feature exists when using the `idl build` command ([#3273](https://github.com/coral-xyz/anchor/pull/3273)). - cli: Build IDL if there is only one program when using the `idl build` command ([#3275](https://github.com/coral-xyz/anchor/pull/3275)). +- cli: Add short alias for the `idl build` command ([#3283](https://github.com/coral-xyz/anchor/pull/3283)). ### Fixes diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 3a24b2972a..bb1058e991 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -470,6 +470,7 @@ pub enum IdlCommand { program_id: Pubkey, }, /// Generates the IDL for the program using the compilation method. + #[clap(alias = "b")] Build { // Program name to build the IDL of(current dir's program if not specified) #[clap(short, long)] From c960b8c6232b3e09f7843c575e33703163bdff85 Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Sat, 28 Sep 2024 01:16:21 +0200 Subject: [PATCH 04/18] idl: Log output with `ANCHOR_LOG` on failure and improve build error message (#3284) --- CHANGELOG.md | 1 + idl/src/build.rs | 17 ++++++++++------- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ab67f89b95..0606b11c6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -77,6 +77,7 @@ The minor version will be incremented upon a breaking change and the patch versi - idl: Fix using full path types with `Program` ([#3228](https://github.com/coral-xyz/anchor/pull/3228)). - lang: Use closures for `init` constraints to reduce the stack usage of `try_accounts` ([#2939](https://github.com/coral-xyz/anchor/pull/2939)). - lang: Allow the `cfg` attribute above the instructions ([#2339](https://github.com/coral-xyz/anchor/pull/2339)). +- idl: Log output with `ANCHOR_LOG` on failure and improve build error message ([#3284](https://github.com/coral-xyz/anchor/pull/3284)). ### Breaking diff --git a/idl/src/build.rs b/idl/src/build.rs index 72af71476a..fe706bac8d 100644 --- a/idl/src/build.rs +++ b/idl/src/build.rs @@ -171,8 +171,16 @@ fn build( .current_dir(program_path) .stderr(Stdio::inherit()) .output()?; + + let stdout = String::from_utf8_lossy(&output.stdout); + if env::var("ANCHOR_LOG").is_ok() { + eprintln!("{}", stdout); + } + if !output.status.success() { - return Err(anyhow!("Building IDL failed")); + return Err(anyhow!( + "Building IDL failed. Run `ANCHOR_LOG=true anchor idl build` to see the logs." + )); } enum State { @@ -191,13 +199,8 @@ fn build( let mut types = BTreeMap::new(); let mut idl: Option = None; - let output = String::from_utf8_lossy(&output.stdout); - if env::var("ANCHOR_LOG").is_ok() { - println!("{}", output); - } - let mut state = State::Pass; - for line in output.lines() { + for line in stdout.lines() { match &mut state { State::Pass => match line { "--- IDL begin address ---" => state = State::Address, From aa3ace36e9970b25ca97f617c0a37fee25df5ae8 Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Sun, 29 Sep 2024 23:51:15 +0200 Subject: [PATCH 05/18] docs: Open external navigation links in a new tab (#3286) --- docs/src/components/Navigation.jsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/docs/src/components/Navigation.jsx b/docs/src/components/Navigation.jsx index 355a724647..47bc3e6aa0 100644 --- a/docs/src/components/Navigation.jsx +++ b/docs/src/components/Navigation.jsx @@ -18,6 +18,9 @@ export function Navigation({ navigation, className }) {
  • Date: Mon, 30 Sep 2024 17:28:33 +0200 Subject: [PATCH 06/18] lang: Fix constant bytes declarations when using `declare_program!` (#3287) --- CHANGELOG.md | 1 + .../src/declare_program/mods/constants.rs | 17 ++- tests/declare-program/idls/external.json | 7 ++ .../declare-program/idls/external_legacy.json | 111 +++++++++++++++--- .../programs/external/src/lib.rs | 3 + 5 files changed, 112 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0606b11c6f..f7a7b52f2b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -78,6 +78,7 @@ The minor version will be incremented upon a breaking change and the patch versi - lang: Use closures for `init` constraints to reduce the stack usage of `try_accounts` ([#2939](https://github.com/coral-xyz/anchor/pull/2939)). - lang: Allow the `cfg` attribute above the instructions ([#2339](https://github.com/coral-xyz/anchor/pull/2339)). - idl: Log output with `ANCHOR_LOG` on failure and improve build error message ([#3284](https://github.com/coral-xyz/anchor/pull/3284)). +- lang: Fix constant bytes declarations when using `declare_program!` ([#3287](https://github.com/coral-xyz/anchor/pull/3287)). ### Breaking diff --git a/lang/attribute/program/src/declare_program/mods/constants.rs b/lang/attribute/program/src/declare_program/mods/constants.rs index 4cb6ec0ed3..74093c6bd4 100644 --- a/lang/attribute/program/src/declare_program/mods/constants.rs +++ b/lang/attribute/program/src/declare_program/mods/constants.rs @@ -1,16 +1,19 @@ use anchor_lang_idl::types::{Idl, IdlType}; use quote::{format_ident, quote, ToTokens}; -use super::common::convert_idl_type_to_str; +use super::common::convert_idl_type_to_syn_type; pub fn gen_constants_mod(idl: &Idl) -> proc_macro2::TokenStream { let constants = idl.constants.iter().map(|c| { let name = format_ident!("{}", c.name); - let ty = match &c.ty { - IdlType::String => quote!(&str), - _ => parse_expr_ts(&convert_idl_type_to_str(&c.ty)), + let val = syn::parse_str::(&c.value) + .unwrap() + .to_token_stream(); + let (ty, val) = match &c.ty { + IdlType::Bytes => (quote!(&[u8]), quote! { &#val }), + IdlType::String => (quote!(&str), val), + _ => (convert_idl_type_to_syn_type(&c.ty).to_token_stream(), val), }; - let val = parse_expr_ts(&c.value); // TODO: Docs quote! { pub const #name: #ty = #val; } @@ -23,7 +26,3 @@ pub fn gen_constants_mod(idl: &Idl) -> proc_macro2::TokenStream { } } } - -fn parse_expr_ts(s: &str) -> proc_macro2::TokenStream { - syn::parse_str::(s).unwrap().to_token_stream() -} diff --git a/tests/declare-program/idls/external.json b/tests/declare-program/idls/external.json index 676532e246..37ea354d1b 100644 --- a/tests/declare-program/idls/external.json +++ b/tests/declare-program/idls/external.json @@ -229,5 +229,12 @@ ] } } + ], + "constants": [ + { + "name": "MASTER_SEED", + "type": "bytes", + "value": "[109, 97, 115, 116, 101, 114]" + } ] } \ No newline at end of file diff --git a/tests/declare-program/idls/external_legacy.json b/tests/declare-program/idls/external_legacy.json index 20da7a7fa2..dcf367ffbc 100644 --- a/tests/declare-program/idls/external_legacy.json +++ b/tests/declare-program/idls/external_legacy.json @@ -1,26 +1,55 @@ { "version": "0.1.0", "name": "external", - "metadata": { - "address": "Externa111111111111111111111111111111111111" - }, + "constants": [ + { + "name": "MASTER_SEED", + "type": "bytes", + "value": "[109, 97, 115, 116, 101, 114]" + } + ], "instructions": [ { "name": "init", "accounts": [ - { "name": "authority", "isMut": true, "isSigner": true }, - { "name": "myAccount", "isMut": true, "isSigner": false }, - { "name": "systemProgram", "isMut": false, "isSigner": false } + { + "name": "authority", + "isMut": true, + "isSigner": true + }, + { + "name": "myAccount", + "isMut": true, + "isSigner": false + }, + { + "name": "systemProgram", + "isMut": false, + "isSigner": false + } ], "args": [] }, { "name": "update", "accounts": [ - { "name": "authority", "isMut": false, "isSigner": true }, - { "name": "myAccount", "isMut": true, "isSigner": false } + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "myAccount", + "isMut": true, + "isSigner": false + } ], - "args": [{ "name": "value", "type": "u32" }] + "args": [ + { + "name": "value", + "type": "u32" + } + ] }, { "name": "updateComposite", @@ -28,21 +57,53 @@ { "name": "update", "accounts": [ - { "name": "authority", "isMut": false, "isSigner": true }, - { "name": "myAccount", "isMut": true, "isSigner": false } + { + "name": "authority", + "isMut": false, + "isSigner": true + }, + { + "name": "myAccount", + "isMut": true, + "isSigner": false + } ] } ], - "args": [{ "name": "value", "type": "u32" }] + "args": [ + { + "name": "value", + "type": "u32" + } + ] }, { "name": "testCompilationDefinedTypeParam", - "accounts": [{ "name": "signer", "isMut": false, "isSigner": true }], - "args": [{ "name": "myAccount", "type": { "defined": "MyAccount" } }] + "accounts": [ + { + "name": "signer", + "isMut": false, + "isSigner": true + } + ], + "args": [ + { + "name": "myAccount", + "type": { + "defined": "MyAccount" + } + } + ] }, { "name": "testCompilationReturnType", - "accounts": [{ "name": "signer", "isMut": false, "isSigner": true }], + "accounts": [ + { + "name": "signer", + "isMut": false, + "isSigner": true + } + ], "args": [], "returns": "bool" } @@ -52,14 +113,28 @@ "name": "MyAccount", "type": { "kind": "struct", - "fields": [{ "name": "field", "type": "u32" }] + "fields": [ + { + "name": "field", + "type": "u32" + } + ] } } ], "events": [ { "name": "MyEvent", - "fields": [{ "name": "value", "type": "u32", "index": false }] + "fields": [ + { + "name": "value", + "type": "u32", + "index": false + } + ] } - ] + ], + "metadata": { + "address": "Externa111111111111111111111111111111111111" + } } diff --git a/tests/declare-program/programs/external/src/lib.rs b/tests/declare-program/programs/external/src/lib.rs index 71dc571db7..b244ad2247 100644 --- a/tests/declare-program/programs/external/src/lib.rs +++ b/tests/declare-program/programs/external/src/lib.rs @@ -2,6 +2,9 @@ use anchor_lang::prelude::*; declare_id!("Externa111111111111111111111111111111111111"); +#[constant] +pub const MASTER_SEED: &[u8] = b"master"; + #[program] pub mod external { use super::*; From 17b6c6dece5324b61c831d1e2fd3e57eeb8e05dc Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Wed, 2 Oct 2024 08:59:05 +0200 Subject: [PATCH 07/18] avm: Remove unused `VERSION` declaration (#3288) --- avm/src/main.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/avm/src/main.rs b/avm/src/main.rs index f4c21a2b2a..4d7f7a29e0 100644 --- a/avm/src/main.rs +++ b/avm/src/main.rs @@ -3,8 +3,6 @@ use avm::InstallTarget; use clap::{CommandFactory, Parser, Subcommand}; use semver::Version; -pub const VERSION: &str = env!("CARGO_PKG_VERSION"); - #[derive(Parser)] #[clap(name = "avm", about = "Anchor version manager", version)] pub struct Cli { From cfe82aa682138f7c6c58bf7a78f48f7d63e9e466 Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Thu, 3 Oct 2024 08:49:53 +0200 Subject: [PATCH 08/18] lang: Fix using non-instruction composite accounts with `declare_program!` (#3290) --- CHANGELOG.md | 1 + .../src/declare_program/mods/internal.rs | 54 +++++++++++++++++-- tests/declare-program/idls/external.json | 46 ++++++++++++++++ .../programs/declare-program/src/lib.rs | 22 ++++++-- .../programs/external/src/lib.rs | 22 ++++++++ 5 files changed, 137 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7a7b52f2b..5f3f7af227 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -79,6 +79,7 @@ The minor version will be incremented upon a breaking change and the patch versi - lang: Allow the `cfg` attribute above the instructions ([#2339](https://github.com/coral-xyz/anchor/pull/2339)). - idl: Log output with `ANCHOR_LOG` on failure and improve build error message ([#3284](https://github.com/coral-xyz/anchor/pull/3284)). - lang: Fix constant bytes declarations when using `declare_program!` ([#3287](https://github.com/coral-xyz/anchor/pull/3287)). +- lang: Fix using non-instruction composite accounts with `declare_program!` ([#3290](https://github.com/coral-xyz/anchor/pull/3290)). ### Breaking diff --git a/lang/attribute/program/src/declare_program/mods/internal.rs b/lang/attribute/program/src/declare_program/mods/internal.rs index 7152f26705..4a394a5979 100644 --- a/lang/attribute/program/src/declare_program/mods/internal.rs +++ b/lang/attribute/program/src/declare_program/mods/internal.rs @@ -1,4 +1,6 @@ -use anchor_lang_idl::types::{Idl, IdlInstructionAccountItem}; +use anchor_lang_idl::types::{ + Idl, IdlInstruction, IdlInstructionAccountItem, IdlInstructionAccounts, +}; use anchor_syn::{ codegen::accounts::{__client_accounts, __cpi_client_accounts}, parser::accounts, @@ -105,8 +107,53 @@ fn gen_internal_accounts_common( idl: &Idl, gen_accounts: impl Fn(&AccountsStruct, proc_macro2::TokenStream) -> proc_macro2::TokenStream, ) -> proc_macro2::TokenStream { - let accounts = idl + // It's possible to declare an accounts struct and not use it as an instruction, see + // https://github.com/coral-xyz/anchor/issues/3274 + fn get_non_instruction_composite_accounts<'a>( + accs: &'a [IdlInstructionAccountItem], + idl: &'a Idl, + ) -> Vec<&'a IdlInstructionAccounts> { + accs.iter() + .flat_map(|acc| match acc { + IdlInstructionAccountItem::Composite(accs) + if !idl + .instructions + .iter() + .any(|ix| ix.accounts == accs.accounts) => + { + let mut non_ix_composite_accs = + get_non_instruction_composite_accounts(&accs.accounts, idl); + if !non_ix_composite_accs.contains(&accs) { + non_ix_composite_accs.push(accs); + } + non_ix_composite_accs + } + _ => Default::default(), + }) + .collect() + } + + let ix_accs = idl .instructions + .iter() + .flat_map(|ix| ix.accounts.to_owned()) + .collect::>(); + let combined_ixs = get_non_instruction_composite_accounts(&ix_accs, idl) + .into_iter() + .map(|accs| IdlInstruction { + // The name is not guaranteed to be the same as the one used in the actual source code + // of the program because the IDL only stores the field names. + name: accs.name.to_owned(), + accounts: accs.accounts.to_owned(), + args: Default::default(), + discriminator: Default::default(), + docs: Default::default(), + returns: Default::default(), + }) + .chain(idl.instructions.iter().cloned()) + .collect::>(); + + let accounts = combined_ixs .iter() .map(|ix| { let ident = format_ident!("{}", ix.name.to_camel_case()); @@ -143,8 +190,7 @@ fn gen_internal_accounts_common( } IdlInstructionAccountItem::Composite(accs) => { let name = format_ident!("{}", accs.name); - let ty_name = idl - .instructions + let ty_name = combined_ixs .iter() .find(|ix| ix.accounts == accs.accounts) .map(|ix| format_ident!("{}", ix.name.to_camel_case())) diff --git a/tests/declare-program/idls/external.json b/tests/declare-program/idls/external.json index 37ea354d1b..1f0fbe091f 100644 --- a/tests/declare-program/idls/external.json +++ b/tests/declare-program/idls/external.json @@ -172,6 +172,52 @@ "type": "u32" } ] + }, + { + "name": "update_non_instruction_composite", + "discriminator": [ + 49, + 218, + 69, + 196, + 204, + 66, + 36, + 29 + ], + "accounts": [ + { + "name": "non_instruction_update", + "accounts": [ + { + "name": "authority", + "signer": true + }, + { + "name": "my_account", + "writable": true, + "pda": { + "seeds": [ + { + "kind": "account", + "path": "authority" + } + ] + } + }, + { + "name": "program", + "address": "Externa111111111111111111111111111111111111" + } + ] + } + ], + "args": [ + { + "name": "value", + "type": "u32" + } + ] } ], "accounts": [ diff --git a/tests/declare-program/programs/declare-program/src/lib.rs b/tests/declare-program/programs/declare-program/src/lib.rs index e3dd6cd18a..dc6c36f8f6 100644 --- a/tests/declare-program/programs/declare-program/src/lib.rs +++ b/tests/declare-program/programs/declare-program/src/lib.rs @@ -35,6 +35,7 @@ pub mod declare_program { pub fn cpi_composite(ctx: Context, value: u32) -> Result<()> { let cpi_my_account = &mut ctx.accounts.cpi_my_account; + // Composite accounts that's also an instruction let cpi_ctx = CpiContext::new( ctx.accounts.external_program.to_account_info(), external::cpi::accounts::UpdateComposite { @@ -44,8 +45,22 @@ pub mod declare_program { }, }, ); - external::cpi::update_composite(cpi_ctx, value)?; + external::cpi::update_composite(cpi_ctx, 42)?; + cpi_my_account.reload()?; + require_eq!(cpi_my_account.field, 42); + // Composite accounts but not an actual instruction + let cpi_ctx = CpiContext::new( + ctx.accounts.external_program.to_account_info(), + external::cpi::accounts::UpdateNonInstructionComposite { + non_instruction_update: external::cpi::accounts::NonInstructionUpdate { + authority: ctx.accounts.authority.to_account_info(), + my_account: cpi_my_account.to_account_info(), + program: ctx.accounts.external_program.to_account_info(), + }, + }, + ); + external::cpi::update_non_instruction_composite(cpi_ctx, value)?; cpi_my_account.reload()?; require_eq!(cpi_my_account.field, value); @@ -60,7 +75,7 @@ pub mod declare_program { return Err(ProgramError::Custom(0).into()); } - const DISC: &[u8] = &external::accounts::MyAccount::DISCRIMINATOR; + const DISC: &[u8] = external::accounts::MyAccount::DISCRIMINATOR; // Correct discriminator but invalid data if Account::try_from_bytes(DISC).is_ok() { @@ -84,8 +99,7 @@ pub mod declare_program { return Err(ProgramError::Custom(0).into()); } - const DISC: &[u8] = - &::DISCRIMINATOR; + const DISC: &[u8] = external::events::MyEvent::DISCRIMINATOR; // Correct discriminator but invalid data if Event::try_from_bytes(DISC).is_ok() { diff --git a/tests/declare-program/programs/external/src/lib.rs b/tests/declare-program/programs/external/src/lib.rs index b244ad2247..0a5284744c 100644 --- a/tests/declare-program/programs/external/src/lib.rs +++ b/tests/declare-program/programs/external/src/lib.rs @@ -23,6 +23,15 @@ pub mod external { Ok(()) } + // Test the issue described in https://github.com/coral-xyz/anchor/issues/3274 + pub fn update_non_instruction_composite( + ctx: Context, + value: u32, + ) -> Result<()> { + ctx.accounts.non_instruction_update.my_account.field = value; + Ok(()) + } + // Compilation test for whether a defined type (an account in this case) can be used in `cpi` client. pub fn test_compilation_defined_type_param( _ctx: Context, @@ -64,11 +73,24 @@ pub struct Update<'info> { pub my_account: Account<'info, MyAccount>, } +#[derive(Accounts)] +pub struct NonInstructionUpdate<'info> { + pub authority: Signer<'info>, + #[account(mut, seeds = [authority.key.as_ref()], bump)] + pub my_account: Account<'info, MyAccount>, + pub program: Program<'info, program::External>, +} + #[derive(Accounts)] pub struct UpdateComposite<'info> { pub update: Update<'info>, } +#[derive(Accounts)] +pub struct UpdateNonInstructionComposite<'info> { + pub non_instruction_update: NonInstructionUpdate<'info>, +} + #[account] pub struct MyAccount { pub field: u32, From 4d06a88a060d61f766588dae91ca9bf0e8c949ab Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Fri, 4 Oct 2024 14:56:13 +0200 Subject: [PATCH 09/18] docs: Add installation based on commit hash to `avm install` (#3293) --- docs/src/pages/docs/avm.md | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/docs/src/pages/docs/avm.md b/docs/src/pages/docs/avm.md index 1279fabf3b..e1da2dcef1 100644 --- a/docs/src/pages/docs/avm.md +++ b/docs/src/pages/docs/avm.md @@ -28,11 +28,24 @@ SUBCOMMANDS: ## Install ```shell -avm install +avm install ``` Install the specified version of anchor-cli. The version argument should follow semver versioning. It is also possible to use `latest` as the version argument to install the latest version. +It's also possible to install based on a specific commit hash: + +```shell +# - +avm install 0.30.1-cfe82aa682138f7c6c58bf7a78f48f7d63e9e466 + +# Full commit hash +avm install cfe82aa682138f7c6c58bf7a78f48f7d63e9e466 + +# Short commit hash +avm install cfe82aa +``` + ## List ```shell From 36e336aba0aab93a6d168118667f5970336a02a0 Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Sat, 5 Oct 2024 09:00:02 +0200 Subject: [PATCH 10/18] idl: Fix instructions with tuple parameters not producing an error (#3294) --- CHANGELOG.md | 1 + lang/syn/src/idl/program.rs | 16 +++++++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5f3f7af227..db3c036ba3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -80,6 +80,7 @@ The minor version will be incremented upon a breaking change and the patch versi - idl: Log output with `ANCHOR_LOG` on failure and improve build error message ([#3284](https://github.com/coral-xyz/anchor/pull/3284)). - lang: Fix constant bytes declarations when using `declare_program!` ([#3287](https://github.com/coral-xyz/anchor/pull/3287)). - lang: Fix using non-instruction composite accounts with `declare_program!` ([#3290](https://github.com/coral-xyz/anchor/pull/3290)). +- idl: Fix instructions with tuple parameters not producing an error([#3294](https://github.com/coral-xyz/anchor/pull/3294)). ### Breaking diff --git a/lang/syn/src/idl/program.rs b/lang/syn/src/idl/program.rs index c616a07c34..d7533ead7e 100644 --- a/lang/syn/src/idl/program.rs +++ b/lang/syn/src/idl/program.rs @@ -2,6 +2,7 @@ use anyhow::{anyhow, Result}; use heck::CamelCase; use proc_macro2::TokenStream; use quote::{format_ident, quote}; +use syn::spanned::Spanned; use super::{ common::{gen_print_section, get_idl_module_path, get_no_docs, get_program_path}, @@ -25,10 +26,10 @@ pub fn gen_idl_print_fn_program(program: &Program) -> TokenStream { _ => quote! { vec![] }, }; - let (instructions, defined) = program + let result = program .ixs .iter() - .flat_map(|ix| -> Result<_> { + .map(|ix| { let name = ix.ident.to_string(); let name_pascal = format_ident!("{}", name.to_camel_case()); let ctx_ident = &ix.anchor_ident; @@ -48,7 +49,8 @@ pub fn gen_idl_print_fn_program(program: &Program) -> TokenStream { Some(docs) if !no_docs => quote! { vec![#(#docs.into()),*] }, _ => quote! { vec![] }, }; - let (ty, defined) = gen_idl_type(&arg.raw_arg.ty, &[])?; + let (ty, defined) = gen_idl_type(&arg.raw_arg.ty, &[]) + .map_err(|_| syn::Error::new(arg.raw_arg.ty.span(), "Unsupported type"))?; Ok(( quote! { @@ -61,7 +63,7 @@ pub fn gen_idl_print_fn_program(program: &Program) -> TokenStream { defined, )) }) - .collect::>>()? + .collect::>>()? .into_iter() .unzip::<_, Vec<_>, Vec<_>, Vec<_>>(); @@ -91,7 +93,11 @@ pub fn gen_idl_print_fn_program(program: &Program) -> TokenStream { defined, )) }) - .unzip::<_, Vec<_>, Vec<_>, Vec<_>>(); + .collect::>>(); + let (instructions, defined) = match result { + Err(e) => return e.into_compile_error(), + Ok(v) => v.into_iter().unzip::<_, Vec<_>, Vec<_>, Vec<_>>(), + }; let defined = defined.into_iter().flatten().flatten().collect::>(); let fn_body = gen_print_section( From 594b449f4d2fdff6da9641ad3d0f27d544cc3b89 Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Sun, 6 Oct 2024 23:59:59 +0200 Subject: [PATCH 11/18] ts: Add documentation for all builder methods (#3295) --- .../anchor/src/program/namespace/methods.ts | 176 +++++++++++++----- 1 file changed, 130 insertions(+), 46 deletions(-) diff --git a/ts/packages/anchor/src/program/namespace/methods.ts b/ts/packages/anchor/src/program/namespace/methods.ts index 7cce79dce8..2dec004506 100644 --- a/ts/packages/anchor/src/program/namespace/methods.ts +++ b/ts/packages/anchor/src/program/namespace/methods.ts @@ -230,6 +230,8 @@ export class MethodsBuilder< * * See {@link accounts} and {@link accountsPartial} methods for automatically * resolving accounts. + * + * @param accounts instruction accounts */ public accountsStrict(accounts: Accounts) { this._resolveAccounts = false; @@ -237,16 +239,40 @@ export class MethodsBuilder< return this; } + /** + * Set instruction signers. + * + * Note that calling this method appends the given signers to the existing + * signers (instead of overriding them). + * + * @param signers signers to append + */ public signers(signers: Array) { this._signers = this._signers.concat(signers); return this; } + /** + * Set remaining accounts. + * + * Note that calling this method appends the given accounts to the existing + * remaining accounts (instead of overriding them). + * + * @param accounts remaining accounts + */ public remainingAccounts(accounts: Array) { this._remainingAccounts = this._remainingAccounts.concat(accounts); return this; } + /** + * Set previous instructions. + * + * See {@link postInstructions} to set the post instructions instead. + * + * @param ixs instructions + * @param prepend whether to prepend to the existing previous instructions + */ public preInstructions(ixs: Array, prepend = false) { if (prepend) { this._preInstructions = ixs.concat(this._preInstructions); @@ -256,6 +282,13 @@ export class MethodsBuilder< return this; } + /** + * Set post instructions. + * + * See {@link preInstructions} to set the previous instructions instead. + * + * @param ixs instructions + */ public postInstructions(ixs: Array) { this._postInstructions = this._postInstructions.concat(ixs); return this; @@ -280,58 +313,59 @@ export class MethodsBuilder< return this._accounts; } - public async rpc(options?: ConfirmOptions): Promise { + /** + * Create an instruction based on the current configuration. + * + * See {@link transaction} to create a transaction instead. + * + * @returns the transaction instruction + */ + public async instruction(): Promise { if (this._resolveAccounts) { await this._accountsResolver.resolve(); } // @ts-ignore - return this._rpcFn(...this._args, { + return this._ixFn(...this._args, { accounts: this._accounts, signers: this._signers, remainingAccounts: this._remainingAccounts, preInstructions: this._preInstructions, postInstructions: this._postInstructions, - options, }); } - public async rpcAndKeys(options?: ConfirmOptions): Promise<{ - pubkeys: InstructionAccountAddresses; - signature: TransactionSignature; - }> { - const pubkeys = await this.pubkeys(); - return { - pubkeys: pubkeys as Required>, - signature: await this.rpc(options), - }; - } - - public async view(options?: ConfirmOptions): Promise { + /** + * Create a transaction based on the current configuration. + * + * This method doesn't send the created transaction. Use {@link rpc} method + * to conveniently send an confirm the configured transaction. + * + * See {@link instruction} to only create an instruction instead. + * + * @returns the transaction + */ + public async transaction(): Promise { if (this._resolveAccounts) { await this._accountsResolver.resolve(); } - if (!this._viewFn) { - throw new Error( - [ - "Method does not support views.", - "The instruction should return a value, and its accounts must be read-only", - ].join(" ") - ); - } - // @ts-ignore - return this._viewFn(...this._args, { + return this._txFn(...this._args, { accounts: this._accounts, signers: this._signers, remainingAccounts: this._remainingAccounts, preInstructions: this._preInstructions, postInstructions: this._postInstructions, - options, }); } + /** + * Simulate the configured transaction. + * + * @param options confirmation options + * @returns the simulation response + */ public async simulate(options?: ConfirmOptions): Promise { if (this._resolveAccounts) { await this._accountsResolver.resolve(); @@ -348,52 +382,102 @@ export class MethodsBuilder< }); } - public async instruction(): Promise { + /** + * View the configured transaction. + * + * Note that to use this method, the instruction needs to return a value and + * all its accounts must be read-only. + * + * @param options confirmation options + * @returns the return value of the instruction + */ + public async view(options?: ConfirmOptions): Promise { if (this._resolveAccounts) { await this._accountsResolver.resolve(); } + if (!this._viewFn) { + throw new Error( + [ + "Method does not support views.", + "The instruction should return a value, and its accounts must be read-only", + ].join(" ") + ); + } + // @ts-ignore - return this._ixFn(...this._args, { + return this._viewFn(...this._args, { accounts: this._accounts, signers: this._signers, remainingAccounts: this._remainingAccounts, preInstructions: this._preInstructions, postInstructions: this._postInstructions, + options, }); } /** - * Convenient shortcut to get instructions and pubkeys via: + * Send and confirm the configured transaction. * - * ```ts - * const { pubkeys, instructions } = await method.prepare(); - * ``` + * See {@link rpcAndKeys} to both send the transaction and get the resolved + * account public keys. + * + * @param options confirmation options + * @returns the transaction signature */ - public async prepare(): Promise<{ - pubkeys: Partial>; - instruction: TransactionInstruction; - signers: Signer[]; - }> { - return { - instruction: await this.instruction(), - pubkeys: await this.pubkeys(), - signers: this._signers, - }; - } - - public async transaction(): Promise { + public async rpc(options?: ConfirmOptions): Promise { if (this._resolveAccounts) { await this._accountsResolver.resolve(); } // @ts-ignore - return this._txFn(...this._args, { + return this._rpcFn(...this._args, { accounts: this._accounts, signers: this._signers, remainingAccounts: this._remainingAccounts, preInstructions: this._preInstructions, postInstructions: this._postInstructions, + options, }); } + + /** + * Conveniently call both {@link rpc} and {@link pubkeys} methods. + * + * @param options confirmation options + * @returns the transaction signature and account public keys + */ + public async rpcAndKeys(options?: ConfirmOptions): Promise<{ + signature: TransactionSignature; + pubkeys: InstructionAccountAddresses; + }> { + return { + signature: await this.rpc(options), + pubkeys: (await this.pubkeys()) as Required< + InstructionAccountAddresses + >, + }; + } + + /** + * Get instruction information necessary to include the instruction inside a + * transaction. + * + * # Example + * + * ```ts + * const { instruction, signers, pubkeys } = await method.prepare(); + * ``` + */ + public async prepare(): Promise<{ + instruction: TransactionInstruction; + signers: Signer[]; + pubkeys: Partial>; + }> { + return { + instruction: await this.instruction(), + signers: this._signers, + pubkeys: await this.pubkeys(), + }; + } } From 8b67b672e4b5609901734fdf148ca0374fbf8e30 Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Mon, 7 Oct 2024 23:54:25 +0200 Subject: [PATCH 12/18] lang: Use associated `DISCRIMINATOR` constants for `Account` and `Event` utils in `declare_program!` (#3297) --- .../program/src/declare_program/mods/utils.rs | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/lang/attribute/program/src/declare_program/mods/utils.rs b/lang/attribute/program/src/declare_program/mods/utils.rs index 4c359c2c4e..6b7ccf9438 100644 --- a/lang/attribute/program/src/declare_program/mods/utils.rs +++ b/lang/attribute/program/src/declare_program/mods/utils.rs @@ -1,8 +1,6 @@ use anchor_lang_idl::types::Idl; use quote::{format_ident, quote}; -use super::common::gen_discriminator; - pub fn gen_utils_mod(idl: &Idl) -> proc_macro2::TokenStream { let account = gen_account(idl); let event = gen_event(idl); @@ -26,9 +24,8 @@ fn gen_account(idl: &Idl) -> proc_macro2::TokenStream { .map(|name| quote! { #name(#name) }); let if_statements = idl.accounts.iter().map(|acc| { let name = format_ident!("{}", acc.name); - let disc = gen_discriminator(&acc.discriminator); quote! { - if value.starts_with(&#disc) { + if value.starts_with(#name::DISCRIMINATOR) { return #name::try_deserialize_unchecked(&mut &value[..]) .map(Self::#name) .map_err(Into::into) @@ -73,11 +70,9 @@ fn gen_event(idl: &Idl) -> proc_macro2::TokenStream { .map(|name| quote! { #name(#name) }); let if_statements = idl.events.iter().map(|ev| { let name = format_ident!("{}", ev.name); - let disc = gen_discriminator(&ev.discriminator); - let disc_len = ev.discriminator.len(); quote! { - if value.starts_with(&#disc) { - return #name::try_from_slice(&value[#disc_len..]) + if value.starts_with(#name::DISCRIMINATOR) { + return #name::try_from_slice(&value[#name::DISCRIMINATOR.len()..]) .map(Self::#name) .map_err(Into::into) } From 6eb4cc7539636983e768561ea9c528d59486799d Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Wed, 9 Oct 2024 00:04:35 +0200 Subject: [PATCH 13/18] cli: Inform users to rebuild their programs after running `keys sync` (#3299) --- cli/src/lib.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/cli/src/lib.rs b/cli/src/lib.rs index bb1058e991..808e43d4e2 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -4502,6 +4502,7 @@ fn keys_sync(cfg_override: &ConfigOverride, program_name: Option) -> Res .build() .unwrap(); + let mut changed_src = false; for program in cfg.get_programs(program_name)? { // Get the pubkey from the keypair file let actual_program_id = program.pubkey()?.to_string(); @@ -4527,6 +4528,7 @@ fn keys_sync(cfg_override: &ConfigOverride, program_name: Option) -> Res content.replace_range(program_id_match.range(), &actual_program_id); fs::write(&path, content)?; + changed_src = true; println!("Updated to {actual_program_id}\n"); break; } @@ -4555,6 +4557,9 @@ fn keys_sync(cfg_override: &ConfigOverride, program_name: Option) -> Res } println!("All program id declarations are synced."); + if changed_src { + println!("Please rebuild the program to update the generated artifacts.") + } Ok(()) }) From aa48efb437cc7e0b4437c6506431953482d0c0fa Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Wed, 9 Oct 2024 23:58:09 +0200 Subject: [PATCH 14/18] ts: Update `engines.node` to `>= 17` (#3301) --- CHANGELOG.md | 1 + examples/tutorial/basic-0/package.json | 2 +- examples/tutorial/basic-1/package.json | 2 +- examples/tutorial/basic-2/package.json | 2 +- examples/tutorial/basic-3/package.json | 2 +- examples/tutorial/basic-4/package.json | 2 +- examples/tutorial/basic-5/package.json | 2 +- tests/anchor-cli-account/package.json | 2 +- tests/anchor-cli-idl/package.json | 2 +- tests/bpf-upgradeable-state/package.json | 28 +++++++-------- tests/cashiers-check/package.json | 2 +- tests/cfo/package.json | 2 +- tests/chat/package.json | 2 +- tests/composite/package.json | 2 +- tests/cpi-returns/package.json | 2 +- tests/custom-coder/package.json | 2 +- tests/declare-id/package.json | 2 +- tests/docs/package.json | 2 +- tests/errors/package.json | 2 +- tests/escrow/package.json | 2 +- tests/events/package.json | 2 +- tests/floats/package.json | 34 +++++++++---------- tests/ido-pool/package.json | 2 +- tests/lockup/package.json | 2 +- tests/misc/package.json | 2 +- tests/multiple-suites-run-single/package.json | 34 +++++++++---------- tests/multiple-suites/package.json | 34 +++++++++---------- tests/multisig/package.json | 2 +- tests/optional/package.json | 2 +- tests/pda-derivation/package.json | 2 +- tests/pyth/package.json | 2 +- tests/realloc/package.json | 2 +- tests/relations-derivation/package.json | 2 +- tests/solang/package.json | 2 +- tests/spl/token-extensions/package.json | 2 +- tests/spl/token-proxy/package.json | 2 +- tests/spl/token-wrapper/package.json | 2 +- tests/spl/transfer-hook/package.json | 2 +- tests/swap/package.json | 2 +- tests/system-accounts/package.json | 2 +- tests/sysvars/package.json | 2 +- tests/tictactoe/package.json | 2 +- tests/typescript/package.json | 2 +- tests/validator-clone/package.json | 2 +- tests/zero-copy/package.json | 2 +- ts/packages/anchor/package.json | 2 +- 46 files changed, 107 insertions(+), 106 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index db3c036ba3..c65f2cbc17 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -81,6 +81,7 @@ The minor version will be incremented upon a breaking change and the patch versi - lang: Fix constant bytes declarations when using `declare_program!` ([#3287](https://github.com/coral-xyz/anchor/pull/3287)). - lang: Fix using non-instruction composite accounts with `declare_program!` ([#3290](https://github.com/coral-xyz/anchor/pull/3290)). - idl: Fix instructions with tuple parameters not producing an error([#3294](https://github.com/coral-xyz/anchor/pull/3294)). +- ts: Update `engines.node` to `>= 17` ([#3301](https://github.com/coral-xyz/anchor/pull/3301)). ### Breaking diff --git a/examples/tutorial/basic-0/package.json b/examples/tutorial/basic-0/package.json index 57b13033bf..daf7cf1fdd 100644 --- a/examples/tutorial/basic-0/package.json +++ b/examples/tutorial/basic-0/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test --skip-lint && anchor clean" diff --git a/examples/tutorial/basic-1/package.json b/examples/tutorial/basic-1/package.json index 349ee92fa2..b34ba6c6dc 100644 --- a/examples/tutorial/basic-1/package.json +++ b/examples/tutorial/basic-1/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test --skip-lint && anchor clean" diff --git a/examples/tutorial/basic-2/package.json b/examples/tutorial/basic-2/package.json index 7e63322454..e8e143660d 100644 --- a/examples/tutorial/basic-2/package.json +++ b/examples/tutorial/basic-2/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test --skip-lint && anchor clean" diff --git a/examples/tutorial/basic-3/package.json b/examples/tutorial/basic-3/package.json index 2f4763adf5..9afe4bc121 100644 --- a/examples/tutorial/basic-3/package.json +++ b/examples/tutorial/basic-3/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test --skip-lint && anchor clean" diff --git a/examples/tutorial/basic-4/package.json b/examples/tutorial/basic-4/package.json index e162df60a2..adeef85e68 100644 --- a/examples/tutorial/basic-4/package.json +++ b/examples/tutorial/basic-4/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test --skip-lint && anchor clean" diff --git a/examples/tutorial/basic-5/package.json b/examples/tutorial/basic-5/package.json index 4455561c29..6f5d086c26 100644 --- a/examples/tutorial/basic-5/package.json +++ b/examples/tutorial/basic-5/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test --skip-lint && anchor clean" diff --git a/tests/anchor-cli-account/package.json b/tests/anchor-cli-account/package.json index 690bdc5362..e4fa548dab 100644 --- a/tests/anchor-cli-account/package.json +++ b/tests/anchor-cli-account/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/anchor-cli-idl/package.json b/tests/anchor-cli-idl/package.json index 4c31edba4c..f57d8f0ae3 100644 --- a/tests/anchor-cli-idl/package.json +++ b/tests/anchor-cli-idl/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "./test.sh" diff --git a/tests/bpf-upgradeable-state/package.json b/tests/bpf-upgradeable-state/package.json index 5caf6fe106..292dbc95ce 100644 --- a/tests/bpf-upgradeable-state/package.json +++ b/tests/bpf-upgradeable-state/package.json @@ -1,16 +1,16 @@ { - "name": "bpf-upgradeable-state", - "version": "0.24.0", - "license": "(MIT OR Apache-2.0)", - "homepage": "https://github.com/coral-xyz/anchor#readme", - "bugs": { - "url": "https://github.com/coral-xyz/anchor/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/coral-xyz/anchor.git" - }, - "engines": { - "node": ">=11" - } + "name": "bpf-upgradeable-state", + "version": "0.24.0", + "license": "(MIT OR Apache-2.0)", + "homepage": "https://github.com/coral-xyz/anchor#readme", + "bugs": { + "url": "https://github.com/coral-xyz/anchor/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/coral-xyz/anchor.git" + }, + "engines": { + "node": ">=17" + } } diff --git a/tests/cashiers-check/package.json b/tests/cashiers-check/package.json index 4c178102ac..7565523a5a 100644 --- a/tests/cashiers-check/package.json +++ b/tests/cashiers-check/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/cfo/package.json b/tests/cfo/package.json index 46ffb91918..131958525e 100644 --- a/tests/cfo/package.json +++ b/tests/cfo/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor run test-with-build" diff --git a/tests/chat/package.json b/tests/chat/package.json index 3a552e0021..82e87fe5ec 100644 --- a/tests/chat/package.json +++ b/tests/chat/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/composite/package.json b/tests/composite/package.json index d937685d5d..2df9657982 100644 --- a/tests/composite/package.json +++ b/tests/composite/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/cpi-returns/package.json b/tests/cpi-returns/package.json index 69d795796a..fa4f77b2ed 100644 --- a/tests/cpi-returns/package.json +++ b/tests/cpi-returns/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor run test-with-build" diff --git a/tests/custom-coder/package.json b/tests/custom-coder/package.json index e0c6039f27..6235b86a49 100644 --- a/tests/custom-coder/package.json +++ b/tests/custom-coder/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test --skip-lint" diff --git a/tests/declare-id/package.json b/tests/declare-id/package.json index 1fc78018e3..4fb315775b 100644 --- a/tests/declare-id/package.json +++ b/tests/declare-id/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/docs/package.json b/tests/docs/package.json index 7fa3731579..dc6f8f9c95 100644 --- a/tests/docs/package.json +++ b/tests/docs/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/errors/package.json b/tests/errors/package.json index 7fa3731579..dc6f8f9c95 100644 --- a/tests/errors/package.json +++ b/tests/errors/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/escrow/package.json b/tests/escrow/package.json index fafedc4363..79f9780519 100644 --- a/tests/escrow/package.json +++ b/tests/escrow/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/events/package.json b/tests/events/package.json index f39b99711d..97a0f70cf9 100644 --- a/tests/events/package.json +++ b/tests/events/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/floats/package.json b/tests/floats/package.json index be38a18bb9..b63e92b890 100644 --- a/tests/floats/package.json +++ b/tests/floats/package.json @@ -1,19 +1,19 @@ { - "name": "floats", - "version": "0.30.1", - "license": "(MIT OR Apache-2.0)", - "homepage": "https://github.com/coral-xyz/anchor#readme", - "bugs": { - "url": "https://github.com/coral-xyz/anchor/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/coral-xyz/anchor.git" - }, - "engines": { - "node": ">=11" - }, - "scripts": { - "test": "anchor test" - } + "name": "floats", + "version": "0.30.1", + "license": "(MIT OR Apache-2.0)", + "homepage": "https://github.com/coral-xyz/anchor#readme", + "bugs": { + "url": "https://github.com/coral-xyz/anchor/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/coral-xyz/anchor.git" + }, + "engines": { + "node": ">=17" + }, + "scripts": { + "test": "anchor test" } +} diff --git a/tests/ido-pool/package.json b/tests/ido-pool/package.json index 9731ddb1b8..a937283c12 100644 --- a/tests/ido-pool/package.json +++ b/tests/ido-pool/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/lockup/package.json b/tests/lockup/package.json index ace9f2986f..c15c3c94ee 100644 --- a/tests/lockup/package.json +++ b/tests/lockup/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/misc/package.json b/tests/misc/package.json index 65396b55fa..c5a61b86a2 100644 --- a/tests/misc/package.json +++ b/tests/misc/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/multiple-suites-run-single/package.json b/tests/multiple-suites-run-single/package.json index f11e4edbf7..b57fb8b715 100644 --- a/tests/multiple-suites-run-single/package.json +++ b/tests/multiple-suites-run-single/package.json @@ -1,19 +1,19 @@ { - "name": "multiple-suites-run-single", - "version": "0.24.2", - "license": "(MIT OR Apache-2.0)", - "homepage": "https://github.com/coral-xyz/anchor#readme", - "bugs": { - "url": "https://github.com/coral-xyz/anchor/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/coral-xyz/anchor.git" - }, - "engines": { - "node": ">=11" - }, - "scripts": { - "test": "anchor test" - } + "name": "multiple-suites-run-single", + "version": "0.24.2", + "license": "(MIT OR Apache-2.0)", + "homepage": "https://github.com/coral-xyz/anchor#readme", + "bugs": { + "url": "https://github.com/coral-xyz/anchor/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/coral-xyz/anchor.git" + }, + "engines": { + "node": ">=17" + }, + "scripts": { + "test": "anchor test" } +} diff --git a/tests/multiple-suites/package.json b/tests/multiple-suites/package.json index 1d560b537f..4e71e6d58b 100644 --- a/tests/multiple-suites/package.json +++ b/tests/multiple-suites/package.json @@ -1,19 +1,19 @@ { - "name": "multiple-suites", - "version": "0.30.1", - "license": "(MIT OR Apache-2.0)", - "homepage": "https://github.com/coral-xyz/anchor#readme", - "bugs": { - "url": "https://github.com/coral-xyz/anchor/issues" - }, - "repository": { - "type": "git", - "url": "https://github.com/coral-xyz/anchor.git" - }, - "engines": { - "node": ">=11" - }, - "scripts": { - "test": "anchor test" - } + "name": "multiple-suites", + "version": "0.30.1", + "license": "(MIT OR Apache-2.0)", + "homepage": "https://github.com/coral-xyz/anchor#readme", + "bugs": { + "url": "https://github.com/coral-xyz/anchor/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/coral-xyz/anchor.git" + }, + "engines": { + "node": ">=17" + }, + "scripts": { + "test": "anchor test" } +} diff --git a/tests/multisig/package.json b/tests/multisig/package.json index 5fc36c1314..c4be117b00 100644 --- a/tests/multisig/package.json +++ b/tests/multisig/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/optional/package.json b/tests/optional/package.json index a5914f01cf..e18cb656e0 100644 --- a/tests/optional/package.json +++ b/tests/optional/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/pda-derivation/package.json b/tests/pda-derivation/package.json index 36b78953d2..a018c0d333 100644 --- a/tests/pda-derivation/package.json +++ b/tests/pda-derivation/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/pyth/package.json b/tests/pyth/package.json index 8d09d64ff0..638d3163b6 100644 --- a/tests/pyth/package.json +++ b/tests/pyth/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/realloc/package.json b/tests/realloc/package.json index 149233a774..4bcc3be0c1 100644 --- a/tests/realloc/package.json +++ b/tests/realloc/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/relations-derivation/package.json b/tests/relations-derivation/package.json index 37870c0c2b..ba767ebdf3 100644 --- a/tests/relations-derivation/package.json +++ b/tests/relations-derivation/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/solang/package.json b/tests/solang/package.json index 9063210c76..c97ba8ca5a 100644 --- a/tests/solang/package.json +++ b/tests/solang/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor run test-with-build" diff --git a/tests/spl/token-extensions/package.json b/tests/spl/token-extensions/package.json index 487bc1297f..a8249709a7 100644 --- a/tests/spl/token-extensions/package.json +++ b/tests/spl/token-extensions/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/spl/token-proxy/package.json b/tests/spl/token-proxy/package.json index bda4e6f519..56c6468a02 100644 --- a/tests/spl/token-proxy/package.json +++ b/tests/spl/token-proxy/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/spl/token-wrapper/package.json b/tests/spl/token-wrapper/package.json index ce70ff4b2f..53e22d29ba 100644 --- a/tests/spl/token-wrapper/package.json +++ b/tests/spl/token-wrapper/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/spl/transfer-hook/package.json b/tests/spl/transfer-hook/package.json index c97b24f510..33320fdc1b 100644 --- a/tests/spl/transfer-hook/package.json +++ b/tests/spl/transfer-hook/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/swap/package.json b/tests/swap/package.json index 4327e5e233..50ae1338cc 100644 --- a/tests/swap/package.json +++ b/tests/swap/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/system-accounts/package.json b/tests/system-accounts/package.json index a3211bfe26..4fd0a11f70 100644 --- a/tests/system-accounts/package.json +++ b/tests/system-accounts/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/sysvars/package.json b/tests/sysvars/package.json index 54ffc6e258..6a861fc4e0 100644 --- a/tests/sysvars/package.json +++ b/tests/sysvars/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/tictactoe/package.json b/tests/tictactoe/package.json index a471abb8f3..588d2a2d9f 100644 --- a/tests/tictactoe/package.json +++ b/tests/tictactoe/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/typescript/package.json b/tests/typescript/package.json index c338ff7f3e..5fe7d650e7 100644 --- a/tests/typescript/package.json +++ b/tests/typescript/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/validator-clone/package.json b/tests/validator-clone/package.json index 338257929c..139fc29e18 100644 --- a/tests/validator-clone/package.json +++ b/tests/validator-clone/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/tests/zero-copy/package.json b/tests/zero-copy/package.json index 386538a86b..0c61dbf9b5 100644 --- a/tests/zero-copy/package.json +++ b/tests/zero-copy/package.json @@ -11,7 +11,7 @@ "url": "https://github.com/coral-xyz/anchor.git" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "test": "anchor test" diff --git a/ts/packages/anchor/package.json b/ts/packages/anchor/package.json index 5e78c50279..f96e0f15fe 100644 --- a/ts/packages/anchor/package.json +++ b/ts/packages/anchor/package.json @@ -19,7 +19,7 @@ "access": "public" }, "engines": { - "node": ">=11" + "node": ">=17" }, "scripts": { "build": "rimraf dist/ && yarn build:node && yarn build:browser", From 5df7fbda90cfd564b052fce58301f6d19ac74a34 Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Thu, 10 Oct 2024 23:57:56 +0200 Subject: [PATCH 15/18] cli: Use OS-agnostic paths (#3307) --- CHANGELOG.md | 1 + cli/src/config.rs | 42 ++++++++++------ cli/src/lib.rs | 124 ++++++++++++++++++++++++++++------------------ 3 files changed, 106 insertions(+), 61 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c65f2cbc17..9ef4602b76 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -82,6 +82,7 @@ The minor version will be incremented upon a breaking change and the patch versi - lang: Fix using non-instruction composite accounts with `declare_program!` ([#3290](https://github.com/coral-xyz/anchor/pull/3290)). - idl: Fix instructions with tuple parameters not producing an error([#3294](https://github.com/coral-xyz/anchor/pull/3294)). - ts: Update `engines.node` to `>= 17` ([#3301](https://github.com/coral-xyz/anchor/pull/3301)). +- cli: Use OS-agnostic paths ([#3307](https://github.com/coral-xyz/anchor/pull/3307)). ### Breaking diff --git a/cli/src/config.rs b/cli/src/config.rs index 5eb6d416d2..b844dfc195 100644 --- a/cli/src/config.rs +++ b/cli/src/config.rs @@ -243,7 +243,10 @@ impl WithPath { let cargo = Manifest::from_path(path.join("Cargo.toml"))?; let lib_name = cargo.lib_name()?; - let idl_filepath = format!("target/idl/{lib_name}.json"); + let idl_filepath = Path::new("target") + .join("idl") + .join(&lib_name) + .with_extension("json"); let idl = fs::read(idl_filepath) .ok() .map(|bytes| serde_json::from_reader(&*bytes)) @@ -257,7 +260,10 @@ impl WithPath { }); } for (lib_name, path) in self.get_solidity_program_list()? { - let idl_filepath = format!("target/idl/{lib_name}.json"); + let idl_filepath = Path::new("target") + .join("idl") + .join(&lib_name) + .with_extension("json"); let idl = fs::read(idl_filepath) .ok() .map(|bytes| serde_json::from_reader(&*bytes)) @@ -1131,7 +1137,7 @@ impl From<_Validator> for Validator { url: _validator.url, ledger: _validator .ledger - .unwrap_or_else(|| DEFAULT_LEDGER_PATH.to_string()), + .unwrap_or_else(|| get_default_ledger_path().display().to_string()), limit_ledger_size: _validator.limit_ledger_size, rpc_port: _validator .rpc_port @@ -1169,7 +1175,10 @@ impl From for _Validator { } } -pub const DEFAULT_LEDGER_PATH: &str = ".anchor/test-ledger"; +pub fn get_default_ledger_path() -> PathBuf { + Path::new(".anchor").join("test-ledger") +} + const DEFAULT_BIND_ADDRESS: &str = "0.0.0.0"; impl Merge for _Validator { @@ -1282,12 +1291,12 @@ impl Program { // Lazily initializes the keypair file with a new key if it doesn't exist. pub fn keypair_file(&self) -> Result> { - let deploy_dir_path = "target/deploy/"; - fs::create_dir_all(deploy_dir_path) - .with_context(|| format!("Error creating directory with path: {deploy_dir_path}"))?; + let deploy_dir_path = Path::new("target").join("deploy"); + fs::create_dir_all(&deploy_dir_path) + .with_context(|| format!("Error creating directory with path: {deploy_dir_path:?}"))?; let path = std::env::current_dir() .expect("Must have current dir") - .join(format!("target/deploy/{}-keypair.json", self.lib_name)); + .join(deploy_dir_path.join(format!("{}-keypair.json", self.lib_name))); if path.exists() { return Ok(WithPath::new( File::open(&path) @@ -1303,11 +1312,10 @@ impl Program { } pub fn binary_path(&self, verifiable: bool) -> PathBuf { - let path = if verifiable { - format!("target/verifiable/{}.so", self.lib_name) - } else { - format!("target/deploy/{}.so", self.lib_name) - }; + let path = Path::new("target") + .join(if verifiable { "verifiable" } else { "deploy" }) + .join(&self.lib_name) + .with_extension("so"); std::env::current_dir() .expect("Must have current dir") @@ -1389,7 +1397,13 @@ macro_rules! home_path { impl Default for $my_struct { fn default() -> Self { - $my_struct(home_dir().unwrap().join($path).display().to_string()) + $my_struct( + home_dir() + .unwrap() + .join($path.replace('/', std::path::MAIN_SEPARATOR_STR)) + .display() + .to_string(), + ) } } diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 808e43d4e2..51c280cc83 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -1,7 +1,7 @@ use crate::config::{ - AnchorPackage, BootstrapMode, BuildConfig, Config, ConfigOverride, Manifest, ProgramArch, - ProgramDeployment, ProgramWorkspace, ScriptsConfig, TestValidator, WithPath, - DEFAULT_LEDGER_PATH, SHUTDOWN_WAIT, STARTUP_WAIT, + get_default_ledger_path, AnchorPackage, BootstrapMode, BuildConfig, Config, ConfigOverride, + Manifest, ProgramArch, ProgramDeployment, ProgramWorkspace, ScriptsConfig, TestValidator, + WithPath, SHUTDOWN_WAIT, STARTUP_WAIT, }; use anchor_client::Cluster; use anchor_lang::idl::{IdlAccount, IdlInstruction, ERASED_AUTHORITY}; @@ -1028,7 +1028,8 @@ fn init( } // Build the migrations directory. - fs::create_dir_all("migrations")?; + let migrations_path = Path::new("migrations"); + fs::create_dir_all(migrations_path)?; let license = get_npm_init_license()?; @@ -1038,8 +1039,7 @@ fn init( let mut package_json = File::create("package.json")?; package_json.write_all(rust_template::package_json(jest, license).as_bytes())?; - let mut deploy = File::create("migrations/deploy.js")?; - + let mut deploy = File::create(migrations_path.join("deploy.js"))?; deploy.write_all(rust_template::deploy_script().as_bytes())?; } else { // Build typescript config @@ -1049,7 +1049,7 @@ fn init( let mut ts_package_json = File::create("package.json")?; ts_package_json.write_all(rust_template::ts_package_json(jest, license).as_bytes())?; - let mut deploy = File::create("migrations/deploy.ts")?; + let mut deploy = File::create(migrations_path.join("deploy.ts"))?; deploy.write_all(rust_template::ts_deploy_script().as_bytes())?; } @@ -1171,7 +1171,11 @@ pub type Files = Vec<(PathBuf, String)>; /// ``` pub fn create_files(files: &Files) -> Result<()> { for (path, content) in files { - let path = Path::new(path); + let path = path + .display() + .to_string() + .replace('/', std::path::MAIN_SEPARATOR_STR); + let path = Path::new(&path); if path.exists() { continue; } @@ -1228,7 +1232,7 @@ pub fn expand( let cfg_parent = workspace_cfg.path().parent().expect("Invalid Anchor.toml"); let cargo = Manifest::discover()?; - let expansions_path = cfg_parent.join(".anchor/expanded-macros"); + let expansions_path = cfg_parent.join(".anchor").join("expanded-macros"); fs::create_dir_all(&expansions_path)?; match cargo { @@ -1347,13 +1351,13 @@ pub fn build( let idl_out = match idl { Some(idl) => Some(PathBuf::from(idl)), - None => Some(cfg_parent.join("target/idl")), + None => Some(cfg_parent.join("target").join("idl")), }; fs::create_dir_all(idl_out.as_ref().unwrap())?; let idl_ts_out = match idl_ts { Some(idl_ts) => Some(PathBuf::from(idl_ts)), - None => Some(cfg_parent.join("target/types")), + None => Some(cfg_parent.join("target").join("types")), }; fs::create_dir_all(idl_ts_out.as_ref().unwrap())?; @@ -1563,9 +1567,10 @@ fn build_cwd_verifiable( ) -> Result<()> { // Create output dirs. let workspace_dir = cfg.path().parent().unwrap().canonicalize()?; - fs::create_dir_all(workspace_dir.join("target/verifiable"))?; - fs::create_dir_all(workspace_dir.join("target/idl"))?; - fs::create_dir_all(workspace_dir.join("target/types"))?; + let target_dir = workspace_dir.join("target"); + fs::create_dir_all(target_dir.join("verifiable"))?; + fs::create_dir_all(target_dir.join("idl"))?; + fs::create_dir_all(target_dir.join("types"))?; if !&cfg.workspace.types.is_empty() { fs::create_dir_all(workspace_dir.join(&cfg.workspace.types))?; } @@ -1595,12 +1600,20 @@ fn build_cwd_verifiable( let idl = generate_idl(cfg, skip_lint, no_docs, &cargo_args)?; // Write out the JSON file. println!("Writing the IDL file"); - let out_file = workspace_dir.join(format!("target/idl/{}.json", idl.metadata.name)); + let out_file = workspace_dir + .join("target") + .join("idl") + .join(&idl.metadata.name) + .with_extension("json"); write_idl(&idl, OutFile::File(out_file))?; // Write out the TypeScript type. println!("Writing the .ts file"); - let ts_file = workspace_dir.join(format!("target/types/{}.ts", idl.metadata.name)); + let ts_file = workspace_dir + .join("target") + .join("types") + .join(&idl.metadata.name) + .with_extension("ts"); fs::write(&ts_file, idl_ts(&idl)?)?; // Copy out the TypeScript type. @@ -1802,7 +1815,12 @@ fn docker_build_bpf( println!("Copying out the build artifacts"); let out_file = cfg_parent .canonicalize()? - .join(format!("target/verifiable/{binary_name}.so")) + .join( + Path::new("target") + .join("verifiable") + .join(&binary_name) + .with_extension("so"), + ) .display() .to_string(); @@ -2053,8 +2071,10 @@ fn verify( .path() .parent() .ok_or_else(|| anyhow!("Unable to find workspace root"))? - .join("target/verifiable/") - .join(format!("{binary_name}.so")); + .join("target") + .join("verifiable") + .join(&binary_name) + .with_extension("so"); let url = cluster_url(&cfg, &cfg.test_validator); let bin_ver = verify_bin(program_id, &bin_path, &url)?; @@ -3417,7 +3437,8 @@ fn validator_flags( idl.address = address; // Persist it. - let idl_out = PathBuf::from("target/idl") + let idl_out = Path::new("target") + .join("idl") .join(&idl.metadata.name) .with_extension("json"); write_idl(idl, OutFile::File(idl_out))?; @@ -3547,20 +3568,24 @@ fn validator_flags( } fn stream_logs(config: &WithPath, rpc_url: &str) -> Result> { - let program_logs_dir = ".anchor/program-logs"; - if Path::new(program_logs_dir).exists() { - fs::remove_dir_all(program_logs_dir)?; + let program_logs_dir = Path::new(".anchor").join("program-logs"); + if program_logs_dir.exists() { + fs::remove_dir_all(&program_logs_dir)?; } - fs::create_dir_all(program_logs_dir)?; + fs::create_dir_all(&program_logs_dir)?; + let mut handles = vec![]; for program in config.read_all_programs()? { - let idl = fs::read(format!("target/idl/{}.json", program.lib_name))?; + let idl_path = Path::new("target") + .join("idl") + .join(&program.lib_name) + .with_extension("json"); + let idl = fs::read(idl_path)?; let idl = convert_idl(&idl)?; - let log_file = File::create(format!( - "{}/{}.{}.log", - program_logs_dir, idl.address, program.lib_name, - ))?; + let log_file = File::create( + program_logs_dir.join(format!("{}.{}.log", idl.address, program.lib_name)), + )?; let stdio = std::process::Stdio::from(log_file); let child = std::process::Command::new("solana") .arg("logs") @@ -3574,7 +3599,8 @@ fn stream_logs(config: &WithPath, rpc_url: &str) -> Result) -> Result<( Some(TestValidator { validator: Some(validator), .. - }) => &validator.ledger, - _ => DEFAULT_LEDGER_PATH, + }) => PathBuf::from(&validator.ledger), + _ => get_default_ledger_path(), }; - let ledger_path = Path::new(ledger_path); if !ledger_path.is_relative() { // Prevent absolute paths to avoid someone using / or similar, as the @@ -3704,15 +3729,13 @@ fn test_validator_file_paths(test_validator: &Option) -> Result<( std::process::exit(1); } if ledger_path.exists() { - fs::remove_dir_all(ledger_path)?; + fs::remove_dir_all(&ledger_path)?; } - fs::create_dir_all(ledger_path)?; + fs::create_dir_all(&ledger_path)?; - Ok(( - ledger_path.to_owned(), - ledger_path.join("test-ledger-log.txt"), - )) + let log_path = ledger_path.join("test-ledger-log.txt"); + Ok((ledger_path, log_path)) } fn cluster_url(cfg: &Config, test_validator: &Option) -> String { @@ -3825,7 +3848,8 @@ fn deploy( idl.address = program_id.to_string(); // Persist it. - let idl_out = PathBuf::from("target/idl") + let idl_out = Path::new("target") + .join("idl") .join(&idl.metadata.name) .with_extension("json"); write_idl(idl, OutFile::File(idl_out))?; @@ -4267,12 +4291,14 @@ fn run(cfg_override: &ConfigOverride, script: String, script_args: Vec) } fn login(_cfg_override: &ConfigOverride, token: String) -> Result<()> { - let dir = shellexpand::tilde("~/.config/anchor"); - if !Path::new(&dir.to_string()).exists() { - fs::create_dir(dir.to_string())?; + let anchor_dir = Path::new(&*shellexpand::tilde("~")) + .join(".config") + .join("anchor"); + if !anchor_dir.exists() { + fs::create_dir(&anchor_dir)?; } - std::env::set_current_dir(dir.to_string())?; + std::env::set_current_dir(&anchor_dir)?; // Freely overwrite the entire file since it's not used for anything else. let mut file = File::create("credentials")?; @@ -4467,8 +4493,11 @@ fn registry_api_token(_cfg_override: &ConfigOverride) -> Result { struct Credentials { registry: Registry, } - let filename = shellexpand::tilde("~/.config/anchor/credentials"); - let mut file = File::open(filename.to_string())?; + let filename = Path::new(&*shellexpand::tilde("~")) + .join(".config") + .join("anchor") + .join("credentials"); + let mut file = File::open(filename)?; let mut contents = String::new(); file.read_to_string(&mut contents)?; @@ -4730,7 +4759,8 @@ fn get_node_dns_option() -> Result<&'static str> { // of spaces in keypair/binary paths, but this should be fixed in the Solana CLI // and removed here. fn strip_workspace_prefix(absolute_path: String) -> String { - let workspace_prefix = std::env::current_dir().unwrap().display().to_string() + "/"; + let workspace_prefix = + std::env::current_dir().unwrap().display().to_string() + std::path::MAIN_SEPARATOR_STR; absolute_path .strip_prefix(&workspace_prefix) .unwrap_or(&absolute_path) From a043abd4d312cdb7ca7e590571f12b1ed0fdba66 Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Fri, 11 Oct 2024 23:59:05 +0200 Subject: [PATCH 16/18] cli: Add `--program-id` option to `idl convert` command (#3309) --- CHANGELOG.md | 1 + cli/src/lib.rs | 27 +++++++++++++++++++++++++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ef4602b76..a9af9fa6c7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -53,6 +53,7 @@ The minor version will be incremented upon a breaking change and the patch versi - cli: Check whether the `idl-build` feature exists when using the `idl build` command ([#3273](https://github.com/coral-xyz/anchor/pull/3273)). - cli: Build IDL if there is only one program when using the `idl build` command ([#3275](https://github.com/coral-xyz/anchor/pull/3275)). - cli: Add short alias for the `idl build` command ([#3283](https://github.com/coral-xyz/anchor/pull/3283)). +- cli: Add `--program-id` option to `idl convert` command ([#3309](https://github.com/coral-xyz/anchor/pull/3309)). ### Fixes diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 51c280cc83..31be5dbb17 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -506,6 +506,9 @@ pub enum IdlCommand { /// Output file for the IDL (stdout if not specified) #[clap(short, long)] out: Option, + /// Address to use (defaults to `metadata.address` value) + #[clap(short, long)] + program_id: Option, }, /// Generate TypeScript type for the IDL Type { @@ -2302,7 +2305,11 @@ fn idl(cfg_override: &ConfigOverride, subcmd: IdlCommand) -> Result<()> { cargo_args, ), IdlCommand::Fetch { address, out } => idl_fetch(cfg_override, address, out), - IdlCommand::Convert { path, out } => idl_convert(path, out), + IdlCommand::Convert { + path, + out, + program_id, + } => idl_convert(path, out, program_id), IdlCommand::Type { path, out } => idl_type(path, out), } } @@ -2809,8 +2816,24 @@ fn idl_fetch(cfg_override: &ConfigOverride, address: Pubkey, out: Option write_idl(&idl, out) } -fn idl_convert(path: String, out: Option) -> Result<()> { +fn idl_convert(path: String, out: Option, program_id: Option) -> Result<()> { let idl = fs::read(path)?; + + // Set the `metadata.address` field based on the given `program_id` + let idl = match program_id { + Some(program_id) => { + let mut idl = serde_json::from_slice::(&idl)?; + idl.as_object_mut() + .ok_or_else(|| anyhow!("IDL must be an object"))? + .insert( + "metadata".into(), + serde_json::json!({ "address": program_id.to_string() }), + ); + serde_json::to_vec(&idl)? + } + _ => idl, + }; + let idl = convert_idl(&idl)?; let out = match out { None => OutFile::Stdout, From 6e7783800987d55e450ea1cac5727fbc00dcd900 Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Sat, 12 Oct 2024 23:59:39 +0200 Subject: [PATCH 17/18] ci: Re-enable the `anchor init` test (#3310) --- .github/workflows/reusable-tests.yaml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/workflows/reusable-tests.yaml b/.github/workflows/reusable-tests.yaml index b6725485ee..1c7d815a32 100644 --- a/.github/workflows/reusable-tests.yaml +++ b/.github/workflows/reusable-tests.yaml @@ -358,9 +358,8 @@ jobs: path: ~/.cargo/bin/ - run: chmod +x ~/.cargo/bin/anchor - # TODO: Re-enable once https://github.com/solana-labs/solana/issues/33504 is resolved - # - run: cd "$(mktemp -d)" && anchor init hello-anchor && cd hello-anchor && yarn link @coral-xyz/anchor && yarn && anchor test && yarn lint:fix - # - uses: ./.github/actions/git-diff/ + - run: cd "$(mktemp -d)" && anchor init hello-anchor && cd hello-anchor && yarn link @coral-xyz/anchor && yarn && anchor test && yarn lint:fix + - uses: ./.github/actions/git-diff/ test-programs: needs: setup-anchor-cli From f5f8edf77d9c1fe406a44f589605fc23ae17fb8b Mon Sep 17 00:00:00 2001 From: acheron <98934430+acheroncrypto@users.noreply.github.com> Date: Sun, 13 Oct 2024 23:59:36 +0200 Subject: [PATCH 18/18] lang: Generate documentation of constants in `declare_program!` (#3311) --- CHANGELOG.md | 1 + .../program/src/declare_program/mods/constants.rs | 9 ++++++--- tests/declare-program/idls/external.json | 3 +++ tests/declare-program/programs/external/src/lib.rs | 1 + 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a9af9fa6c7..e69c51182f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -54,6 +54,7 @@ The minor version will be incremented upon a breaking change and the patch versi - cli: Build IDL if there is only one program when using the `idl build` command ([#3275](https://github.com/coral-xyz/anchor/pull/3275)). - cli: Add short alias for the `idl build` command ([#3283](https://github.com/coral-xyz/anchor/pull/3283)). - cli: Add `--program-id` option to `idl convert` command ([#3309](https://github.com/coral-xyz/anchor/pull/3309)). +- lang: Generate documentation of constants in `declare_program!` ([#3311](https://github.com/coral-xyz/anchor/pull/3311)). ### Fixes diff --git a/lang/attribute/program/src/declare_program/mods/constants.rs b/lang/attribute/program/src/declare_program/mods/constants.rs index 74093c6bd4..cf046fa05f 100644 --- a/lang/attribute/program/src/declare_program/mods/constants.rs +++ b/lang/attribute/program/src/declare_program/mods/constants.rs @@ -1,11 +1,12 @@ use anchor_lang_idl::types::{Idl, IdlType}; use quote::{format_ident, quote, ToTokens}; -use super::common::convert_idl_type_to_syn_type; +use super::common::{convert_idl_type_to_syn_type, gen_docs}; pub fn gen_constants_mod(idl: &Idl) -> proc_macro2::TokenStream { let constants = idl.constants.iter().map(|c| { let name = format_ident!("{}", c.name); + let docs = gen_docs(&c.docs); let val = syn::parse_str::(&c.value) .unwrap() .to_token_stream(); @@ -15,8 +16,10 @@ pub fn gen_constants_mod(idl: &Idl) -> proc_macro2::TokenStream { _ => (convert_idl_type_to_syn_type(&c.ty).to_token_stream(), val), }; - // TODO: Docs - quote! { pub const #name: #ty = #val; } + quote! { + #docs + pub const #name: #ty = #val; + } }); quote! { diff --git a/tests/declare-program/idls/external.json b/tests/declare-program/idls/external.json index 1f0fbe091f..3bb4e4b641 100644 --- a/tests/declare-program/idls/external.json +++ b/tests/declare-program/idls/external.json @@ -279,6 +279,9 @@ "constants": [ { "name": "MASTER_SEED", + "docs": [ + "Master seed slice" + ], "type": "bytes", "value": "[109, 97, 115, 116, 101, 114]" } diff --git a/tests/declare-program/programs/external/src/lib.rs b/tests/declare-program/programs/external/src/lib.rs index 0a5284744c..86a08ae0b8 100644 --- a/tests/declare-program/programs/external/src/lib.rs +++ b/tests/declare-program/programs/external/src/lib.rs @@ -2,6 +2,7 @@ use anchor_lang::prelude::*; declare_id!("Externa111111111111111111111111111111111111"); +/// Master seed slice #[constant] pub const MASTER_SEED: &[u8] = b"master";