• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

tamada / totebag / 12971428409

26 Jan 2025 04:28AM UTC coverage: 79.748% (-0.9%) from 80.663%
12971428409

push

github

web-flow
Merge pull request #37 from tamada/release/v0.7.0

Release/v0.7.0

734 of 954 new or added lines in 20 files covered. (76.94%)

35 existing lines in 7 files now uncovered.

1583 of 1985 relevant lines covered (79.75%)

15.41 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.29
/src/cli.rs
1
use clap::{Parser, ValueEnum};
2
use std::path::PathBuf;
3

4
use totebag::format::is_all_args_archives;
5
use totebag::{IgnoreType, Result, ToteError};
6

7
#[derive(Debug, Clone, ValueEnum, PartialEq, Copy)]
8
pub enum RunMode {
9
    Auto,
10
    Archive,
11
    Extract,
12
    List,
13
}
14

15
#[derive(Parser, Debug)]
16
#[clap(version, author, about, arg_required_else_help = true)]
17
pub struct CliOpts {
18
    #[clap(flatten)]
19
    pub extractors: ExtractorOpts,
20

21
    #[clap(flatten)]
22
    pub archivers: ArchiverOpts,
23

24
    #[clap(flatten)]
25
    pub listers: ListerOpts,
26

27
    #[clap(long = "level", help = "Specify the log level", default_value_t = LogLevel::Warn, ignore_case = true, value_enum)]
1✔
28
    pub level: LogLevel,
×
29

30
    #[clap(short = 'm', long = "mode", default_value_t = RunMode::Auto, value_name = "MODE", required = false, ignore_case = true, value_enum, help = "Mode of operation.")]
1✔
31
    pub mode: RunMode,
×
32

33
    #[cfg(debug_assertions)]
34
    #[clap(
35
        long = "generate-completion",
36
        hide = true,
37
        help = "Generate the completion files"
38
    )]
NEW
39
    pub generate_completion: bool,
×
40

41
    #[clap(
42
        short = 'o',
43
        short_alias = 'd',
44
        long = "output",
45
        alias = "dest",
46
        value_name = "DEST",
47
        required = false,
48
        help = "Output file in archive mode, or output directory in extraction mode"
49
    )]
50
    pub output: Option<PathBuf>,
51

52
    #[clap(long, help = "Overwrite existing files.")]
53
    pub overwrite: bool,
×
54

55
    #[clap(
56
        value_name = "ARGUMENTS",
57
        help = r###"List of files or directories to be processed.
58
If archive mode, the archive file name can specify at the first argument.
59
If the frist argument was not the archive name, the default archive name `totebag.zip` is applied.
60
"###
61
    )]
62
    pub args: Vec<String>,
5✔
63
}
64

65
#[derive(Parser, Debug)]
66
pub struct ListerOpts {
67
    #[clap(
68
        short,
69
        long,
70
        help = "List entries in the archive file with long format."
71
    )]
UNCOV
72
    pub long: bool,
×
73
}
74

75
#[derive(Parser, Debug)]
76
pub struct ArchiverOpts {
77
    #[clap(
78
        short = 'C',
79
        long = "dir",
80
        value_name = "DIR",
81
        required = false,
82
        default_value = ".",
83
        help = "Specify the base directory for archiving or extracting."
84
    )]
85
    pub base_dir: PathBuf,
×
86

87
    #[clap(
88
        short = 'i',
89
        long = "ignore-types",
90
        value_name = "IGNORE_TYPES",
91
        value_delimiter = ',',
92
        help = "Specify the ignore type."
93
    )]
UNCOV
94
    pub ignores: Vec<IgnoreType>,
×
95

96
    #[clap(
97
        short = 'n',
98
        long = "no-recursive",
99
        help = "No recursive directory (archive mode).",
100
        default_value_t = false
1✔
101
    )]
UNCOV
102
    pub no_recursive: bool,
×
103
}
104

105
#[derive(Parser, Debug)]
106
pub struct ExtractorOpts {
107
    #[clap(
108
        long = "to-archive-name-dir",
109
        help = "extract files to DEST/ARCHIVE_NAME directory (extract mode).",
110
        default_value_t = false
1✔
111
    )]
UNCOV
112
    pub to_archive_name_dir: bool,
×
113
}
114

115
#[derive(Parser, Debug, ValueEnum, Clone, PartialEq, Copy)]
116
pub enum LogLevel {
117
    Error,
118
    Warn,
119
    Info,
120
    Debug,
121
}
122

123
impl CliOpts {
124
    pub fn run_mode(&mut self) -> Result<RunMode> {
7✔
125
        if self.args.len() == 0 {
7✔
NEW
126
            return Err(ToteError::NoArgumentsGiven);
×
127
        }
7✔
128
        if self.mode == RunMode::Auto {
7✔
129
            if is_all_args_archives(
3✔
130
                &self
3✔
131
                    .args
3✔
132
                    .iter()
3✔
133
                    .map(PathBuf::from)
3✔
134
                    .collect::<Vec<PathBuf>>(),
3✔
135
            ) {
3✔
136
                self.mode = RunMode::Extract;
1✔
137
                Ok(RunMode::Extract)
1✔
138
            } else {
139
                self.mode = RunMode::Archive;
2✔
140
                Ok(RunMode::Archive)
2✔
141
            }
142
        } else {
143
            Ok(self.mode)
4✔
144
        }
145
    }
7✔
146
}
147

148
#[cfg(test)]
149
mod tests {
150
    use clap::Parser;
151

152
    use super::*;
153

154
    #[test]
155
    fn test_find_mode() {
1✔
156
        let mut cli1 =
1✔
157
            CliOpts::parse_from(&["totebag_test", "src", "LICENSE", "README.md", "Cargo.toml"]);
1✔
158
        let r1 = cli1.run_mode();
1✔
159
        assert!(r1.is_ok());
1✔
160
        assert_eq!(r1.unwrap(), RunMode::Archive);
1✔
161

162
        let mut cli2 =
1✔
163
            CliOpts::parse_from(&["totebag_test", "src", "LICENSE", "README.md", "hoge.zip"]);
1✔
164
        let r2 = cli2.run_mode();
1✔
165
        assert!(r2.is_ok());
1✔
166
        assert_eq!(cli2.run_mode().unwrap(), RunMode::Archive);
1✔
167

168
        let mut cli3 = CliOpts::parse_from(&[
1✔
169
            "totebag_test",
1✔
170
            "src.zip",
1✔
171
            "LICENSE.tar",
1✔
172
            "README.tar.bz2",
1✔
173
            "hoge.rar",
1✔
174
        ]);
1✔
175
        let r3 = cli3.run_mode();
1✔
176
        assert!(r3.is_ok());
1✔
177
        assert_eq!(cli3.run_mode().unwrap(), RunMode::Extract);
1✔
178

179
        let mut cli4 = CliOpts::parse_from(&[
1✔
180
            "totebag_test",
1✔
181
            "src.zip",
1✔
182
            "LICENSE.tar",
1✔
183
            "README.tar.bz2",
1✔
184
            "hoge.rar",
1✔
185
            "--mode",
1✔
186
            "list",
1✔
187
        ]);
1✔
188
        let r4 = cli4.run_mode();
1✔
189
        assert!(r4.is_ok());
1✔
190
        assert_eq!(cli4.run_mode().unwrap(), RunMode::List);
1✔
191

192
        let r = CliOpts::try_parse_from(&["totebag_test"]);
1✔
193
        assert!(r.is_err());
1✔
194
    }
1✔
195
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc