Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add options for package manager #3328

Merged
merged 13 commits into from
Oct 27, 2024
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,9 @@ The minor version will be incremented upon a breaking change and the patch versi
- 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)).
- cli: Add support for fetching legacy IDLs ([#3324](https://github.com/coral-xyz/anchor/pull/3324)).
- avm: Add short alias for `install` and `list` command ([#3326])(https://github.com/coral-xyz/anchor/pull/3326).
- avm: Add short alias for `install` and `list` commands ([#3326](https://github.com/coral-xyz/anchor/pull/3326)).
- avm: Add Windows support for renaming anchor binary ([#3325](https://github.com/coral-xyz/anchor/pull/3325)).
- cli: Add optional `package-manager` flag in `init` command to set package manager field in Anchor.toml ([#3328](https://github.com/coral-xyz/anchor/pull/3328)).

### Fixes

Expand Down
13 changes: 11 additions & 2 deletions cli/src/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use anyhow::{anyhow, Result};
use semver::{Version, VersionReq};

use crate::{
config::{Config, Manifest, WithPath},
config::{Config, Manifest, PackageManager, WithPath},
VERSION,
};

Expand Down Expand Up @@ -69,12 +69,21 @@ pub fn check_anchor_version(cfg: &WithPath<Config>) -> Result<()> {
.and_then(|ver| VersionReq::parse(ver).ok())
.filter(|ver| !ver.matches(&cli_version));

let update_cmd = match &cfg.toolchain.package_manager {
Some(pkg_manager) => match pkg_manager {
PackageManager::NPM => "npm update",
PackageManager::Yarn => "yarn upgrade",
PackageManager::PNPM => "pnpm update",
},
None => "npm update",
};

if let Some(ver) = mismatched_ts_version {
eprintln!(
"WARNING: `@coral-xyz/anchor` version({ver}) and the current CLI version\
({cli_version}) don't match.\n\n\t\
This can lead to unwanted behavior. To fix, upgrade the package by running:\n\n\t\
yarn upgrade @coral-xyz/anchor@{cli_version}\n"
{update_cmd} @coral-xyz/anchor@{cli_version}\n"
);
}

Expand Down
25 changes: 25 additions & 0 deletions cli/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,31 @@ pub struct Config {
pub struct ToolchainConfig {
pub anchor_version: Option<String>,
pub solana_version: Option<String>,
pub package_manager: Option<PackageManager>,
}

/// Package manager to use for the project.
#[derive(Clone, Debug, Default, Eq, PartialEq, Parser, ValueEnum, Serialize, Deserialize)]
pub enum PackageManager {
/// Use npm as the package manager.
NPM,
/// Use yarn as the package manager.
#[default]
Yarn,
/// Use pnpm as the package manager.
PNPM,
}

impl std::fmt::Display for PackageManager {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
let pkg_manager_str = match self {
PackageManager::NPM => "npm",
PackageManager::Yarn => "yarn",
PackageManager::PNPM => "pnpm",
};

write!(f, "{pkg_manager_str}")
}
}

#[derive(Clone, Debug, Serialize, Deserialize)]
Expand Down
41 changes: 32 additions & 9 deletions cli/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::config::{
get_default_ledger_path, AnchorPackage, BootstrapMode, BuildConfig, Config, ConfigOverride,
Manifest, ProgramArch, ProgramDeployment, ProgramWorkspace, ScriptsConfig, TestValidator,
WithPath, SHUTDOWN_WAIT, STARTUP_WAIT,
Manifest, PackageManager, ProgramArch, ProgramDeployment, ProgramWorkspace, ScriptsConfig,
TestValidator, WithPath, SHUTDOWN_WAIT, STARTUP_WAIT,
};
use anchor_client::Cluster;
use anchor_lang::idl::{IdlAccount, IdlInstruction, ERASED_AUTHORITY};
Expand Down Expand Up @@ -82,6 +82,9 @@ pub enum Command {
/// Don't install JavaScript dependencies
#[clap(long)]
no_install: bool,
/// Package Manager to use
#[clap(value_enum, long, default_value = "yarn")]
package_manager: PackageManager,
/// Don't initialize git
#[clap(long)]
no_git: bool,
Expand Down Expand Up @@ -756,6 +759,7 @@ fn process_command(opts: Opts) -> Result<()> {
javascript,
solidity,
no_install,
package_manager,
no_git,
template,
test_template,
Expand All @@ -766,6 +770,7 @@ fn process_command(opts: Opts) -> Result<()> {
javascript,
solidity,
no_install,
package_manager,
no_git,
template,
test_template,
Expand Down Expand Up @@ -952,6 +957,7 @@ fn init(
javascript: bool,
solidity: bool,
no_install: bool,
package_manager: PackageManager,
no_git: bool,
template: ProgramTemplate,
test_template: TestTemplate,
Expand Down Expand Up @@ -990,9 +996,12 @@ fn init(
fs::create_dir_all("app")?;

let mut cfg = Config::default();
let test_script = test_template.get_test_script(javascript);
cfg.scripts
.insert("test".to_owned(), test_script.to_owned());

let test_script = test_template.get_test_script(javascript, &package_manager);
cfg.scripts.insert("test".to_owned(), test_script);

let package_manager_cmd = package_manager.to_string();
cfg.toolchain.package_manager = Some(package_manager);

let mut localnet = BTreeMap::new();
let program_id = rust_template::get_or_create_program_id(&rust_name);
Expand Down Expand Up @@ -1064,10 +1073,16 @@ fn init(
)?;

if !no_install {
let yarn_result = install_node_modules("yarn")?;
if !yarn_result.status.success() {
println!("Failed yarn install will attempt to npm install");
let package_manager_result = install_node_modules(&package_manager_cmd)?;

if !package_manager_result.status.success() && package_manager_cmd != "npm" {
println!(
"Failed {} install will attempt to npm install",
package_manager_cmd
);
install_node_modules("npm")?;
} else {
eprintln!("Failed to install node modules");
}
}

Expand Down Expand Up @@ -4124,7 +4139,12 @@ fn migrate(cfg_override: &ConfigOverride) -> Result<()> {
rust_template::deploy_ts_script_host(&url, &module_path.display().to_string());
fs::write(deploy_ts, deploy_script_host_str)?;

std::process::Command::new("yarn")
let pkg_manager_cmd = match &cfg.toolchain.package_manager {
Some(pkg_manager) => pkg_manager.to_string(),
None => PackageManager::default().to_string(),
};

std::process::Command::new(pkg_manager_cmd)
.args([
"run",
"ts-node",
Expand Down Expand Up @@ -4812,6 +4832,7 @@ mod tests {
true,
false,
true,
PackageManager::default(),
false,
ProgramTemplate::default(),
TestTemplate::default(),
Expand All @@ -4832,6 +4853,7 @@ mod tests {
true,
false,
true,
PackageManager::default(),
false,
ProgramTemplate::default(),
TestTemplate::default(),
Expand All @@ -4852,6 +4874,7 @@ mod tests {
true,
false,
true,
PackageManager::default(),
false,
ProgramTemplate::default(),
TestTemplate::default(),
Expand Down
26 changes: 16 additions & 10 deletions cli/src/rust_template.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{
config::ProgramWorkspace, create_files, override_or_create_files, solidity_template, Files,
VERSION,
PackageManager, VERSION,
};
use anyhow::Result;
use clap::{Parser, ValueEnum};
Expand Down Expand Up @@ -401,7 +401,7 @@ pub fn ts_package_json(jest: bool, license: String) -> String {
if jest {
format!(
r#"{{
"license": "{license}",
"license": "{license}",
"scripts": {{
"lint:fix": "prettier */*.js \"*/**/*{{.js,.ts}}\" -w",
"lint": "prettier */*.js \"*/**/*{{.js,.ts}}\" --check"
Expand All @@ -423,7 +423,7 @@ pub fn ts_package_json(jest: bool, license: String) -> String {
} else {
format!(
r#"{{
"license": "{license}",
"license": "{license}",
"scripts": {{
"lint:fix": "prettier */*.js \"*/**/*{{.js,.ts}}\" -w",
"lint": "prettier */*.js \"*/**/*{{.js,.ts}}\" --check"
Expand Down Expand Up @@ -607,30 +607,36 @@ pub enum TestTemplate {
/// Generate template for Mocha unit-test
#[default]
Mocha,
/// Generate template for Jest unit-test
/// Generate template for Jest unit-test
Jest,
/// Generate template for Rust unit-test
Rust,
}

impl TestTemplate {
pub fn get_test_script(&self, js: bool) -> &str {
pub fn get_test_script(&self, js: bool, pkg_manager: &PackageManager) -> String {
let pkg_manager_exec_cmd = match pkg_manager {
PackageManager::Yarn => "yarn run",
PackageManager::NPM => "npx",
PackageManager::PNPM => "pnpm exec",
};

match &self {
Self::Mocha => {
if js {
"yarn run mocha -t 1000000 tests/"
format!("{pkg_manager_exec_cmd} mocha -t 1000000 tests/")
} else {
"yarn run ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts"
format!("{pkg_manager_exec_cmd} ts-mocha -p ./tsconfig.json -t 1000000 tests/**/*.ts")
}
}
Self::Jest => {
if js {
"yarn run jest"
format!("{pkg_manager_exec_cmd} jest")
} else {
"yarn run jest --preset ts-jest"
format!("{pkg_manager_exec_cmd} jest --preset ts-jest")
}
}
Self::Rust => "cargo test",
Self::Rust => "cargo test".to_owned(),
}
}

Expand Down
Loading