Skip to main content

license_trace/
cli.rs

1use clap::{Args, Parser, Subcommand, ValueEnum};
2use std::path::PathBuf;
3
4#[derive(Parser, Debug)]
5#[command(
6    name = "license-trace",
7    author,
8    version,
9    about = "Recursive license tracer, obligations lower-bound evaluator, and OSS compliance analyzer",
10    long_about = "Traces recursive dependencies and analyzes license compatibility (e.g. MIT readiness), obligations, and path origins."
11)]
12pub struct Cli {
13    #[command(subcommand)]
14    pub command: Commands,
15}
16
17#[derive(Subcommand, Debug)]
18pub enum Commands {
19    /// Audit a local project for license compliance and aggregate obligations against an outbound license (e.g., MIT)
20    #[command(alias = "a", alias = "check")]
21    Audit(AuditArgs),
22
23    /// Trace a remote package and its recursive transitive dependencies online via registry API
24    #[command(alias = "t")]
25    Trace(TraceArgs),
26
27    /// Explain why a dependency is included in the project by showing all arrival paths
28    #[command(alias = "w")]
29    Why(WhyArgs),
30
31    /// Export aggregated third-party notices and licenses into THIRD_PARTY_LICENSES.md
32    #[command(alias = "e", alias = "notice")]
33    Export(ExportArgs),
34}
35
36#[derive(ValueEnum, Clone, Copy, Debug, PartialEq, Eq)]
37pub enum OutputFormat {
38    Audit,
39    Table,
40    Tree,
41    Json,
42    Markdown,
43    CycloneDx,
44    Sarif,
45}
46
47#[derive(Args, Debug)]
48pub struct AuditArgs {
49    /// Path to project root directory
50    #[arg(short, long, default_value = ".")]
51    pub path: PathBuf,
52
53    /// Outbound license you intend to release under
54    #[arg(short, long, default_value = "MIT")]
55    pub outbound: String,
56
57    /// Only analyze production dependencies (exclude devDependencies)
58    #[arg(short = 'P', long)]
59    pub prod_only: bool,
60
61    /// Output format
62    #[arg(short, long, value_enum, default_value = "audit")]
63    pub format: OutputFormat,
64
65    /// Exit with code 1 if incompatible licenses are detected
66    #[arg(short = 'i', long)]
67    pub fail_on_incompatible: bool,
68
69    /// Exit with code 1 if unknown or un-evaluated licenses are detected
70    #[arg(short = 'u', long)]
71    pub fail_on_unknown: bool,
72}
73
74#[derive(Args, Debug)]
75pub struct TraceArgs {
76    /// Target to trace: local directory (e.g. '.', './my-app'), remote package ('express', 'lodash@4.17.21'), or git repository URL
77    #[arg(default_value = ".")]
78    pub target: String,
79
80    /// Maximum dependency resolution depth
81    #[arg(short = 'd', short_alias = 'm', long, default_value = "10")]
82    pub max_depth: usize,
83
84    /// Outbound target license to evaluate against
85    #[arg(short, long, default_value = "MIT")]
86    pub outbound: String,
87
88    /// Only analyze production dependencies
89    #[arg(short = 'P', long)]
90    pub prod_only: bool,
91
92    /// Output format
93    #[arg(short, long, value_enum, default_value = "audit")]
94    pub format: OutputFormat,
95
96    /// Exit with code 1 if incompatible licenses are detected
97    #[arg(short = 'i', long)]
98    pub fail_on_incompatible: bool,
99
100    /// Exit with code 2 if unknown licenses are detected
101    #[arg(short = 'u', long)]
102    pub fail_on_unknown: bool,
103}
104
105#[derive(Args, Debug)]
106pub struct WhyArgs {
107    /// Package name to trace the path for
108    pub package: String,
109
110    /// Path to project root directory
111    #[arg(short, long, default_value = ".")]
112    pub path: PathBuf,
113}
114
115#[derive(Args, Debug)]
116pub struct ExportArgs {
117    /// Target project directory to export licenses for
118    #[arg(default_value = ".")]
119    pub path: PathBuf,
120
121    /// Output file path (e.g. THIRD_PARTY_LICENSES.md). If omitted, prints to stdout.
122    #[arg(short, long)]
123    pub output: Option<PathBuf>,
124
125    /// Only include production dependencies
126    #[arg(short = 'P', long)]
127    pub prod_only: bool,
128}