release_kit/cli/depend.rs
1//! Arguments for `rk depend`.
2
3use camino::Utf8PathBuf;
4use clap::{Args, Subcommand, ValueEnum};
5use serde::Serialize;
6
7/// Add another project as a dependency of a target, from how the source distributes itself.
8#[derive(Debug, Args)]
9pub struct DependArgs {
10 /// What to do with the dependency.
11 #[command(subcommand)]
12 pub action: DependAction,
13}
14
15/// The depend operations.
16#[derive(Debug, Subcommand)]
17pub enum DependAction {
18 /// Read the source and the target, offline, and report every way the dependency can land.
19 Assess(AssessArgs),
20 /// Serve the fragment or the native command for one way; seed a manager file only where the target has none.
21 Add(AddArgs),
22}
23
24/// Arguments for `rk depend assess`.
25#[derive(Debug, Args)]
26pub struct AssessArgs {
27 /// The dependency's checkout: a local directory, never a URL.
28 #[arg(long)]
29 pub source: Utf8PathBuf,
30
31 /// The project that takes the dependency.
32 #[arg(long, default_value = ".")]
33 pub target: Utf8PathBuf,
34
35 /// Emit one JSON object on stdout instead of the human report.
36 #[arg(long)]
37 pub json: bool,
38}
39
40/// Arguments for `rk depend add`.
41#[derive(Debug, Args)]
42pub struct AddArgs {
43 /// The dependency's checkout: a local directory, never a URL.
44 #[arg(long)]
45 pub source: Utf8PathBuf,
46
47 /// The project that takes the dependency.
48 #[arg(long, default_value = ".")]
49 pub target: Utf8PathBuf,
50
51 /// dev: a tool on PATH in the development environment; prod: a library the code imports.
52 #[arg(long, value_enum)]
53 pub kind: Kind,
54
55 /// The target's tool manager; required when the target carries several, or none.
56 #[arg(long, value_enum)]
57 pub manager: Option<Manager>,
58
59 /// How the source is fetched; the first viable channel for the manager by default.
60 #[arg(long, value_enum)]
61 pub channel: Option<Channel>,
62
63 /// The version to pin: 1.2.3, v1.2.3, or the release URL; the source tree's declared version by default.
64 #[arg(long)]
65 pub pin: Option<String>,
66
67 /// Write the seed file; without it the fragment or command is printed and nothing is written.
68 #[arg(long)]
69 pub apply: bool,
70
71 /// Emit one JSON object on stdout instead of the human report.
72 #[arg(long)]
73 pub json: bool,
74}
75
76/// What kind of dependency the target takes.
77#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, ValueEnum)]
78#[serde(rename_all = "kebab-case")]
79#[value(rename_all = "kebab-case")]
80pub enum Kind {
81 /// A tool on PATH in the development environment.
82 Dev,
83 /// A library the code imports, through the technology's own manifest.
84 Prod,
85}
86
87impl Kind {
88 /// The wire form.
89 #[must_use]
90 pub const fn as_str(self) -> &'static str {
91 match self {
92 Self::Dev => "dev",
93 Self::Prod => "prod",
94 }
95 }
96}
97
98/// The target's tool manager.
99#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, ValueEnum)]
100#[serde(rename_all = "kebab-case")]
101#[value(rename_all = "kebab-case")]
102pub enum Manager {
103 /// A Nix flake: an input pinned at a tag and its package in the devshell.
104 Flake,
105 /// mise: one `[tools]` entry in its configuration file.
106 Mise,
107 /// asdf: one line in `.tool-versions`.
108 Asdf,
109 /// devbox: one entry in the `packages` array of `devbox.json`.
110 Devbox,
111}
112
113impl Manager {
114 /// The wire form.
115 #[must_use]
116 pub const fn as_str(self) -> &'static str {
117 match self {
118 Self::Flake => "flake",
119 Self::Mise => "mise",
120 Self::Asdf => "asdf",
121 Self::Devbox => "devbox",
122 }
123 }
124
125 /// Every manager, in the order the reports list them.
126 pub const ALL: [Self; 4] = [Self::Flake, Self::Mise, Self::Asdf, Self::Devbox];
127}
128
129/// Where the source is fetched from.
130#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, ValueEnum)]
131#[serde(rename_all = "kebab-case")]
132#[value(rename_all = "kebab-case")]
133pub enum Channel {
134 /// The crate on crates.io.
135 Crates,
136 /// The flake the source repository serves, at a tag.
137 Flake,
138 /// The project on the Python package index.
139 Pypi,
140 /// The package on the npm registry.
141 Npm,
142 /// The prebuilt archives attached to a GitHub release.
143 GithubRelease,
144}
145
146impl Channel {
147 /// The wire form.
148 #[must_use]
149 pub const fn as_str(self) -> &'static str {
150 match self {
151 Self::Crates => "crates",
152 Self::Flake => "flake",
153 Self::Pypi => "pypi",
154 Self::Npm => "npm",
155 Self::GithubRelease => "github-release",
156 }
157 }
158
159 /// Every channel, in the order the reports list them.
160 pub const ALL: [Self; 5] = [
161 Self::Crates,
162 Self::Flake,
163 Self::Pypi,
164 Self::Npm,
165 Self::GithubRelease,
166 ];
167}