1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use std::path::PathBuf;

use clap::{crate_version, Parser, ValueEnum};

#[derive(Parser)]
#[clap(name = "monorepo", version = crate_version!(), author = "Eric Crosson <eric.s.crosson@utexas.edu>")]
pub struct Opts {
    #[clap(subcommand)]
    pub subcommand: ClapSubCommand,
}

#[derive(Parser)]
pub enum ClapSubCommand {
    #[clap(about = "Pin internal dependencies to locally-declared package versions")]
    Pin(Pin),
    #[clap(about = "Configure TypeScript Project References")]
    Link(Link),
    #[clap(about = "Create GNU Makefile containing package dependency information")]
    MakeDepend(MakeDepend),
    #[clap(about = "Query properties of the current monorepo state")]
    Query(Query),
    #[clap(about = "Lint internal packages for consistent use of external dependency versions")]
    Lint(Lint),
}

#[derive(Parser)]
pub struct Link {
    /// Path to monorepo root
    #[clap(short, long, default_value = ".")]
    pub root: PathBuf,
    /// Exit with code 1 when project references are not properly configured
    #[clap(long = "check")]
    pub check_only: bool,
}

#[derive(Parser)]
pub struct Pin {
    /// Path to monorepo root
    #[clap(short, long, default_value = ".")]
    pub root: PathBuf,
    /// Exit with code 1 when internal dependencies are not properly pinned
    #[clap(long = "check")]
    pub check_only: bool,
}

#[derive(Parser)]
pub struct MakeDepend {
    /// Path to monorepo root
    #[clap(short, long, default_value = ".")]
    pub root: PathBuf,
    /// Directory to package for which to calculate dependencies
    #[clap(long)]
    pub package_directory: PathBuf,
    /// Output file, relative to the package directory
    #[clap(long)]
    pub output_file: PathBuf,
    /// Include GNU make target for creating package archive with npm pack
    #[clap(long)]
    pub create_pack_target: bool,
}

#[derive(Parser)]
pub struct Query {
    #[clap(subcommand)]
    pub subcommand: ClapQuerySubCommand,
}

#[derive(Parser)]
pub enum ClapQuerySubCommand {
    #[clap(
        about = "Print a JSON object mapping a package name to a list of relative paths to its internal dependencies"
    )]
    InternalDependencies(InternalDependencies),
}

#[derive(ValueEnum, Clone)]
pub enum InternalDependenciesFormat {
    Name,
    Path,
}

#[derive(Parser)]
pub struct InternalDependencies {
    /// Path to monorepo root
    #[clap(short, long, default_value = ".")]
    pub root: PathBuf,
    /// Format in which to describe internal dependencies (defaults to name)
    #[clap(long = "format", value_enum, default_value = "name")]
    pub format: InternalDependenciesFormat,
}

#[derive(Parser)]
pub struct Lint {
    #[clap(subcommand)]
    pub subcommand: ClapLintSubCommand,
}

#[derive(Parser)]
pub enum ClapLintSubCommand {
    #[clap(about = "Lint the used versions of an external dependency for consistency")]
    DependencyVersion(DependencyVersion),
}

#[derive(Parser)]
pub struct DependencyVersion {
    /// Path to monorepo root
    #[clap(short, long, default_value = ".")]
    pub root: PathBuf,
    /// External dependency to lint for consistency of version used
    #[clap(short, long = "dependency")]
    pub dependencies: Vec<String>,
}