如何解决 CLI 工具的 Rust Cargo 工作区中的依赖冲突?

问题描述 投票:0回答:1

我正在开发一个 CLI 工具,其中包含多个子命令,适用于不同的用例。这是我的项目结构:

project/
├── Cargo.toml 
└── crates/
    ├── project-foo/
    │   └── src/
    │       └── lib.rs (subcommand for 'foo')
    ├── project-bar/
    │   └── src/
    │       └── lib.rs (subcommand for 'bar')
    └── project-core/
        └── src/
            └── main.rs (main entry point for the CLI app)

在我的

Cargo.toml
中,我设置了如下工作区配置:

[workspace]
members = ["crates/*"]

resolver = "2"

例如,考虑

project-foo
箱,它公开一个名为
FileAction
的子命令。该子命令包含两个子命令。

#[derive(Debug, Subcommand)]
pub enum FileAction {
    Copy(CopyCommand),
    Paste(PasteCommand),
}

#[derive(Debug, clap::Args)]
pub struct CopyCommand {
    // Include any relevant options here.
}

impl CopyCommand {
    pub async fn handle(&self) -> Result<()> {
        // handle the code 
    }
}

project-core
箱中,我们使用
Cli
结构来管理这些子命令。

#[derive(Parser)]
#[command(subcommand_required = true)]
pub struct Cli {
    #[command(subcommand)]
    pub command: Commands,
}

#[derive(Subcommand)]
pub enum Commands {
    File {
        #[clap(subcommand)]
        action: FileAction,
    },
}


fn main() {
    let matches = Cli::command().get_matches();
    let cli = Cli::from_arg_matches(&matches).unwrap();

    match cli.command {
        File { action } => match action {
            FileAction::Copy(copy_args) => {
                if let Err(err) = copy_args.handle().await {
                    eprintln!("{}", err);
                }
            },
            FileAction::Paste(paste_args) => {
                if let Err(err) = paste_args.handle().await {
                    eprintln!("{}", err);
                }
            },
        },
    }
}

理想情况下,我的

project-core/Cargo.toml
看起来像这样:

[package]
name = "project"
version = "0.1.0"
edition = "2021"

[dependencies]
project-foo = { path = "../project-foo" }
project-bar = { path = "../project-bar" }

由于两个子命令中使用的 crate 之间存在持续的依赖性问题,因此此方法不起作用。这个问题似乎不太可能在不久的将来得到解决。

注意:由于功能统一

,无法使用Cargo功能来解决问题

我最初的想法是将一个箱子移到

crates
文件夹之外,这样当我运行
cargo build
时它就不会自动编译。然后,我想找到一种方法从
project-core
构建它,并将其作为
project-core/main.rs
中定义的 CLI 中的子进程执行。 这种方法是否可行,是否是一个好的解决方案?或者有没有更直接的方法来解决这个问题

rust rust-cargo cargo-features
1个回答
0
投票

我设法通过修补导致问题的板条箱解决了这个问题。

在两个依赖项(例如

project-foo
project-bar
)依赖于第三个 crate 的不同版本的情况下,会出现依赖项冲突。

每个 crate 都指定一个特定的版本,从而导致这种冲突。幸运的是,我在第三个箱子中发现了一个满足两个箱子版本要求的提交。我在我的

Cargo.toml
中添加了一个补丁来解决这个问题:

[patch.crates-io.third_crate]
git = "https://github.com/user/third_crate"
rev = "<commit>" # This commit meets both crates' version requirements

但是,如果不存在合适的提交,我会通过分叉箱子并进行修改来解决问题。

© www.soinside.com 2019 - 2024. All rights reserved.