From 6ddfcedc274cf85923ab06df20b10d2cd4719f3c Mon Sep 17 00:00:00 2001 From: Wolf Vollprecht Date: Mon, 10 Jul 2023 16:15:47 +0200 Subject: [PATCH] add `info` sub-command (#158) --- Cargo.toml | 1 + src/cli/info.rs | 109 ++++++++++++++++++++++++++++++++++++++++++++++++ src/cli/mod.rs | 3 ++ 3 files changed, 113 insertions(+) create mode 100644 src/cli/info.rs diff --git a/Cargo.toml b/Cargo.toml index b85d58178..addd6c9ec 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -50,6 +50,7 @@ rattler_virtual_packages = { default-features = false, git = "https://github.com #rattler_networking = { default-features = false, path="../rattler/crates/rattler_networking" } reqwest = { version = "0.11.16", default-features = false } serde = "1.0.163" +serde_json = "1.0.96" serde_spanned = "0.6.2" serde_with = { version = "3.0.0", features = ["indexmap"] } shlex = "1.1.0" diff --git a/src/cli/info.rs b/src/cli/info.rs new file mode 100644 index 000000000..0adec5d4e --- /dev/null +++ b/src/cli/info.rs @@ -0,0 +1,109 @@ +use std::{fmt::Display, path::PathBuf}; + +use clap::Parser; +use rattler_conda_types::{GenericVirtualPackage, Platform}; +use rattler_virtual_packages::VirtualPackage; +use serde::Serialize; +use serde_with::serde_as; +use serde_with::DisplayFromStr; + +use crate::Project; + +#[derive(Parser, Debug)] +pub struct Args { + /// Wether to show the output as JSON or not + #[arg(long)] + json: bool, + + /// The path to 'pixi.toml' + #[arg(long)] + pub manifest_path: Option, +} + +#[derive(Serialize)] +pub struct ProjectInfo { + tasks: Vec, + manifest_path: PathBuf, +} + +#[serde_as] +#[derive(Serialize)] +pub struct Info { + platform: String, + #[serde_as(as = "Vec")] + virtual_packages: Vec, + version: String, + cache_dir: Option, + project_info: Option, +} + +impl Display for Info { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let cache_dir = match &self.cache_dir { + Some(path) => path.to_string_lossy().to_string(), + None => "None".to_string(), + }; + + writeln!(f, "pixi {}\n", self.version)?; + writeln!(f, "{:20}: {}", "Platform", self.platform)?; + + for (i, p) in self.virtual_packages.iter().enumerate() { + if i == 0 { + writeln!(f, "{:20}: {}", "Virtual packages", p)?; + } else { + writeln!(f, "{:20}: {}", "", p)?; + } + } + + writeln!(f, "{:20}: {}", "Cache dir", cache_dir)?; + + if let Some(pi) = self.project_info.as_ref() { + writeln!(f, "\nProject\n------------\n")?; + + writeln!( + f, + "{:20}: {}", + "Manifest file", + pi.manifest_path.to_string_lossy() + )?; + + writeln!(f, "Tasks:")?; + for c in &pi.tasks { + writeln!(f, " - {}", c)?; + } + } + + Ok(()) + } +} + +pub async fn execute(args: Args) -> anyhow::Result<()> { + let project = Project::load_or_else_discover(args.manifest_path.as_deref()).ok(); + + let project_info = project.map(|p| ProjectInfo { + manifest_path: p.root().to_path_buf().join("pixi.toml"), + tasks: p.manifest.tasks.keys().cloned().collect(), + }); + + let virtual_packages = VirtualPackage::current()? + .iter() + .cloned() + .map(GenericVirtualPackage::from) + .collect::>(); + + let info = Info { + platform: Platform::current().to_string(), + virtual_packages, + version: env!("CARGO_PKG_VERSION").to_string(), + cache_dir: rattler::default_cache_dir().ok(), + project_info, + }; + + if args.json { + println!("{}", serde_json::to_string_pretty(&info)?); + Ok(()) + } else { + println!("{}", info); + Ok(()) + } +} diff --git a/src/cli/mod.rs b/src/cli/mod.rs index 5a0643edb..b12f48404 100644 --- a/src/cli/mod.rs +++ b/src/cli/mod.rs @@ -10,6 +10,7 @@ use tracing_subscriber::{filter::LevelFilter, util::SubscriberInitExt, EnvFilter pub mod add; pub mod auth; pub mod global; +pub mod info; pub mod init; pub mod install; pub mod run; @@ -53,6 +54,7 @@ pub enum Command { #[clap(alias = "i")] Install(install::Args), Task(task::Args), + Info(info::Args), } fn completion(args: CompletionCommand) -> Result<(), Error> { @@ -108,5 +110,6 @@ pub async fn execute_command(command: Command) -> Result<(), Error> { Command::Install(cmd) => install::execute(cmd).await, Command::Shell(cmd) => shell::execute(cmd).await, Command::Task(cmd) => task::execute(cmd), + Command::Info(cmd) => info::execute(cmd).await, } }