underhill_init/
options.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! CLI argument parsing for the underhill init process.
5
6#![warn(missing_docs)]
7
8// We've made our own parser here instead of using something like clap in order
9// to save on compiled file size. We don't need all the features a crate can provide.
10/// underhill init command-line options.
11#[derive(Debug, Default)]
12pub struct Options {
13    /// additional setup commands to run before starting underhill
14    pub setup_script: Vec<String>,
15
16    /// additional args to run underhill with
17    pub underhill_args: Vec<String>,
18}
19
20impl Options {
21    pub(crate) fn parse() -> Self {
22        let mut opts = Self::default();
23
24        let args: Vec<_> = std::env::args_os().collect();
25        // Skip our own filename.
26        let mut i = 1;
27
28        while let Some(next) = args.get(i) {
29            let arg = next.to_string_lossy();
30
31            if arg.starts_with("--") && arg.len() > 2 {
32                if let Some(eq) = arg.find('=') {
33                    let (name, value) = arg.split_at(eq);
34                    let parsed = Self::parse_value_arg(&mut opts, name, &value[1..]); // Don't forget to exclude the '=' itself.
35
36                    if !parsed {
37                        break;
38                    }
39                } else {
40                    if let Some(value) = args.get(i + 1).map(|x| x.to_string_lossy()) {
41                        let parsed = Self::parse_value_arg(&mut opts, &arg, &value);
42
43                        if parsed {
44                            i += 1;
45                        } else {
46                            break;
47                        }
48                    } else {
49                        break;
50                    }
51                }
52            } else if arg == "--" {
53                i += 1;
54                break;
55            } else {
56                break;
57            }
58
59            i += 1;
60        }
61
62        opts.underhill_args = args
63            .into_iter()
64            .skip(i)
65            .map(|x| x.to_string_lossy().into_owned())
66            .collect();
67
68        opts
69    }
70
71    #[must_use]
72    fn parse_value_arg(opts: &mut Self, name: &str, value: &str) -> bool {
73        match name {
74            "--setup-script" => {
75                opts.setup_script.push(value.to_owned());
76            }
77            _ => return false,
78        }
79
80        true
81    }
82}