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

tamada / sibling / 21934150801

12 Feb 2026 04:57AM UTC coverage: 61.953% (-2.4%) from 64.338%
21934150801

Pull #44

github

tamada
refactor: simplify current directory handling in CliOpts initialization
Pull Request #44: refactor: reorganize code structure and update dependencies for improved functionality

136 of 243 new or added lines in 6 files covered. (55.97%)

3 existing lines in 2 files now uncovered.

425 of 686 relevant lines covered (61.95%)

4.17 hits per line

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

68.48
/cli/src/main.rs
1
use std::vec;
2

3
use crate::cli::{CliOpts, PrintingOpts};
4
use clap::Parser;
5
use sibling::{Dirs, Error, Nexter, Result};
6

7
mod cli;
8
mod gencomp;
9
mod init;
10
pub(crate) mod minisib;
11
pub(crate) mod printer;
12

13
#[derive(clap::ValueEnum, Clone, Debug)]
14
pub enum LogLevel {
15
    Error,
16
    Warn,
17
    Info,
18
    Debug,
19
    Trace,
20
}
21

22
fn perform_impl(dirs: &Dirs, nexter: &dyn Nexter, step: i32, opts: &PrintingOpts) -> String {
1✔
23
    let next = dirs.next_with(nexter, step);
1✔
24
    printer::result_string(dirs, next, opts)
1✔
25
}
1✔
26

27
fn perform_from_file(opts: CliOpts) -> Vec<Result<String>> {
1✔
28
    let nexter = sibling::NexterFactory::create(opts.nexter_opts.nexter);
1✔
29
    let r = match opts.nexter_opts.input {
1✔
UNCOV
30
        None => Err(Error::Fatal("input is not specified".into())),
×
31
        Some(file) => match Dirs::new_from_file_with(file, opts.nexter_opts.all) {
1✔
32
            Err(e) => Err(e),
1✔
NEW
33
            Ok(dirs) => Ok(perform_impl(
×
NEW
34
                &dirs,
×
NEW
35
                nexter.as_ref(),
×
NEW
36
                opts.nexter_opts.step,
×
NEW
37
                &opts.p_opts,
×
NEW
38
            )),
×
39
        },
40
    };
41
    vec![r]
1✔
42
}
1✔
43

44
fn perform_each(
1✔
45
    dir: std::path::PathBuf,
1✔
46
    nexter: &dyn Nexter,
1✔
47
    step: i32,
1✔
48
    opts: &PrintingOpts,
1✔
49
) -> Result<String> {
1✔
50
    match Dirs::new(dir) {
1✔
51
        Err(e) => Err(e),
×
52
        Ok(dirs) => Ok(perform_impl(&dirs, nexter, step, opts)),
1✔
53
    }
54
}
1✔
55

56
fn perform_sibling(opts: CliOpts) -> Vec<Result<String>> {
1✔
57
    let nexter = sibling::NexterFactory::create(opts.nexter_opts.nexter);
1✔
58
    let target_dirs = if opts.dirs.is_empty() {
1✔
59
        vec![std::env::current_dir().unwrap()]
×
60
    } else {
61
        opts.dirs
1✔
62
    };
63
    let mut result = vec![];
1✔
64
    for dir in target_dirs {
1✔
65
        let dir = if dir == std::path::Path::new(".") {
1✔
66
            std::env::current_dir().unwrap()
1✔
67
        } else {
68
            dir
×
69
        };
70
        let r = perform_each(dir, nexter.as_ref(), opts.nexter_opts.step, &opts.p_opts);
1✔
71
        result.push(r);
1✔
72
    }
73
    result
1✔
74
}
1✔
75

76
fn perform(opts: CliOpts) -> Vec<Result<String>> {
2✔
77
    if let Some(shell) = opts.init_script.init {
2✔
78
        vec![init::generate_init_script(&shell)]
×
79
    } else if opts.nexter_opts.input.is_some() {
2✔
80
        perform_from_file(opts)
1✔
81
    } else if let Some(minisib) = opts.minisib {
1✔
NEW
82
        vec![minisib.perform()]
×
83
    } else {
84
        perform_sibling(opts)
1✔
85
    }
86
}
2✔
87

88
fn main() {
×
NEW
89
    let mut opts = cli::CliOpts::parse();
×
NEW
90
    opts.init();
×
UNCOV
91
    if cfg!(debug_assertions) {
×
92
        #[cfg(debug_assertions)]
93
        if opts.compopts.completion {
×
94
            return gencomp::generate(&opts.compopts.dest);
×
95
        }
×
96
    }
×
97
    for item in perform(opts) {
×
98
        match item {
×
99
            Ok(result) => println!("{result}"),
×
100
            Err(e) => eprintln!("{e}"),
×
101
        }
102
    }
103
}
×
104

105
#[cfg(test)]
106
mod tests {
107
    use super::*;
108

109
    #[test]
110
    fn test_nexter_example() {
1✔
111
        let opts_r = cli::CliOpts::try_parse_from(vec!["sibling", "."]);
1✔
112

113
        if let Err(e) = &opts_r {
1✔
114
            eprintln!("{e}");
×
115
        }
1✔
116
        assert!(opts_r.is_ok());
1✔
117
        let r = perform(opts_r.unwrap());
1✔
118
        assert_eq!(r.len(), 1);
1✔
119
        match r.first().unwrap() {
1✔
120
            Err(e) => eprintln!("{e}"),
×
121
            Ok(result) => println!("{result}"),
1✔
122
        }
123
    }
1✔
124

125
    #[test]
126
    fn test_from_file() {
1✔
127
        let opts_r = cli::CliOpts::try_parse_from(vec![
1✔
128
            "sibling",
129
            "--input",
1✔
130
            "testdata/basic/dirlist.txt",
1✔
131
            "--type",
1✔
132
            "previous",
1✔
133
        ]);
134

135
        if let Err(e) = &opts_r {
1✔
136
            eprintln!("{e}");
×
137
        }
1✔
138
        assert!(opts_r.is_ok());
1✔
139
        let r = perform(opts_r.unwrap());
1✔
140
        assert_eq!(r.len(), 1);
1✔
141
        match r.first().unwrap() {
1✔
142
            Err(e) => eprintln!("{e}"),
1✔
143
            Ok(result) => assert_eq!(result, "testdata/basic/a"),
×
144
        }
145
    }
1✔
146
}
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