docker_pose/args.rs
1/// Types to parse the command line arguments with the clap crate.
2use crate::{Verbosity, header, positive_less_than_32, string_no_empty, string_script};
3use clap::{Parser, Subcommand, ValueEnum};
4use std::cmp::Ord;
5
6#[derive(Parser)]
7#[command(author, version, about, long_about = None)]
8pub struct Args {
9 #[command(subcommand)]
10 pub command: Commands,
11
12 #[arg(short, long = "file", value_name = "FILENAME")]
13 pub filenames: Vec<String>,
14
15 /// Increase verbosity
16 #[arg(long, conflicts_with = "quiet")]
17 pub verbose: bool,
18
19 /// Only display relevant information or errors
20 #[arg(long, short, conflicts_with = "verbose")]
21 pub quiet: bool,
22
23 /// Don't call docker compose to parse compose model
24 #[arg(long)]
25 pub no_docker: bool,
26
27 /// Don't check model consistency - warning: may produce invalid Compose output
28 #[arg(long, conflicts_with = "no_docker")]
29 pub no_consistency: bool,
30
31 /// Don't interpolate environment variables
32 #[arg(long, conflicts_with = "no_docker")]
33 pub no_interpolate: bool,
34}
35
36impl Args {
37 pub fn get_verbosity(&self) -> Verbosity {
38 match self.verbose {
39 true => Verbosity::Verbose,
40 false => match self.quiet {
41 true => Verbosity::Quiet,
42 false => Verbosity::Info,
43 },
44 }
45 }
46}
47
48#[derive(Subcommand)]
49pub enum Commands {
50 /// List objects found in the compose file: services, volumes, ...
51 List {
52 #[command(subcommand)]
53 object: Objects,
54
55 #[arg(short, long, value_enum, default_value_t = Formats::Full, value_name = "FORMAT")]
56 pretty: Formats,
57 },
58 /// Parse, resolve and render compose file in canonical format
59 Config {
60 /// Save to file (default to stdout)
61 #[arg(short, long, value_name = "FILE")]
62 output: Option<String>,
63 /// output image attributes in services with a tag passed instead of the one set in the file
64 /// if they exist locally or in the remote docker registry
65 #[arg(short, long, value_name = "TAG", value_parser = string_no_empty)]
66 tag: Option<String>,
67 /// use with --tag to filter which images should be checked whether the
68 /// tag exists or not locally or remotely.
69 /// Currently only regex=EXPR or regex!=EXPR (invert match) are supported
70 #[arg(long, value_name = "FILTER", requires("tag"), value_parser = string_no_empty)]
71 tag_filter: Option<String>,
72 /// ignore unauthorized errors from docker when fetching remote tags info
73 #[arg(long, requires("tag"))]
74 ignore_unauthorized: bool,
75 /// Don't slugify the value from --tag
76 #[arg(long, requires("tag"))]
77 no_slug: bool,
78 /// only check --tag TAG with the local docker registry
79 #[arg(long, requires("tag"))]
80 offline: bool,
81 /// outputs in stderr the progress of fetching the tags info, similar to --verbose,
82 /// but without all the other details --verbose adds
83 #[arg(long, requires("tag"))]
84 progress: bool,
85 /// max number of threads used to fetch remote images info
86 #[arg(long, value_name = "NUM", default_value_t = 8, value_parser = positive_less_than_32, requires("tag"))]
87 threads: u8,
88 },
89 /// Outputs a slug version of the text passed, or the slug version of the
90 /// current branch.
91 ///
92 /// It's the same slug used with the --tag value in other commands.
93 /// The output is a lowercase version with all no-alphanumeric
94 /// characters translated into the "-" symbol, except for the char ".", to make it
95 /// compatible with a valid docker tag name.
96 Slug {
97 /// text to slugify, if not provided the current branch name is used
98 #[arg(value_parser = string_no_empty)]
99 text: Option<String>,
100 },
101
102 /// Download a file from an HTTP URL. If the resource doesn't exist, fallback
103 /// to another URL generated editing the URL given with a script provided in the
104 /// form of "text-to-replace:replacer".
105 Get {
106 /// The URL where the file is located
107 #[arg(value_parser = string_no_empty)]
108 url: String,
109 /// if request to URL responds back with HTTP 404, create a second URL
110 /// replacing any occurrence of the left part of the script with the right
111 /// part. Each part of the script has to be separated with the symbol `:`.
112 /// E.g. `pose get https://server.com/repo/feature-a/compose.yml feature-a:master`
113 /// will try to first download the resource from https://server.com/repo/feature-a/compose.yml,
114 /// if not found, will try at https://server.com/repo/master/compose.yml
115 #[arg(value_parser = string_script)]
116 script: Option<(String, String)>,
117 /// Save to file (default use the same filename set in the url)
118 #[arg(short, long, value_name = "FILE")]
119 output: Option<String>,
120 /// Maximum time in seconds that you allow pose's connection to take.
121 /// This only limits the connection phase, so if pose connects within the
122 /// given period, it will continue, if not, it will exit with error.
123 #[arg(long, value_name = "SECONDS", default_value_t = 10)]
124 timeout_connect: u16,
125 /// Maximum time in seconds that you allow the whole operation to take.
126 #[arg(short, long, value_name = "SECONDS", default_value_t = 300)]
127 max_time: u16,
128 /// HTTP header to include in the request
129 #[arg(short = 'H', long = "header", value_name = "HEADER", value_parser = header)]
130 headers: Vec<(String, String)>,
131 },
132}
133
134#[derive(Subcommand, strum_macros::Display, PartialEq)]
135pub enum Objects {
136 /// List services
137 Services {
138 /// filter by a property, currently only tag=TAG is supported
139 #[arg(short, long)]
140 filter: Option<String>,
141 },
142 /// List images
143 Images {
144 /// filter by a property, if --tag is used as well,
145 /// this filter is applied first, filtering out images that
146 /// don't match the filter. Currently only tag=TAG is supported
147 #[arg(short, long)]
148 filter: Option<String>,
149 /// print images with the tag passed instead of the one set in the file if they exist
150 /// locally or in the remote docker registry
151 #[arg(short, long, value_name = "TAG", value_parser = string_no_empty)]
152 tag: Option<String>,
153 /// use with --tag to filter which images should be checked whether the tag exists
154 /// or not, but images that don't match the filter are not filtered out from the list
155 /// printed, only printed with the tag they have in the compose file.
156 /// Currently only regex=EXPR or regex!=EXPR are supported
157 #[arg(long, value_name = "FILTER", requires("tag"), value_parser = string_no_empty)]
158 tag_filter: Option<String>,
159 /// ignore unauthorized errors from docker when fetching remote tags info
160 #[arg(long, requires("tag"))]
161 ignore_unauthorized: bool,
162 /// Don't slugify the value from --tag
163 #[arg(long, requires("tag"))]
164 no_slug: bool,
165 /// only check --tag TAG with the local docker registry
166 #[arg(long, requires("tag"))]
167 offline: bool,
168 /// outputs in stderr the progress of fetching the tags info, similar to --verbose
169 /// but without all the other details --verbose adds
170 #[arg(long, requires("tag"))]
171 progress: bool,
172 /// max number of threads used to fetch images info
173 #[arg(long, value_name = "NUM", default_value_t = 8, value_parser = positive_less_than_32, requires("tag"))]
174 threads: u8,
175 },
176 /// List service's depends_on services
177 Depends {
178 #[arg(required = true)]
179 services: Vec<String>,
180 },
181 /// List services that are dependants of the given services
182 Dependents {
183 #[arg(required = true)]
184 services: Vec<String>,
185 },
186 /// List volumes
187 Volumes,
188 /// List networks
189 Networks,
190 /// List configs
191 Configs,
192 /// List secrets
193 Secrets,
194 /// List profiles
195 Profiles,
196 /// List service's environment variables
197 Envs {
198 #[arg(value_parser = string_no_empty)]
199 service: String,
200 },
201}
202
203#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, ValueEnum, strum_macros::Display)]
204pub enum Formats {
205 Full,
206 Oneline,
207}