component/
args.rs

1// Copyright 2023 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5use argh::FromArgs;
6use component_debug::cli::{GraphFilter, GraphOrientation, ListFilter};
7use component_debug::config::RawConfigEntry;
8use component_debug::explore::DashNamespaceLayout;
9use fuchsia_url::AbsoluteComponentUrl;
10use moniker::Moniker;
11
12#[derive(FromArgs, PartialEq, Debug)]
13#[argh(
14    name = "component",
15    description = "Discover and manage components. Functionally equivalent to `ffx component`."
16)]
17pub struct ComponentArgs {
18    #[argh(subcommand)]
19    pub subcommand: ComponentSubcommand,
20}
21
22#[derive(FromArgs, PartialEq, Debug)]
23#[argh(subcommand)]
24pub enum ComponentSubcommand {
25    Capability(CapabilityArgs),
26    List(ListArgs),
27    Graph(GraphArgs),
28    Show(ShowArgs),
29    Create(CreateArgs),
30    Destroy(DestroyArgs),
31    Resolve(ResolveArgs),
32    Run(RunArgs),
33    Start(StartArgs),
34    Stop(StopArgs),
35    Reload(ReloadArgs),
36    Doctor(DoctorArgs),
37    Copy(CopyArgs),
38    Route(RouteArgs),
39    Storage(StorageArgs),
40    Collection(CollectionArgs),
41    Explore(ExploreArgs),
42    Config(ConfigArgs),
43}
44
45#[derive(FromArgs, PartialEq, Debug)]
46#[argh(subcommand, name = "show", description = "Same as `ffx component show`")]
47pub struct ShowArgs {
48    #[argh(positional)]
49    /// component URL, moniker or instance ID. Partial matches allowed.
50    pub query: String,
51}
52
53#[derive(FromArgs, Debug, PartialEq)]
54#[argh(subcommand, name = "create", description = "Same as `ffx component create`")]
55pub struct CreateArgs {
56    #[argh(positional)]
57    pub moniker: Moniker,
58
59    #[argh(positional)]
60    pub url: AbsoluteComponentUrl,
61
62    #[argh(option)]
63    /// provide a configuration override to the component being run. Requires
64    /// `mutability: [ "parent" ]` on the configuration field. Specified in the format
65    /// `KEY=VALUE` where `VALUE` is a JSON string which can be resolved as the correct type of
66    /// configuration value.
67    pub config: Vec<RawConfigEntry>,
68}
69
70#[derive(FromArgs, Debug, PartialEq)]
71#[argh(subcommand, name = "resolve", description = "Same as `ffx component resolve`")]
72pub struct ResolveArgs {
73    #[argh(positional)]
74    /// component URL, moniker or instance ID. Partial matches allowed.
75    pub query: String,
76}
77
78#[derive(FromArgs, Debug, PartialEq)]
79#[argh(subcommand, name = "destroy", description = "Same as `ffx component destroy`")]
80pub struct DestroyArgs {
81    #[argh(positional)]
82    /// component URL, moniker or instance ID. Partial matches allowed.
83    pub query: String,
84}
85
86#[derive(FromArgs, Debug, PartialEq)]
87#[argh(subcommand, name = "start", description = "Same as `ffx component start`")]
88pub struct StartArgs {
89    #[argh(positional)]
90    /// component URL, moniker or instance ID. Partial matches allowed.
91    pub query: String,
92}
93
94#[derive(FromArgs, Debug, PartialEq)]
95#[argh(subcommand, name = "stop", description = "Same as `ffx component stop`")]
96pub struct StopArgs {
97    #[argh(positional)]
98    /// component URL, moniker or instance ID. Partial matches allowed.
99    pub query: String,
100}
101
102#[derive(FromArgs, Debug, PartialEq)]
103#[argh(subcommand, name = "reload", description = "Same as `ffx component reload`")]
104pub struct ReloadArgs {
105    #[argh(positional)]
106    /// component URL, moniker or instance ID. Partial matches allowed.
107    pub query: String,
108}
109
110#[derive(FromArgs, Debug, PartialEq)]
111#[argh(subcommand, name = "doctor", description = "Same as `ffx component doctor`")]
112pub struct DoctorArgs {
113    #[argh(positional)]
114    /// component URL, moniker or instance ID. Partial matches allowed.
115    pub query: String,
116}
117
118#[derive(FromArgs, Debug, PartialEq)]
119#[argh(subcommand, name = "capability", description = "Same as `ffx component capability`")]
120pub struct CapabilityArgs {
121    #[argh(positional)]
122    pub capability_name: String,
123}
124
125#[derive(FromArgs, Debug, PartialEq)]
126#[argh(subcommand, name = "list", description = "Same as `ffx component list`")]
127pub struct ListArgs {
128    #[argh(option, long = "only", short = 'o')]
129    /// filter the instance list by a criteria: running, stopped, ancestors:<component_name>, descendants:<component_name>, or relatives:<component_name>
130    pub filter: Option<ListFilter>,
131
132    #[argh(switch, long = "verbose", short = 'v')]
133    /// show detailed information about each instance
134    pub verbose: bool,
135}
136
137#[derive(FromArgs, Debug, PartialEq)]
138#[argh(subcommand, name = "graph", description = "Same as `ffx component graph`")]
139pub struct GraphArgs {
140    #[argh(option, long = "only", short = 'o')]
141    /// filter the instance list by a criteria: ancestor, descendant, relative
142    pub filter: Option<GraphFilter>,
143
144    #[argh(option, long = "orientation", short = 'r', default = "GraphOrientation::TopToBottom")]
145    /// changes the visual orientation of the graph's nodes.
146    /// Allowed values are "lefttoright"/"lr" and "toptobottom"/"tb".
147    pub orientation: GraphOrientation,
148}
149
150#[derive(FromArgs, Debug, PartialEq)]
151#[argh(subcommand, name = "run", description = "Same as `ffx component run`")]
152pub struct RunArgs {
153    #[argh(positional)]
154    pub moniker: Moniker,
155
156    #[argh(positional)]
157    pub url: AbsoluteComponentUrl,
158
159    #[argh(switch, short = 'r')]
160    /// destroy and recreate the component instance if it already exists
161    pub recreate: bool,
162
163    #[argh(switch)]
164    /// connect stdin, stdout, and stderr to the component (requires component
165    /// to be in a collection with single_run durability)
166    pub connect_stdio: bool,
167
168    #[argh(option)]
169    /// provide a configuration override to the component being run. Requires
170    /// `mutability: [ "parent" ]` on the configuration field. Specified in the format
171    /// `KEY=VALUE` where `VALUE` is a JSON string which can be resolved as the correct type of
172    /// configuration value.
173    pub config: Vec<RawConfigEntry>,
174}
175
176#[derive(FromArgs, Debug, PartialEq)]
177#[argh(subcommand, name = "route", description = "Same as `ffx component route`")]
178pub struct RouteArgs {
179    #[argh(positional)]
180    /// component URL, moniker or instance ID of target component. Partial matches allowed.
181    pub target: String,
182
183    #[argh(positional)]
184    /// optional filter of comma-separated capability names or <decl type>:<capability> pairs.
185    /// If provided, <decl type> is one of `use` or `expose`, otherwise it will match both used
186    /// and exposed capabilities. Partial matches on <capability> are allowed.
187    ///
188    /// Examples:
189    /// - fuchsia.pkg.FontResolver
190    /// - use:fuchsia.pkg.FontResolver
191    /// - expose:fuchsia.fonts.Provider
192    /// - fuchsia.pkg.FontResolver,expose:fuchsia.fonts.Provider
193    /// - fuchsia.pkg
194    pub filter: Option<String>,
195}
196
197#[derive(FromArgs, Debug, PartialEq)]
198#[argh(subcommand, name = "copy", description = "Same as `ffx component copy`")]
199pub struct CopyArgs {
200    #[argh(positional)]
201    pub paths: Vec<String>,
202    /// show detailed information about copy action
203    #[argh(switch, short = 'v')]
204    pub verbose: bool,
205}
206
207#[derive(FromArgs, Debug, PartialEq)]
208#[argh(subcommand, name = "storage", description = "Same as `ffx component storage`")]
209pub struct StorageArgs {
210    #[argh(subcommand)]
211    pub subcommand: StorageSubcommand,
212
213    #[argh(option, default = "String::from(\"/core\")")]
214    /// the moniker of the storage provider component.
215    /// Defaults to "/core"
216    pub provider: String,
217
218    #[argh(option, default = "String::from(\"data\")")]
219    /// the capability name of the storage to use.
220    /// Examples: "data", "cache", "tmp"
221    /// Defaults to "data"
222    pub capability: String,
223}
224
225#[derive(FromArgs, PartialEq, Debug)]
226#[argh(subcommand)]
227pub enum StorageSubcommand {
228    Copy(StorageCopyArgs),
229    Delete(StorageDeleteArgs),
230    List(StorageListArgs),
231    MakeDirectory(StorageMakeDirectoryArgs),
232}
233
234#[derive(FromArgs, PartialEq, Debug)]
235#[argh(subcommand, name = "list", description = "Same as `ffx component storage list`")]
236pub struct StorageListArgs {
237    #[argh(positional)]
238    pub path: String,
239}
240
241#[derive(FromArgs, Debug, PartialEq)]
242#[argh(
243    subcommand,
244    name = "make-directory",
245    description = "Same as `ffx component storage make-directory`"
246)]
247pub struct StorageMakeDirectoryArgs {
248    #[argh(positional)]
249    pub path: String,
250}
251
252#[derive(FromArgs, Debug, PartialEq)]
253#[argh(subcommand, name = "copy", description = "Same as `ffx component storage copy`")]
254pub struct StorageCopyArgs {
255    #[argh(positional)]
256    pub source_path: String,
257
258    #[argh(positional)]
259    pub destination_path: String,
260}
261
262#[derive(FromArgs, Debug, PartialEq)]
263#[argh(subcommand, name = "delete", description = "Same as `ffx component storage delete`")]
264pub struct StorageDeleteArgs {
265    #[argh(positional)]
266    pub path: String,
267}
268
269#[derive(FromArgs, Debug, PartialEq)]
270#[argh(subcommand, name = "collection", description = "Same as `ffx component collection`")]
271pub struct CollectionArgs {
272    #[argh(subcommand)]
273    pub subcommand: CollectionSubcommand,
274}
275
276#[derive(FromArgs, PartialEq, Debug)]
277#[argh(subcommand)]
278pub enum CollectionSubcommand {
279    List(CollectionListArgs),
280    Show(CollectionShowArgs),
281}
282
283#[derive(FromArgs, PartialEq, Debug)]
284#[argh(subcommand, name = "list", description = "Same as `ffx component collection list`")]
285pub struct CollectionListArgs {
286    #[argh(positional)]
287    pub path: String,
288}
289
290#[derive(FromArgs, Debug, PartialEq)]
291#[argh(subcommand, name = "show", description = "Same as `ffx component collection show`")]
292pub struct CollectionShowArgs {
293    #[argh(positional)]
294    pub query: String,
295}
296
297#[derive(FromArgs, Debug, PartialEq)]
298#[argh(subcommand, name = "explore", description = "Same as `ffx component explore`")]
299pub struct ExploreArgs {
300    #[argh(positional)]
301    /// component URL, moniker or instance ID. Partial matches allowed.
302    pub query: String,
303
304    #[argh(option)]
305    /// list of URLs of tools packages to include in the shell environment.
306    /// the PATH variable will be updated to include binaries from these tools packages.
307    /// repeat `--tools url` for each package to be included.
308    /// The path preference is given by command line order.
309    pub tools: Vec<String>,
310
311    #[argh(option, short = 'c', long = "command")]
312    /// execute a command instead of reading from stdin.
313    /// the exit code of the command will be forwarded to the host.
314    pub command: Option<String>,
315
316    #[argh(
317        option,
318        short = 'l',
319        long = "layout",
320        default = "DashNamespaceLayout::NestAllInstanceDirs"
321    )]
322    /// changes the namespace layout that is created for the shell.
323    /// nested: nests all instance directories under subdirs (default)
324    /// namespace: sets the instance namespace as the root (works better for tools)
325    pub ns_layout: DashNamespaceLayout,
326}
327
328#[derive(FromArgs, Debug, PartialEq)]
329#[argh(subcommand, name = "config", description = "Same as `ffx component config`")]
330pub struct ConfigArgs {
331    #[argh(subcommand)]
332    pub subcommand: ConfigSubcommand,
333}
334
335#[derive(FromArgs, Debug, PartialEq)]
336#[argh(subcommand)]
337pub enum ConfigSubcommand {
338    Set(SetArgs),
339    Unset(UnsetArgs),
340    List(ConfigListArgs),
341}
342
343#[derive(FromArgs, Debug, PartialEq)]
344#[argh(subcommand, name = "set", description = "Same as `ffx component config set`")]
345pub struct SetArgs {
346    #[argh(positional)]
347    /// component URL, moniker or instance ID. Partial matches allowed.
348    pub query: String,
349    #[argh(positional)]
350    /// key-value pairs of the configuration capability to be overridden. Takes
351    /// the form 'key="value"'.
352    pub key_values: Vec<String>,
353    #[argh(switch, short = 'r')]
354    /// if enabled, component instance will be immediately reloaded so overrides
355    /// take effect.
356    pub reload: bool,
357}
358
359#[derive(FromArgs, Debug, PartialEq)]
360#[argh(subcommand, name = "unset", description = "Same as `ffx component config unset`")]
361pub struct UnsetArgs {
362    #[argh(positional)]
363    /// component URL, moniker or instance ID. Partial matches allowed. If
364    /// empty, unsets structured config overrides for all components.
365    pub query: Option<String>,
366    #[argh(switch, short = 'r')]
367    /// if enabled, component instance will be immediately reloaded so overrides
368    /// take effect.
369    pub reload: bool,
370}
371
372#[derive(FromArgs, Debug, PartialEq)]
373#[argh(subcommand, name = "list", description = "Same as `ffx component config list`")]
374pub struct ConfigListArgs {
375    #[argh(positional)]
376    /// component URL, moniker or instance ID. Partial matches allowed.
377    pub query: String,
378}