diff --git a/src/cli/diff.rs b/src/cli/diff.rs new file mode 100644 index 000000000..46b73639a --- /dev/null +++ b/src/cli/diff.rs @@ -0,0 +1,46 @@ +use std::path::PathBuf; + +use clap::Parser; +use miette::IntoDiagnostic; +use pixi_config::{self, ConfigCli}; +use rattler_lock::LockFile; + +use crate::{ + cli::update::{LockFileDiff, LockFileJsonDiff}, + Project, +}; + +use super::cli_config::ProjectConfig; + +#[derive(Parser, Debug, Default)] +pub struct Args { + #[clap(flatten)] + pub config: ConfigCli, + + #[clap(flatten)] + pub project_config: ProjectConfig, + + #[arg(long)] + pub old_lockfile: PathBuf, +} + +pub async fn execute(args: Args) -> miette::Result<()> { + let project = Project::load_or_else_discover(args.project_config.manifest_path.as_deref())? + .with_cli_config(args.config); + let current_lockfile = LockFile::from_path(&project.lock_file_path()).into_diagnostic()?; + + let input: Box = if args.old_lockfile.as_os_str() == "-" { + Box::new(std::io::stdin()) + } else { + Box::new(std::fs::File::open(&args.old_lockfile).into_diagnostic()?) + }; + + let prior_lockfile = LockFile::from_reader(input).into_diagnostic()?; + + let diff = LockFileDiff::from_lock_files(&prior_lockfile, ¤t_lockfile); + let json_diff = LockFileJsonDiff::new(&project, diff); + let json = serde_json::to_string_pretty(&json_diff).expect("failed to convert to json"); + println!("{}", json); + + Ok(()) +} diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 5e6764591..df1474094 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -18,6 +18,7 @@ pub mod clean; pub mod cli_config; pub mod completion; pub mod config; +pub mod diff; mod exec; pub mod global; pub mod has_specs; @@ -104,6 +105,7 @@ pub enum Command { #[clap(visible_alias = "s")] Shell(shell::Args), ShellHook(shell_hook::Args), + Diff(diff::Args), // Project modification commands Project(project::Args), @@ -281,6 +283,7 @@ pub async fn execute_command(command: Command) -> miette::Result<()> { Command::Tree(cmd) => tree::execute(cmd).await, Command::Update(cmd) => update::execute(cmd).await, Command::Exec(args) => exec::execute(args).await, + Command::Diff(args) => diff::execute(args).await, } } diff --git a/src/cli/update.rs b/src/cli/update.rs index 88636fa8e..76484dc73 100644 --- a/src/cli/update.rs +++ b/src/cli/update.rs @@ -638,7 +638,7 @@ pub struct LockFileJsonDiff { } impl LockFileJsonDiff { - fn new(project: &Project, value: LockFileDiff) -> Self { + pub fn new(project: &Project, value: LockFileDiff) -> Self { let mut environment = IndexMap::new(); for (environment_name, environment_diff) in value.environment {