idl: Add `IdlBuilder` (#3188)

This commit is contained in:
acheron 2024-08-22 23:56:33 +02:00 committed by GitHub
parent 6d37cce8f3
commit 84fdf31d58
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 93 additions and 38 deletions

View File

@ -40,6 +40,7 @@ The minor version will be incremented upon a breaking change and the patch versi
- cli: Add `--no-idl` option to the `test` command ([#3175](https://github.com/coral-xyz/anchor/pull/3175)).
- spl: Add `burn_checked`, `mint_to_checked` and `approve_checked` instructions ([#3186]([https://github.com/coral-xyz/anchor/pull/3186)).
- cli: Migrate to `agave-install` when `solana_version` is `>= 1.18.19` ([#3185](https://github.com/coral-xyz/anchor/pull/3185)).
- idl: Add `IdlBuilder` ([#3188](https://github.com/coral-xyz/anchor/pull/3188)).
### Fixes

View File

@ -2722,13 +2722,13 @@ fn idl_build(
}
};
check_idl_build_feature().ok();
let idl = anchor_lang_idl::build::build_idl_with_cargo_args(
program_path,
cfg.features.resolution,
cfg.features.skip_lint || skip_lint,
no_docs,
&cargo_args,
)?;
let idl = anchor_lang_idl::build::IdlBuilder::new()
.program_path(program_path)
.resolution(cfg.features.resolution)
.skip_lint(cfg.features.skip_lint || skip_lint)
.no_docs(no_docs)
.cargo_args(cargo_args)
.build()?;
let out = match out {
Some(path) => OutFile::File(PathBuf::from(path)),
None => OutFile::Stdout,
@ -2776,13 +2776,12 @@ in `{path}`."#
check_idl_build_feature().ok();
anchor_lang_idl::build::build_idl_with_cargo_args(
std::env::current_dir()?,
cfg.features.resolution,
cfg.features.skip_lint || skip_lint,
no_docs,
cargo_args,
)
anchor_lang_idl::build::IdlBuilder::new()
.resolution(cfg.features.resolution)
.skip_lint(cfg.features.skip_lint || skip_lint)
.no_docs(no_docs)
.cargo_args(cargo_args.into())
.build()
}
fn idl_fetch(cfg_override: &ConfigOverride, address: Pubkey, out: Option<String>) -> Result<()> {

View File

@ -1,7 +1,7 @@
use std::{
collections::BTreeMap,
env, mem,
path::Path,
path::{Path, PathBuf},
process::{Command, Stdio},
};
@ -43,36 +43,91 @@ pub trait IdlBuild {
}
}
/// IDL builder using builder pattern.
///
/// # Example
///
/// ```ignore
/// let idl = IdlBuilder::new().program_path(path).skip_lint(true).build()?;
/// ```
#[derive(Default)]
pub struct IdlBuilder {
program_path: Option<PathBuf>,
resolution: Option<bool>,
skip_lint: Option<bool>,
no_docs: Option<bool>,
cargo_args: Option<Vec<String>>,
}
impl IdlBuilder {
/// Create a new [`IdlBuilder`] instance.
pub fn new() -> Self {
Self::default()
}
/// Set the program path (default: current directory)
pub fn program_path(mut self, program_path: PathBuf) -> Self {
self.program_path.replace(program_path);
self
}
/// Set whether to include account resolution information in the IDL (default: true).
pub fn resolution(mut self, resolution: bool) -> Self {
self.resolution.replace(resolution);
self
}
/// Set whether to skip linting (default: false).
pub fn skip_lint(mut self, skip_lint: bool) -> Self {
self.skip_lint.replace(skip_lint);
self
}
/// Set whether to skip generating docs in the IDL (default: false).
pub fn no_docs(mut self, no_docs: bool) -> Self {
self.no_docs.replace(no_docs);
self
}
/// Set the `cargo` args that will get passed to the underyling `cargo` command when building
/// IDLs (default: empty).
pub fn cargo_args(mut self, cargo_args: Vec<String>) -> Self {
self.cargo_args.replace(cargo_args);
self
}
/// Build the IDL with the current configuration.
pub fn build(self) -> Result<Idl> {
let idl = build(
&self
.program_path
.unwrap_or_else(|| std::env::current_dir().expect("Failed to get program path")),
self.resolution.unwrap_or(true),
self.skip_lint.unwrap_or_default(),
self.no_docs.unwrap_or_default(),
&self.cargo_args.unwrap_or_default(),
)
.map(convert_module_paths)
.map(sort)?;
verify(&idl)?;
Ok(idl)
}
}
/// Generate IDL via compilation.
#[deprecated(since = "0.1.2", note = "Use `IdlBuilder` instead")]
pub fn build_idl(
program_path: impl AsRef<Path>,
resolution: bool,
skip_lint: bool,
no_docs: bool,
) -> Result<Idl> {
build_idl_with_cargo_args(program_path, resolution, skip_lint, no_docs, &[])
}
/// Generate IDL via compilation with passing cargo arguments.
pub fn build_idl_with_cargo_args(
program_path: impl AsRef<Path>,
resolution: bool,
skip_lint: bool,
no_docs: bool,
cargo_args: &[String],
) -> Result<Idl> {
let idl = build(
program_path.as_ref(),
resolution,
skip_lint,
no_docs,
cargo_args,
)?;
let idl = convert_module_paths(idl);
let idl = sort(idl);
verify(&idl)?;
Ok(idl)
IdlBuilder::new()
.program_path(program_path.as_ref().into())
.resolution(resolution)
.skip_lint(skip_lint)
.no_docs(no_docs)
.build()
}
/// Build IDL.