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}