Skip to content

Commit 967b9df

Browse files
committed
Partial sketch of check_mode "translation" to Rust
1 parent ee33221 commit 967b9df

File tree

4 files changed

+65
-0
lines changed

4 files changed

+65
-0
lines changed

tests/it/src/args.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,17 @@ pub enum Subcommands {
6262
#[clap(value_parser = AsPathSpec)]
6363
patterns: Vec<gix::pathspec::Pattern>,
6464
},
65+
/// Check for executable bits that disagree with shebangs.
66+
///
67+
/// This checks and staged files, but not any unstaged files or changes, to find shell scripts
68+
/// that either begin with a `#!` but not `+x` permissions, or do not begin with `#!` but do
69+
/// have `+x` permissions. Such mismatches are reported but not automatically corrected. Some
70+
/// plaforms (at least Windows) do not support such permissions, but Git still represents them.
71+
///
72+
/// This currently only checks files name with an `.sh` suffix, and only operates on the
73+
/// current repository. Its main use is checking that fixture scripts are have correct modes.
74+
#[clap(visible_alias = "cm")]
75+
CheckMode {},
6576
}
6677

6778
#[derive(Clone)]

tests/it/src/commands/check_mode.rs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
pub(super) mod function {
2+
use anyhow::{bail, Context};
3+
use gix::bstr::ByteSlice;
4+
use std::ffi::OsString;
5+
use std::io::{BufRead, BufReader};
6+
use std::process::{Command, Stdio};
7+
8+
pub fn check_mode() -> anyhow::Result<()> {
9+
let root = find_root()?;
10+
let mut mismatch = false;
11+
12+
let cmd = Command::new("git")
13+
.arg("-C")
14+
.arg(root)
15+
.args(["ls-files", "-sz", "--", "*.sh"])
16+
.stdout(Stdio::piped())
17+
.spawn()
18+
.context("Can't run `git` to list index")?;
19+
20+
let stdout = cmd.stdout.expect("should have captured stdout");
21+
let reader = BufReader::new(stdout);
22+
for record in reader.split(b'\0') {
23+
// FIXME: Use the record, displaying messages and updating `mismatch`.
24+
}
25+
26+
// FIXME: If `cmd` did not report successful completion, bail.
27+
// FIXME: If `mismatch` (any mismatches), bail.
28+
bail!("not yet implemented");
29+
}
30+
31+
fn find_root() -> anyhow::Result<OsString> {
32+
let output = Command::new("git")
33+
.args(["rev-parse", "--show-toplevel"])
34+
.output()
35+
.context("Can't run `git` to find worktree root")?;
36+
37+
if !output.status.success() {
38+
bail!("`git` failed to find worktree root");
39+
}
40+
41+
let root = output
42+
.stdout
43+
.strip_suffix(b"\n")
44+
.context("Can't parse worktree root")?
45+
.to_os_str()?
46+
.to_owned();
47+
48+
Ok(root)
49+
}
50+
}

tests/it/src/commands/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,6 @@ pub use copy_royal::function::copy_royal;
33

44
pub mod git_to_sh;
55
pub use git_to_sh::function::git_to_sh;
6+
7+
pub mod check_mode;
8+
pub use check_mode::function::check_mode;

tests/it/src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ fn main() -> anyhow::Result<()> {
3131
destination_dir,
3232
patterns,
3333
} => commands::copy_royal(dry_run, &worktree_root, destination_dir, patterns),
34+
Subcommands::CheckMode {} => commands::check_mode(),
3435
}
3536
}
3637

0 commit comments

Comments
 (0)