Skip to content

Commit

Permalink
feat: support json output for outdated command
Browse files Browse the repository at this point in the history
Supports json output for the outdated command. This is useful for
automated tools that need to parse the output of the outdated command.
The json output can be specified using the `--output json` flag.
  • Loading branch information
irbull committed Dec 8, 2024
1 parent 9fe52b1 commit de0c21f
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 12 deletions.
52 changes: 45 additions & 7 deletions cli/args/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,10 +477,21 @@ pub enum DenoSubcommand {
Help(HelpFlags),
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum OutdatedOutputFmt {
Table,
Json,
}

#[derive(Clone, Debug, PartialEq, Eq)]
pub enum OutdatedKind {
Update { latest: bool },
PrintOutdated { compatible: bool },
Update {
latest: bool,
},
PrintOutdated {
compatible: bool,
output_fmt: OutdatedOutputFmt,
},
}

#[derive(Clone, Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -2727,6 +2738,16 @@ Specific version requirements to update to can be specified:
.action(ArgAction::SetTrue)
.help("include all workspace members"),
)
.arg(
Arg::new("output")
.long("output")
.short('o')
.value_parser([
"json", "table"
])
.default_value("table")
.help("specify the output format"),
)
})
}

Expand Down Expand Up @@ -4495,7 +4516,16 @@ fn outdated_parse(
OutdatedKind::Update { latest }
} else {
let compatible = matches.get_flag("compatible");
OutdatedKind::PrintOutdated { compatible }
let output = matches.get_one::<String>("output").unwrap();
let output_fmt = match output.as_str() {
"json" => OutdatedOutputFmt::Json,
"table" => OutdatedOutputFmt::Table,
_ => unreachable!(),
};
OutdatedKind::PrintOutdated {
compatible,
output_fmt,
}
};
flags.subcommand = DenoSubcommand::Outdated(OutdatedFlags {
filters,
Expand Down Expand Up @@ -11641,23 +11671,31 @@ Usage: deno repl [OPTIONS] [-- [ARGS]...]\n"
svec![],
OutdatedFlags {
filters: vec![],
kind: OutdatedKind::PrintOutdated { compatible: false },
kind: OutdatedKind::PrintOutdated { compatible: false, output_fmt: OutdatedOutputFmt::Table },
recursive: false,
},
),
(
svec!["--output", "json"],
OutdatedFlags {
filters: vec![],
kind: OutdatedKind::PrintOutdated { compatible: false, output_fmt: OutdatedOutputFmt::Json },
recursive: false,
},
),
(
svec!["--recursive"],
OutdatedFlags {
filters: vec![],
kind: OutdatedKind::PrintOutdated { compatible: false },
kind: OutdatedKind::PrintOutdated { compatible: false, output_fmt: OutdatedOutputFmt::Table },
recursive: true,
},
),
(
svec!["--recursive", "--compatible"],
OutdatedFlags {
filters: vec![],
kind: OutdatedKind::PrintOutdated { compatible: true },
kind: OutdatedKind::PrintOutdated { compatible: true, output_fmt: OutdatedOutputFmt::Table },
recursive: true,
},
),
Expand Down Expand Up @@ -11697,7 +11735,7 @@ Usage: deno repl [OPTIONS] [-- [ARGS]...]\n"
svec!["--latest"],
OutdatedFlags {
filters: svec![],
kind: OutdatedKind::PrintOutdated { compatible: false },
kind: OutdatedKind::PrintOutdated { compatible: false, output_fmt: OutdatedOutputFmt::Table },
recursive: false,
},
),
Expand Down
3 changes: 2 additions & 1 deletion cli/tools/registry/pm/deps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ use deno_semver::VersionReq;
use import_map::ImportMap;
use import_map::ImportMapWithDiagnostics;
use import_map::SpecifierMapEntry;
use serde::Serialize;
use tokio::sync::Semaphore;

use crate::args::CliLockfile;
Expand Down Expand Up @@ -112,7 +113,7 @@ impl std::fmt::Debug for DepLocation {
}
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize)]
pub enum DepKind {
Jsr,
Npm,
Expand Down
22 changes: 18 additions & 4 deletions cli/tools/registry/pm/outdated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@ use std::collections::HashSet;
use std::sync::Arc;

use deno_core::error::AnyError;
use deno_core::serde_json;
use deno_semver::package::PackageNv;
use deno_semver::package::PackageReq;
use deno_semver::VersionReq;
use deno_terminal::colors;
use serde::Serialize;

use crate::args::CacheSetting;
use crate::args::CliOptions;
use crate::args::Flags;
use crate::args::OutdatedFlags;
use crate::args::OutdatedOutputFmt;
use crate::factory::CliFactory;
use crate::file_fetcher::FileFetcher;
use crate::jsr::JsrFetchResolver;
Expand All @@ -24,12 +27,16 @@ use super::deps::DepManager;
use super::deps::DepManagerArgs;
use super::deps::PackageLatestVersion;

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Serialize)]
struct OutdatedPackage {
#[serde(rename="specifier")]
kind: DepKind,
#[serde(rename="latest")]
latest: String,
#[serde(rename="update")]
semver_compatible: String,
current: String,
#[serde(rename="package")]
name: String,
}

Expand Down Expand Up @@ -103,6 +110,7 @@ fn print_outdated_table(packages: &[OutdatedPackage]) {
fn print_outdated(
deps: &mut DepManager,
compatible: bool,
output_fmt: OutdatedOutputFmt,
) -> Result<(), AnyError> {
let mut outdated = Vec::new();
let mut seen = std::collections::BTreeSet::new();
Expand Down Expand Up @@ -147,7 +155,13 @@ fn print_outdated(

if !outdated.is_empty() {
outdated.sort();
print_outdated_table(&outdated);
match output_fmt {
OutdatedOutputFmt::Table => print_outdated_table(&outdated),
OutdatedOutputFmt::Json => {
let json = serde_json::to_string_pretty(&outdated)?;
log::info!("{json}");
}
}
}

Ok(())
Expand Down Expand Up @@ -214,8 +228,8 @@ pub async fn outdated(
crate::args::OutdatedKind::Update { latest } => {
update(deps, latest, &filter_set, flags).await?;
}
crate::args::OutdatedKind::PrintOutdated { compatible } => {
print_outdated(&mut deps, compatible)?;
crate::args::OutdatedKind::PrintOutdated { compatible, output_fmt } => {
print_outdated(&mut deps, compatible, output_fmt)?;
}
}

Expand Down

0 comments on commit de0c21f

Please sign in to comment.