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