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

tamada / sibling / 21935126510

12 Feb 2026 05:44AM UTC coverage: 61.863% (-2.5%) from 64.338%
21935126510

Pull #44

github

tamada
refactor: improve directory change handling and error logging in path resolution
Pull Request #44: refactor: reorganize code structure and update dependencies for improved functionality

136 of 248 new or added lines in 6 files covered. (54.84%)

3 existing lines in 2 files now uncovered.

425 of 687 relevant lines covered (61.86%)

4.17 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
            self.dirs.push(std::env::current_dir().unwrap());
×
NEW
51
        }
×
NEW
52
    }
×
53
}
54

55
#[derive(Parser, Debug)]
56
pub(crate) struct LogOpts {
57
    #[arg(
58
        long,
59
        help = "set the log level",
60
        value_enum,
61
        default_value_t = LogLevel::Warn,
62
        value_name = "LEVEL",
63
        ignore_case = true
64
    )]
65
    pub log: LogLevel,
66
}
67

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

87
#[derive(Parser, Debug)]
88
pub(crate) struct InitOpts {
89
    #[arg(
90
        long,
91
        help = "generate the initialize script for the shell",
92
        value_name = "SHELL",
93
        hide = true,
94
        default_missing_value = "bash"
95
    )]
96
    pub init: Option<String>,
97
}
98

99
#[derive(Parser, Debug)]
100
pub(crate) struct NexterOpts {
101
    #[arg(
102
        short,
103
        long,
104
        help = "specify the number of times to execute sibling",
105
        value_name = "COUNT",
106
        default_value_t = 1
107
    )]
108
    pub step: i32,
109

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

113
    #[arg(
114
        short,
115
        long,
116
        help = "directory list from file, if FILE is \"-\", reads from stdin.",
117
        value_name = "FILE"
118
    )]
119
    pub input: Option<String>,
120

121
    #[arg(
122
        short = 'a',
123
        long,
124
        help = "Set the targets to all directories from the given list. By default, the sibling skips non-existent directories.",
125
        default_value_t = false
126
    )]
127
    pub all: bool,
128
}
129

130
#[cfg(debug_assertions)]
131
#[derive(Parser, Debug)]
132
pub(crate) struct CompletionOpts {
133
    #[arg(
134
        long = "generate-completion-files",
135
        help = "Generate completion files",
136
        hide = true
137
    )]
138
    pub(crate) completion: bool,
139

140
    #[arg(
141
        long = "completion-out-dir",
142
        value_name = "DIR",
143
        default_value = "assets/completions",
144
        help = "Output directory of completion files",
145
        hide = true
146
    )]
147
    pub(crate) dest: PathBuf,
148
}
149

150
#[derive(Debug, Clone, PartialEq, Eq, ValueEnum)]
151
pub enum Format {
152
    Json,
153
    Csv,
154
    List,
155
    Default,
156
}
157

158
#[derive(Debug, Parser)]
159
pub(crate) struct PrintingOpts {
160
    #[arg(
161
        short, long,
162
        help = "print the result in the specified format",
163
        default_value_t = Format::Default,
164
        value_enum,
165
    )]
166
    pub format: Format,
167

168
    #[arg(
169
        short = 'A',
170
        long,
171
        help = "print the directory name in the absolute path",
172
        default_value_t = false
173
    )]
174
    pub absolute: bool,
175

176
    #[arg(
177
        short,
178
        long,
179
        help = "print the progress of traversing directories",
180
        default_value_t = false
181
    )]
182
    pub progress: bool,
183

184
    #[arg(
185
        short = 'P',
186
        long,
187
        help = "print parent directory, when no more sibling directories are found",
188
        default_value_t = false
189
    )]
190
    pub parent: bool,
191
}
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