我正在开发一个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
crate,它公开了一个名为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
crate中,我们使用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之间存在持久的依赖性问题,这种方法不起作用。
注意:由于功能统一,货物功能不能用于解决问题
我最初的想法是将一个crate移出crates
文件夹,这样当我运行cargo build
时它就不会自动编译。然后,我想找到一种方法从project-core
构建它,并在project-core/main.rs
中定义的CLI中作为子进程执行它。这种方法是否可行,它是否是一个好的解决方案?或者有没有更直接的方法来解决这个问题
1条答案
按热度按时间4uqofj5v1#
我设法通过修补导致问题的板条箱来解决这个问题。
在两个依赖项(如
project-foo
和project-bar
)依赖于第三个crate的不同版本的场景中,会出现依赖项冲突。每个crate都指定了一个特定的版本,导致了这个冲突。幸运的是,我在第三个crate中找到了一个符合两个crate版本要求的提交。我给我的
Cargo.toml
添加了一个补丁来解决这个问题:字符串
然而,如果没有合适的提交存在,我会采取分叉板条箱和修改来解决这个问题。