Skip to content

Commit

Permalink
Merge pull request #54 from kpcyrd/json
Browse files Browse the repository at this point in the history
Add --json option for machine-readable output
  • Loading branch information
kpcyrd authored Dec 30, 2024
2 parents 5dddc8b + f87a89a commit ed8a2b1
Show file tree
Hide file tree
Showing 8 changed files with 189 additions and 130 deletions.
3 changes: 3 additions & 0 deletions src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ pub struct Args {
#[clap(long = "all", short = 'a')]
/// Don't truncate dependencies that have already been displayed
pub all: bool,
#[clap(long = "json")]
/// Print package information as machine-readable output
pub json: bool,
#[clap(long = "duplicate", short = 'd')]
/// Show only dependencies which come in multiple versions (implies -i)
pub duplicates: bool,
Expand Down
2 changes: 1 addition & 1 deletion src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
pub use anyhow::{bail, Context, Error, Result};
pub use anyhow::{anyhow, bail, Context as _, Error, Result};
pub use log::{debug, info};
80 changes: 80 additions & 0 deletions src/format/human.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
use crate::errors::*;
use crate::format::{Chunk, Pattern, Pkg};
use colored::Colorize;
use std::fmt::Write;

pub fn display(pattern: &Pattern, package: &Pkg) -> Result<String, Error> {
let mut fmt = String::new();

for chunk in &pattern.0 {
match *chunk {
Chunk::Raw(ref s) => fmt.write_str(s)?,
Chunk::Package => {
let pkg = format!("{} v{}", package.name, package.version);
if let Some(deb) = &package.debinfo {
if deb.in_unstable {
if deb.compatible {
write!(fmt, "{} ({} in debian)", pkg.green(), deb.version.yellow())?;
} else if deb.outdated {
write!(
fmt,
"{} (outdated, {} in debian)",
pkg.yellow(),
deb.version.red()
)?;
} else {
write!(fmt, "{} (in debian)", pkg.green())?;
}
} else if deb.in_new {
if deb.compatible {
write!(
fmt,
"{} ({} in debian NEW queue)",
pkg.blue(),
deb.version.yellow()
)?;
} else if deb.outdated {
write!(
fmt,
"{}, (outdated, {} in debian NEW queue)",
pkg.blue(),
deb.version.red()
)?;
} else {
write!(fmt, "{} (in debian NEW queue)", pkg.blue())?;
}
} else if deb.outdated {
write!(fmt, "{} (outdated, {})", pkg.red(), deb.version.red())?;
} else {
write!(fmt, "{pkg}")?;
}
} else {
write!(fmt, "{pkg}")?;
}

match &package.source {
Some(source) if !source.is_crates_io() => write!(fmt, " ({source})")?,
// https://github.com/rust-lang/cargo/issues/7483
None => write!(
fmt,
" ({})",
package.manifest_path.parent().unwrap().display()
)?,
_ => {}
}
}
Chunk::License => {
if let Some(license) = &package.license {
write!(fmt, "{license}")?
}
}
Chunk::Repository => {
if let Some(repository) = &package.repository {
write!(fmt, "{repository}")?
}
}
}
}

Ok(fmt)
}
49 changes: 49 additions & 0 deletions src/format/json.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
use crate::errors::*;
use crate::format::Pkg;

#[derive(Debug, serde::Serialize)]
pub struct Json {
name: String,
cargo_lock_version: String,
repository: Option<String>,
license: Option<String>,
debian: Option<DebianJson>,
depth: usize,
}

#[derive(Debug, serde::Serialize)]
pub struct DebianJson {
version: String,
compatible: bool,
exact_match: bool,
in_new: bool,
in_unstable: bool,
outdated: bool,
}

impl Json {
pub fn new(pkg: &Pkg, depth: usize) -> Self {
let debian = pkg.debinfo.as_ref().map(|deb| DebianJson {
version: deb.version.clone(),
compatible: deb.compatible,
exact_match: deb.exact_match,
in_new: deb.in_new,
in_unstable: deb.in_unstable,
outdated: deb.outdated,
});

Json {
name: pkg.name.clone(),
cargo_lock_version: pkg.version.to_string(),
repository: pkg.repository.clone(),
license: pkg.license.clone(),
debian,
depth,
}
}
}

pub fn display(package: &Pkg, depth: usize) -> Result<String, Error> {
let json = serde_json::to_string(&Json::new(package, depth))?;
Ok(json)
}
99 changes: 3 additions & 96 deletions src/format/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
use crate::debian::Pkg;
use crate::errors::*;
use crate::format::parse::{Parser, RawChunk};
use anyhow::{anyhow, Error};
use colored::Colorize;
use std::fmt;

pub mod human;
pub mod json;
mod parse;

enum Chunk {
Expand Down Expand Up @@ -35,97 +35,4 @@ impl Pattern {

Ok(Pattern(chunks))
}

pub fn display<'a>(&'a self, package: &'a Pkg) -> Display<'a> {
Display {
pattern: self,
package,
}
}
}

pub struct Display<'a> {
pattern: &'a Pattern,
package: &'a Pkg,
}

impl fmt::Display for Display<'_> {
fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
for chunk in &self.pattern.0 {
match *chunk {
Chunk::Raw(ref s) => fmt.write_str(s)?,
Chunk::Package => {
let pkg = format!("{} v{}", self.package.name, self.package.version);
if let Some(deb) = &self.package.debinfo {
if deb.in_unstable {
if deb.compatible {
write!(
fmt,
"{} ({} in debian)",
pkg.green(),
deb.version.yellow()
)?;
} else if deb.outdated {
write!(
fmt,
"{} (outdated, {} in debian)",
pkg.yellow(),
deb.version.red()
)?;
} else {
write!(fmt, "{} (in debian)", pkg.green())?;
}
} else if deb.in_new {
if deb.compatible {
write!(
fmt,
"{} ({} in debian NEW queue)",
pkg.blue(),
deb.version.yellow()
)?;
} else if deb.outdated {
write!(
fmt,
"{}, (outdated, {} in debian NEW queue)",
pkg.blue(),
deb.version.red()
)?;
} else {
write!(fmt, "{} (in debian NEW queue)", pkg.blue())?;
}
} else if deb.outdated {
write!(fmt, "{} (outdated, {})", pkg.red(), deb.version.red())?;
} else {
write!(fmt, "{pkg}")?;
}
} else {
write!(fmt, "{pkg}")?;
}

match &self.package.source {
Some(source) if !source.is_crates_io() => write!(fmt, " ({source})")?,
// https://github.com/rust-lang/cargo/issues/7483
None => write!(
fmt,
" ({})",
self.package.manifest_path.parent().unwrap().display()
)?,
_ => {}
}
}
Chunk::License => {
if let Some(ref license) = self.package.license {
write!(fmt, "{license}")?
}
}
Chunk::Repository => {
if let Some(ref repository) = self.package.repository {
write!(fmt, "{repository}")?
}
}
}
}

Ok(())
}
}
2 changes: 1 addition & 1 deletion src/graph.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::args::Args;
use crate::debian::Pkg;
use anyhow::{anyhow, Error};
use crate::errors::*;
use cargo_metadata::{DependencyKind, Metadata, PackageId};
use petgraph::graph::NodeIndex;
use petgraph::stable_graph::StableGraph;
Expand Down
2 changes: 1 addition & 1 deletion src/metadata.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::args::Args;
use anyhow::{anyhow, Context, Error};
use crate::errors::*;
use cargo_metadata::Metadata;
use std::env;
use std::ffi::OsString;
Expand Down
Loading

0 comments on commit ed8a2b1

Please sign in to comment.