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

jhheider / semverator / 28843943571

07 Jul 2026 05:31AM UTC coverage: 82.593% (-16.9%) from 99.455%
28843943571

push

github

web-flow
ci: adopt shared jhheider/rust-ci workflows; move off nightly (#106)

Replace the hand-rolled nightly CI (check-and-lint + test with tarpaulin
coverage, plus the separate markdownlint job) with thin callers into
jhheider/rust-ci@v1 (reusable ci/audit/style). Runs on the STABLE toolchain -
semverator builds and tests clean on stable (edition 2021, no nightly
features; the nightly pin was a stale relic) - with the shared 3-OS matrix
and cargo-llvm-cov coverage. Adds a security-audit and the ASCII style gate.
release-packaging.yaml is left for a dedicated release pass.


Claude-Session: https://claude.ai/code/session_01PtgaNLj8kZthZWZBr9kMyh

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

465 of 563 relevant lines covered (82.59%)

39.22 hits per line

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

78.38
/cli/src/args/mod.rs
1
use anyhow::{Context, Result};
2
use clap::{arg, command, ArgAction, ArgMatches, Command};
3
use libsemverator::{
4
    range::Range,
5
    semver::{bump::SemverComponent, Semver},
6
};
7

8
pub fn setup() -> Command {
1✔
9
    command!()
1✔
10
        .subcommand_required(true)
1✔
11
        .arg_required_else_help(true)
1✔
12
        // Semver::validate
13
        .subcommand(
1✔
14
            Command::new("validate")
1✔
15
                .about("validates a version")
1✔
16
                .arg(arg!([semver] "the version to validate").value_parser(Semver::parse)),
1✔
17
        )
18
        // Semver::eq
19
        .subcommand(
1✔
20
            Command::new("eq")
1✔
21
                .about("checks if two versions are equal")
1✔
22
                .arg(arg!([left] "the first version to compare").value_parser(Semver::parse))
1✔
23
                .arg(arg!([right] "the second version to compare").value_parser(Semver::parse)),
1✔
24
        )
25
        // Semver::neq
26
        .subcommand(
1✔
27
            Command::new("neq")
1✔
28
                .about("checks if two versions are not equal")
1✔
29
                .arg(arg!([left] "the first version to compare").value_parser(Semver::parse))
1✔
30
                .arg(arg!([right] "the second version to compare").value_parser(Semver::parse)),
1✔
31
        )
32
        // Semver::gt
33
        .subcommand(
1✔
34
            Command::new("gt")
1✔
35
                .about("checks if left > right")
1✔
36
                .arg(arg!([left] "the first version to compare").value_parser(Semver::parse))
1✔
37
                .arg(arg!([right] "the second version to compare").value_parser(Semver::parse)),
1✔
38
        )
39
        // Semver::lt
40
        .subcommand(
1✔
41
            Command::new("lt")
1✔
42
                .about("checks if left < right")
1✔
43
                .arg(arg!([left] "the first version to compare").value_parser(Semver::parse))
1✔
44
                .arg(arg!([right] "the second version to compare").value_parser(Semver::parse)),
1✔
45
        )
46
        // Semver::bump
47
        .subcommand(
1✔
48
            Command::new("bump")
1✔
49
                .about("bumps a version")
1✔
50
                .arg(arg!([semver] "the version to bump").value_parser(Semver::parse))
1✔
51
                .arg(
1✔
52
                    arg!([bump] "the bump to apply (major|minor|patch)")
1✔
53
                        .value_parser(SemverComponent::parse),
1✔
54
                ),
55
        )
56
        // Range::validate-range
57
        .subcommand(
1✔
58
            Command::new("validate-range")
1✔
59
                .about("validates a range")
1✔
60
                .arg(arg!([range] "the range to validate").value_parser(Range::parse)),
1✔
61
        )
62
        // Range::satisfies
63
        .subcommand(
1✔
64
            Command::new("satisfies")
1✔
65
                .about("validates a range satisfies a semver")
1✔
66
                .arg(arg!([range] "the range to validate").value_parser(Range::parse))
1✔
67
                .arg(arg!([semver] "the semver to test").value_parser(Semver::parse)),
1✔
68
        )
69
        // Range::max
70
        .subcommand(
1✔
71
            Command::new("max")
1✔
72
                .about("maximum version that satisifies a range")
1✔
73
                .arg(arg!([range] "the range to validate").value_parser(Range::parse))
1✔
74
                .arg(
1✔
75
                    arg!([semver] "the semvers to test")
1✔
76
                        .value_parser(Semver::parse)
1✔
77
                        .action(ArgAction::Append),
1✔
78
                ),
79
        )
80
        // Range::intersect
81
        .subcommand(
1✔
82
            Command::new("intersect")
1✔
83
                .about("intersection between two ranges")
1✔
84
                .arg(arg!([left] "the first range to intersect").value_parser(Range::parse))
1✔
85
                .arg(arg!([right] "the second range to intersect").value_parser(Range::parse)),
1✔
86
        )
87
}
1✔
88

89
#[cfg(not(tarpaulin_include))]
90
pub fn get_arg<'a, T>(args: &'a ArgMatches, key: &'a str) -> Result<T>
×
91
where
×
92
    T: Clone + Send + Sync + 'static,
×
93
{
94
    args.get_one::<T>(key)
×
95
        .context(format!("{key} is missing"))
×
96
        .cloned()
×
97
}
×
98

99
#[cfg(not(tarpaulin_include))]
100
pub fn get_arg_vec<'a, T>(args: &'a ArgMatches, key: &'a str) -> Result<Vec<T>>
×
101
where
×
102
    T: Clone + Send + Sync + 'static,
×
103
{
104
    Ok(args
×
105
        .get_many::<T>(key)
×
106
        .context(format!("no {key}s were passed"))?
×
107
        .cloned()
×
108
        .collect::<Vec<T>>())
×
109
}
×
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