Skip to content

Commit f72ec22

Browse files
cli, idl: Pass cargo args to IDL generation (otter-sec#3059)
1 parent 6839d27 commit f72ec22

3 files changed

Lines changed: 58 additions & 18 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ The minor version will be incremented upon a breaking change and the patch versi
1313
### Features
1414

1515
- ts: Add optional `commitment` parameter to `Program.addEventListener` ([#3052](https://github.com/coral-xyz/anchor/pull/3052)).
16+
- cli: Pass "cargo args" to idl generation when building program or idl ([#3059](https://github.com/coral-xyz/anchor/pull/3059)).
1617

1718
### Fixes
1819

cli/src/lib.rs

Lines changed: 30 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -480,6 +480,9 @@ pub enum IdlCommand {
480480
/// Do not check for safety comments
481481
#[clap(long)]
482482
skip_lint: bool,
483+
/// Arguments to pass to the underlying `cargo test` command
484+
#[clap(required = false, last = true)]
485+
cargo_args: Vec<String>,
483486
},
484487
/// Fetches an IDL for the given address from a cluster.
485488
/// The address can be a program, IDL account, or IDL buffer.
@@ -1274,7 +1277,6 @@ pub fn build(
12741277
if let Some(program_name) = program_name.as_ref() {
12751278
cd_member(cfg_override, program_name)?;
12761279
}
1277-
12781280
let cfg = Config::discover(cfg_override)?.expect("Not in workspace.");
12791281
let cfg_parent = cfg.path().parent().expect("Invalid Anchor.toml");
12801282

@@ -1523,7 +1525,7 @@ fn build_cwd_verifiable(
15231525
stdout,
15241526
stderr,
15251527
env_vars,
1526-
cargo_args,
1528+
cargo_args.clone(),
15271529
arch,
15281530
);
15291531

@@ -1534,7 +1536,7 @@ fn build_cwd_verifiable(
15341536
Ok(_) => {
15351537
// Build the idl.
15361538
println!("Extracting the IDL");
1537-
let idl = generate_idl(cfg, skip_lint, no_docs)?;
1539+
let idl = generate_idl(cfg, skip_lint, no_docs, &cargo_args)?;
15381540
// Write out the JSON file.
15391541
println!("Writing the IDL file");
15401542
let out_file = workspace_dir.join(format!("target/idl/{}.json", idl.metadata.name));
@@ -1820,18 +1822,17 @@ fn _build_rust_cwd(
18201822
let subcommand = arch.build_subcommand();
18211823
let exit = std::process::Command::new("cargo")
18221824
.arg(subcommand)
1823-
.args(cargo_args)
1825+
.args(cargo_args.clone())
18241826
.stdout(Stdio::inherit())
18251827
.stderr(Stdio::inherit())
18261828
.output()
18271829
.map_err(|e| anyhow::format_err!("{}", e.to_string()))?;
18281830
if !exit.status.success() {
18291831
std::process::exit(exit.status.code().unwrap_or(1));
18301832
}
1831-
18321833
// Generate IDL
18331834
if !no_idl {
1834-
let idl = generate_idl(cfg, skip_lint, no_docs)?;
1835+
let idl = generate_idl(cfg, skip_lint, no_docs, &cargo_args)?;
18351836

18361837
// JSON out path.
18371838
let out = match idl_out {
@@ -1984,7 +1985,7 @@ fn verify(
19841985
None,
19851986
None,
19861987
env_vars,
1987-
cargo_args,
1988+
cargo_args.clone(),
19881989
false,
19891990
arch,
19901991
)?;
@@ -2008,7 +2009,7 @@ fn verify(
20082009
}
20092010

20102011
// Verify IDL (only if it's not a buffer account).
2011-
let local_idl = generate_idl(&cfg, true, false)?;
2012+
let local_idl = generate_idl(&cfg, true, false, &cargo_args)?;
20122013
if bin_ver.state != BinVerificationState::Buffer {
20132014
let deployed_idl = fetch_idl(cfg_override, program_id)?;
20142015
if local_idl != deployed_idl {
@@ -2215,7 +2216,16 @@ fn idl(cfg_override: &ConfigOverride, subcmd: IdlCommand) -> Result<()> {
22152216
out_ts,
22162217
no_docs,
22172218
skip_lint,
2218-
} => idl_build(cfg_override, program_name, out, out_ts, no_docs, skip_lint),
2219+
cargo_args,
2220+
} => idl_build(
2221+
cfg_override,
2222+
program_name,
2223+
out,
2224+
out_ts,
2225+
no_docs,
2226+
skip_lint,
2227+
cargo_args,
2228+
),
22192229
IdlCommand::Fetch { address, out } => idl_fetch(cfg_override, address, out),
22202230
IdlCommand::Convert { path, out } => idl_convert(path, out),
22212231
IdlCommand::Type { path, out } => idl_type(path, out),
@@ -2657,6 +2667,7 @@ fn idl_build(
26572667
out_ts: Option<String>,
26582668
no_docs: bool,
26592669
skip_lint: bool,
2670+
cargo_args: Vec<String>,
26602671
) -> Result<()> {
26612672
let cfg = Config::discover(cfg_override)?.expect("Not in workspace");
26622673
let program_path = match program_name {
@@ -2670,11 +2681,12 @@ fn idl_build(
26702681
.path
26712682
}
26722683
};
2673-
let idl = anchor_lang_idl::build::build_idl(
2684+
let idl = anchor_lang_idl::build::build_idl_with_cargo_args(
26742685
program_path,
26752686
cfg.features.resolution,
26762687
cfg.features.skip_lint || skip_lint,
26772688
no_docs,
2689+
&cargo_args,
26782690
)?;
26792691
let out = match out {
26802692
Some(path) => OutFile::File(PathBuf::from(path)),
@@ -2690,7 +2702,12 @@ fn idl_build(
26902702
}
26912703

26922704
/// Generate IDL with method decided by whether manifest file has `idl-build` feature or not.
2693-
fn generate_idl(cfg: &WithPath<Config>, skip_lint: bool, no_docs: bool) -> Result<Idl> {
2705+
fn generate_idl(
2706+
cfg: &WithPath<Config>,
2707+
skip_lint: bool,
2708+
no_docs: bool,
2709+
cargo_args: &[String],
2710+
) -> Result<Idl> {
26942711
// Check whether the manifest has `idl-build` feature
26952712
let manifest = Manifest::discover()?.ok_or_else(|| anyhow!("Cargo.toml not found"))?;
26962713
let is_idl_build = manifest
@@ -2716,11 +2733,12 @@ in `{path}`."#
27162733
));
27172734
}
27182735

2719-
anchor_lang_idl::build::build_idl(
2736+
anchor_lang_idl::build::build_idl_with_cargo_args(
27202737
std::env::current_dir()?,
27212738
cfg.features.resolution,
27222739
cfg.features.skip_lint || skip_lint,
27232740
no_docs,
2741+
cargo_args,
27242742
)
27252743
}
27262744

idl/src/build.rs

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,24 @@ pub fn build_idl(
5050
skip_lint: bool,
5151
no_docs: bool,
5252
) -> Result<Idl> {
53-
let idl = build(program_path.as_ref(), resolution, skip_lint, no_docs)?;
53+
build_idl_with_cargo_args(program_path, resolution, skip_lint, no_docs, &[])
54+
}
55+
56+
/// Generate IDL via compilation with passing cargo arguments.
57+
pub fn build_idl_with_cargo_args(
58+
program_path: impl AsRef<Path>,
59+
resolution: bool,
60+
skip_lint: bool,
61+
no_docs: bool,
62+
cargo_args: &[String],
63+
) -> Result<Idl> {
64+
let idl = build(
65+
program_path.as_ref(),
66+
resolution,
67+
skip_lint,
68+
no_docs,
69+
cargo_args,
70+
)?;
5471
let idl = convert_module_paths(idl);
5572
let idl = sort(idl);
5673
verify(&idl)?;
@@ -59,25 +76,29 @@ pub fn build_idl(
5976
}
6077

6178
/// Build IDL.
62-
fn build(program_path: &Path, resolution: bool, skip_lint: bool, no_docs: bool) -> Result<Idl> {
79+
fn build(
80+
program_path: &Path,
81+
resolution: bool,
82+
skip_lint: bool,
83+
no_docs: bool,
84+
cargo_args: &[String],
85+
) -> Result<Idl> {
6386
// `nightly` toolchain is currently required for building the IDL.
6487
let toolchain = std::env::var("RUSTUP_TOOLCHAIN")
6588
.map(|toolchain| format!("+{}", toolchain))
6689
.unwrap_or_else(|_| "+nightly".to_string());
6790

6891
install_toolchain_if_needed(&toolchain)?;
69-
7092
let output = Command::new("cargo")
7193
.args([
7294
&toolchain,
7395
"test",
7496
"__anchor_private_print_idl",
7597
"--features",
7698
"idl-build",
77-
"--",
78-
"--show-output",
79-
"--quiet",
8099
])
100+
.args(cargo_args)
101+
.args(["--", "--show-output", "--quiet"])
81102
.env(
82103
"ANCHOR_IDL_BUILD_NO_DOCS",
83104
if no_docs { "TRUE" } else { "FALSE" },

0 commit comments

Comments
 (0)