Skip to content

Commit

Permalink
cli: Add anchor expand command (#1160)
Browse files Browse the repository at this point in the history
  • Loading branch information
paul-schaaf authored Dec 27, 2021
1 parent 22c2c30 commit 1749a7b
Show file tree
Hide file tree
Showing 5 changed files with 212 additions and 76 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ incremented for features.

## [Unreleased]


### Fixes

* ts: Change commitment message `recent` to `processed` and `max` to `finalized` ([#1128](https://github.com/project-serum/anchor/pull/1128))
Expand All @@ -26,6 +25,7 @@ incremented for features.
* lang: Handle arrays with const as length ([#968](https://github.com/project-serum/anchor/pull/968)).
* ts: Add optional commitment argument to `fetch` and `fetchMultiple` ([#1171](https://github.com/project-serum/anchor/pull/1171)).
* lang: Implement `AsRef<T>` for `Account<'a, T>`([#1173](https://github.com/project-serum/anchor/pull/1173))
* cli: Add `anchor expand` command which wraps around `cargo expand` ([#1160](https://github.com/project-serum/anchor/pull/1160))

### Breaking

Expand Down
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -38,3 +38,4 @@ tokio = "1.0"
pathdiff = "0.2.0"
cargo_toml = "0.9.2"
walkdir = "2"
chrono = "0.4.19"
120 changes: 120 additions & 0 deletions cli/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use solana_sdk::sysvar;
use solana_sdk::transaction::Transaction;
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::ffi::OsString;
use std::fs::{self, File};
use std::io::prelude::*;
use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -97,6 +98,25 @@ pub enum Command {
)]
cargo_args: Vec<String>,
},
/// Expands macros (wrapper around cargo expand)
///
/// Use it in a program folder to expand program
///
/// Use it in a workspace but outside a program
/// folder to expand the entire workspace
Expand {
/// Expand only this program
#[clap(short, long)]
program_name: Option<String>,
/// Arguments to pass to the underlying `cargo expand` command
#[clap(
required = false,
takes_value = true,
multiple_values = true,
last = true
)]
cargo_args: Vec<String>,
},
/// Verifies the on-chain bytecode matches the locally compiled artifact.
/// Run this command inside a program subdirectory, i.e., in the dir
/// containing the program's Cargo.toml.
Expand Down Expand Up @@ -370,6 +390,10 @@ pub fn entry(opts: Opts) -> Result<()> {
cargo_args,
),
Command::Deploy { program_name } => deploy(&opts.cfg_override, program_name),
Command::Expand {
program_name,
cargo_args,
} => expand(&opts.cfg_override, program_name, &cargo_args),
Command::Upgrade {
program_id,
program_filepath,
Expand Down Expand Up @@ -559,6 +583,102 @@ fn new_program(name: &str) -> Result<()> {
Ok(())
}

pub fn expand(
cfg_override: &ConfigOverride,
program_name: Option<String>,
cargo_args: &[String],
) -> Result<()> {
// Change to the workspace member directory, if needed.
if let Some(program_name) = program_name.as_ref() {
cd_member(cfg_override, program_name)?;
}

let workspace_cfg = Config::discover(cfg_override)?.expect("Not in workspace.");
let cfg_parent = workspace_cfg.path().parent().expect("Invalid Anchor.toml");
let cargo = Manifest::discover()?;

let expansions_path = cfg_parent.join(".anchor/expanded-macros");
fs::create_dir_all(&expansions_path)?;

match cargo {
// No Cargo.toml found, expand entire workspace
None => expand_all(&workspace_cfg, expansions_path, cargo_args),
// Cargo.toml is at root of workspace, expand entire workspace
Some(cargo) if cargo.path().parent() == workspace_cfg.path().parent() => {
expand_all(&workspace_cfg, expansions_path, cargo_args)
}
// Reaching this arm means Cargo.toml belongs to a single package. Expand it.
Some(cargo) => expand_program(
// If we found Cargo.toml, it must be in a directory so unwrap is safe
cargo.path().parent().unwrap().to_path_buf(),
expansions_path,
cargo_args,
),
}
}

fn expand_all(
workspace_cfg: &WithPath<Config>,
expansions_path: PathBuf,
cargo_args: &[String],
) -> Result<()> {
let cur_dir = std::env::current_dir()?;
for p in workspace_cfg.get_program_list()? {
expand_program(p, expansions_path.clone(), cargo_args)?;
}
std::env::set_current_dir(cur_dir)?;
Ok(())
}

fn expand_program(
program_path: PathBuf,
expansions_path: PathBuf,
cargo_args: &[String],
) -> Result<()> {
let cargo = Manifest::from_path(program_path.join("Cargo.toml"))
.map_err(|_| anyhow!("Could not find Cargo.toml for program"))?;

let target_dir_arg = {
let mut target_dir_arg = OsString::from("--target-dir=");
target_dir_arg.push(expansions_path.join("expand-target"));
target_dir_arg
};

let package_name = &cargo
.package
.as_ref()
.ok_or_else(|| anyhow!("Cargo config is missing a package"))?
.name;
let program_expansions_path = expansions_path.join(package_name);
fs::create_dir_all(&program_expansions_path)?;

let exit = std::process::Command::new("cargo")
.arg("expand")
.arg(target_dir_arg)
.arg(&format!("--package={}", package_name))
.args(cargo_args)
.stderr(Stdio::inherit())
.output()
.map_err(|e| anyhow::format_err!("{}", e.to_string()))?;
if !exit.status.success() {
eprintln!("'anchor expand' failed. Perhaps you have not installed 'cargo-expand'? https://github.com/dtolnay/cargo-expand#installation");
std::process::exit(exit.status.code().unwrap_or(1));
}

let version = cargo.version();
let time = chrono::Utc::now().to_string().replace(' ', "_");
let file_path =
program_expansions_path.join(format!("{}-{}-{}.rs", package_name, version, time));
fs::write(&file_path, &exit.stdout).map_err(|e| anyhow::format_err!("{}", e.to_string()))?;

println!(
"Expanded {} into file {}\n",
package_name,
file_path.to_string_lossy()
);
Ok(())
}

#[allow(clippy::too_many_arguments)]
pub fn build(
cfg_override: &ConfigOverride,
Expand Down
Loading

0 comments on commit 1749a7b

Please sign in to comment.