diff --git a/src/apps/mod.rs b/src/apps/mod.rs index 7dee6c68..7b3c22da 100644 --- a/src/apps/mod.rs +++ b/src/apps/mod.rs @@ -17,6 +17,7 @@ mod goreleaser; mod govulnchec; mod ireturn; mod mdbook; +mod node_prune; mod nodejs; mod npm; mod npx; @@ -103,6 +104,7 @@ pub fn all() -> Apps { Box::new(ireturn::Ireturn {}), Box::new(mdbook::MdBook {}), Box::new(nodejs::NodeJS {}), + Box::new(node_prune::NodePrune {}), Box::new(npm::Npm {}), Box::new(npx::Npx {}), Box::new(scc::Scc {}), diff --git a/src/apps/node_prune.rs b/src/apps/node_prune.rs new file mode 100644 index 00000000..57b948a0 --- /dev/null +++ b/src/apps/node_prune.rs @@ -0,0 +1,91 @@ +use super::{AnalyzeResult, App}; +use crate::config::{AppName, Version}; +use crate::hosting::github_releases; +use crate::install::{self, Method}; +use crate::platform::{Cpu, Os, Platform}; +use crate::prelude::*; +use crate::subshell::Executable; +use crate::Log; +use const_format::formatcp; + +pub struct NodePrune {} + +const ORG: &str = "tj"; +const REPO: &str = "node-prune"; + +impl App for NodePrune { + fn name(&self) -> AppName { + AppName::from("node-prune") + } + + fn homepage(&self) -> &'static str { + formatcp!("https://github.com/{ORG}/{REPO}") + } + + fn latest_installable_version(&self, log: Log) -> Result { + github_releases::latest(ORG, REPO, log) + } + + fn install_methods(&self) -> Vec { + vec![Method::DownloadExecutable(self), Method::CompileGoSource(self)] + } + + fn installable_versions(&self, amount: usize, log: Log) -> Result> { + github_releases::versions(ORG, REPO, amount, log) + } + + fn analyze_executable(&self, executable: &Executable, log: Log) -> Result { + let output = executable.run_output("-h", log)?; + if !identify(&output) { + return Ok(AnalyzeResult::NotIdentified { output }); + } + Ok(AnalyzeResult::IdentifiedButUnknownVersion) + } +} + +impl install::DownloadExecutable for NodePrune { + fn download_url(&self, version: &Version, platform: Platform) -> String { + let os = match platform.os { + Os::Linux => "linux", + Os::MacOS => "darwin", + Os::Windows => "windows", + }; + let cpu = match platform.cpu { + Cpu::Arm64 => "arm64", + Cpu::Intel64 => "amd64", + }; + format!("https://github.com/{ORG}/{REPO}/releases/download/v{version}/node-prune_{version}_{os}_{cpu}.tar.gz") + } +} + +impl install::CompileGoSource for NodePrune { + fn import_path(&self, version: &Version) -> String { + format!("github.com/tj/node-prune@{version}") + } +} + +fn identify(output: &str) -> bool { + output.contains("Glob of files that should not be pruned") +} + +#[cfg(test)] +mod tests { + + mod artifact_url { + use crate::config::Version; + use crate::install::DownloadExecutable; + use crate::platform::{Cpu, Os, Platform}; + + #[test] + fn windows_intel64() { + let node_prune = super::super::NodePrune {}; + let platform = Platform { + os: Os::Linux, + cpu: Cpu::Intel64, + }; + let have = node_prune.download_url(&Version::from("1.0.1"), platform); + let want = "https://github.com/tj/node-prune/releases/download/v1.0.1/node-prune_1.0.1_linux_amd64.tar.gz"; + assert_eq!(have, want); + } + } +}