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

tamada / sibling / 21940904248

12 Feb 2026 09:28AM UTC coverage: 62.953% (-1.4%) from 64.338%
21940904248

Pull #44

github

tamada
refactor: update test assertions for path_to_string to reflect correct relative paths
Pull Request #44: refactor: reorganize code structure and update dependencies for improved functionality

165 of 282 new or added lines in 6 files covered. (58.51%)

3 existing lines in 2 files now uncovered.

452 of 718 relevant lines covered (62.95%)

4.07 hits per line

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

0.0
/cli/src/cli.rs
1
use std::path::PathBuf;
2

3
use clap::{Parser, ValueEnum};
4

5
use crate::{LogLevel, minisib};
6

7
#[derive(Debug, Parser)]
8
#[clap(version, author, about, arg_required_else_help = true)]
9
pub struct CliOpts {
10
    #[clap(flatten)]
11
    pub(crate) p_opts: PrintingOpts,
12

13
    #[clap(flatten)]
14
    pub(crate) nexter_opts: NexterOpts,
15

16
    #[clap(flatten)]
17
    pub(crate) init_script: InitOpts,
18

19
    #[clap(flatten)]
20
    pub(crate) log_opts: LogOpts,
21

22
    #[arg(
23
        short = 'w',
24
        long = "working-dir",
25
        help = "set the current working directory.",
26
        hide = true,
27
        value_name = "DIR",
28
        long_help = "This option is applied before any other processing. Therefore, other options that specify paths should use the relative path from this option value. If this option is not specified, the current directory is used."
29
    )]
30
    pub(crate) cwd: Option<PathBuf>,
31

32
    #[arg(index = 1, help = "the target directory", value_name = "DIR")]
33
    pub dirs: Vec<PathBuf>,
34

35
    #[cfg(debug_assertions)]
36
    #[clap(flatten)]
37
    pub(crate) compopts: CompletionOpts,
38

39
    #[clap(subcommand)]
40
    pub(crate) minisib: Option<minisib::MiniSibCommand>,
41
}
42

43
impl CliOpts {
NEW
44
    pub fn init(&mut self) {
×
NEW
45
        self.log_opts.init();
×
NEW
46
        if let Some(cwd) = &self.cwd && let Err(e) = std::env::set_current_dir(cwd) {
×
NEW
47
            log::error!("Failed to set current directory to {cwd:?}: {e}, use \".\"");
×
NEW
48
        }
×
NEW
49
        if self.dirs.is_empty() {
×
NEW
50
            match std::env::current_dir() {
×
NEW
51
                Ok(cwd) => self.dirs.push(cwd),
×
NEW
52
                Err(e) => {
×
NEW
53
                    log::error!("Failed to get current directory: {e}");
×
NEW
54
                    eprintln!("Error: failed to determine current working directory: {e}");
×
NEW
55
                    std::process::exit(1);
×
56
                }
57
            }
NEW
58
        }
×
NEW
59
    }
×
60
}
61

62
#[derive(Parser, Debug)]
63
pub(crate) struct LogOpts {
64
    #[arg(
65
        long,
66
        help = "set the log level",
67
        value_enum,
68
        default_value_t = LogLevel::Warn,
69
        value_name = "LEVEL",
70
        ignore_case = true
71
    )]
72
    pub log: LogLevel,
73
}
74

75
impl LogOpts {
NEW
76
    pub fn init(&self) {
×
77
        use LogLevel::{Debug, Error, Info, Trace, Warn};
NEW
78
        if std::env::var_os("RUST_LOG").is_none() {
×
79
            unsafe {
NEW
80
                match self.log {
×
NEW
81
                    Error => std::env::set_var("RUST_LOG", "error"),
×
NEW
82
                    Warn => std::env::set_var("RUST_LOG", "warn"),
×
NEW
83
                    Info => std::env::set_var("RUST_LOG", "info"),
×
NEW
84
                    Debug => std::env::set_var("RUST_LOG", "debug"),
×
NEW
85
                    Trace => std::env::set_var("RUST_LOG", "trace"),
×
86
                };
87
            }
NEW
88
        }
×
NEW
89
        env_logger::init();
×
NEW
90
        log::info!("Log level set to {:?}", self.log);
×
NEW
91
    }
×
92
}
93

94
#[derive(Parser, Debug)]
95
pub(crate) struct InitOpts {
96
    #[arg(
97
        long,
98
        help = "generate the initialize script for the shell",
99
        value_name = "SHELL",
100
        hide = true,
101
        default_missing_value = "bash"
102
    )]
103
    pub init: Option<String>,
104
}
105

106
#[derive(Parser, Debug)]
107
pub(crate) struct NexterOpts {
108
    #[arg(
109
        short,
110
        long,
111
        help = "specify the number of times to execute sibling",
112
        value_name = "COUNT",
113
        default_value_t = 1
114
    )]
115
    pub step: i32,
116

117
    #[arg(short = 't', long = "type", help = "specify the nexter type", value_enum, default_value_t = sibling::NexterType::Next, value_name = "TYPE", ignore_case = true)]
118
    pub nexter: sibling::NexterType,
119

120
    #[arg(
121
        short,
122
        long,
123
        help = "directory list from file, if FILE is \"-\", reads from stdin.",
124
        value_name = "FILE"
125
    )]
126
    pub input: Option<String>,
127

128
    #[arg(
129
        short = 'a',
130
        long,
131
        help = "Set the targets to all directories from the given list. By default, the sibling skips non-existent directories.",
132
        default_value_t = false
133
    )]
134
    pub all: bool,
135
}
136

137
#[cfg(debug_assertions)]
138
#[derive(Parser, Debug)]
139
pub(crate) struct CompletionOpts {
140
    #[arg(
141
        long = "generate-completion-files",
142
        help = "Generate completion files",
143
        hide = true
144
    )]
145
    pub(crate) completion: bool,
146

147
    #[arg(
148
        long = "completion-out-dir",
149
        value_name = "DIR",
150
        default_value = "assets/completions",
151
        help = "Output directory of completion files",
152
        hide = true
153
    )]
154
    pub(crate) dest: PathBuf,
155
}
156

157
#[derive(Debug, Clone, PartialEq, Eq, ValueEnum)]
158
pub enum Format {
159
    Json,
160
    Csv,
161
    List,
162
    Default,
163
}
164

165
#[derive(Debug, Parser)]
166
pub(crate) struct PrintingOpts {
167
    #[arg(
168
        short, long,
169
        help = "print the result in the specified format",
170
        default_value_t = Format::Default,
171
        value_enum,
172
    )]
173
    pub format: Format,
174

175
    #[arg(
176
        short = 'A',
177
        long,
178
        help = "print the directory name in the absolute path",
179
        default_value_t = false
180
    )]
181
    pub absolute: bool,
182

183
    #[arg(
184
        short,
185
        long,
186
        help = "print the progress of traversing directories",
187
        default_value_t = false
188
    )]
189
    pub progress: bool,
190

191
    #[arg(
192
        short = 'P',
193
        long,
194
        help = "print parent directory, when no more sibling directories are found",
195
        default_value_t = false
196
    )]
197
    pub parent: bool,
198
}
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