diff --git a/src/cli/diff.rs b/src/cli/diff.rs new file mode 100644 index 0000000000..32bce338e1 --- /dev/null +++ b/src/cli/diff.rs @@ -0,0 +1,47 @@ +use std::path::{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 lock = LockFile::from_path(Path::new("pixi.lock")).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 old = LockFile::from_reader(input).into_diagnostic()?; + + let diff = LockFileDiff::from_lock_files(&old, &lock); + let config = args.config; + let project = Project::load_or_else_discover(args.project_config.manifest_path.as_deref())? + .with_cli_config(config); + 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 5e67645915..df14740943 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 88636fa8e3..76484dc736 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 {