From 77ecc314310c3595505a6a8e3e928fed84968684 Mon Sep 17 00:00:00 2001 From: acheron Date: Sat, 14 Sep 2024 17:11:54 +0200 Subject: [PATCH] cli: Warn if a manifest has `solana-program` dependency --- cli/src/checks.rs | 30 ++++++++++++++++++++++++++++++ cli/src/lib.rs | 3 ++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/cli/src/checks.rs b/cli/src/checks.rs index 20069c4455..b4c188e93c 100644 --- a/cli/src/checks.rs +++ b/cli/src/checks.rs @@ -81,6 +81,36 @@ pub fn check_anchor_version(cfg: &WithPath) -> Result<()> { Ok(()) } +/// Check for potential dependency improvements. +/// +/// The main problem people will run into with Solana v2 is that the `solana-program` version +/// specified in users' `Cargo.toml` might be incompatible with `anchor-lang`'s dependency. +/// To fix this and similar problems, users should use the crates exported from `anchor-lang` or +/// `anchor-spl` when possible. +pub fn check_deps(cfg: &WithPath) -> Result<()> { + // Check `solana-program` + cfg.get_rust_program_list()? + .into_iter() + .map(|path| path.join("Cargo.toml")) + .map(cargo_toml::Manifest::from_path) + .map(|man| man.map_err(|e| anyhow!("Failed to read manifest: {e}"))) + .collect::>>()? + .into_iter() + .filter(|man| man.dependencies.contains_key("solana-program")) + .for_each(|man| { + eprintln!( + "WARNING: Adding `solana-program` as a separate dependency might cause conflicts.\n\ + To solve, remove the `solana-program` dependency and use the exported crate from \ + `anchor-lang`.\n\ + `use solana_program` becomes `use anchor_lang::solana_program`.\n\ + Program name: `{}`\n", + man.package().name() + ) + }); + + Ok(()) +} + /// Check whether the `idl-build` feature is being used correctly. /// /// **Note:** The check expects the current directory to be a program directory. diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 9d4f8eeeeb..8e18ffdd3f 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -9,7 +9,7 @@ use anchor_lang::{AccountDeserialize, AnchorDeserialize, AnchorSerialize, Discri use anchor_lang_idl::convert::convert_idl; use anchor_lang_idl::types::{Idl, IdlArrayLen, IdlDefinedFields, IdlType, IdlTypeDefTy}; use anyhow::{anyhow, Context, Result}; -use checks::{check_anchor_version, check_idl_build_feature, check_overflow}; +use checks::{check_anchor_version, check_deps, check_idl_build_feature, check_overflow}; use clap::Parser; use dirs::home_dir; use flate2::read::GzDecoder; @@ -1328,6 +1328,7 @@ pub fn build( // Check whether there is a mismatch between CLI and crate/package versions check_anchor_version(&cfg).ok(); + check_deps(&cfg).ok(); let idl_out = match idl { Some(idl) => Some(PathBuf::from(idl)),