Skip to content

Commit a35783e

Browse files
committed
Repair non-unix builds
There were a couple of unix-specifc API usages wrapped by `if cfg!(unix)`. The problem with this approach is that although `if cfg!(unix)` will prevent that branch from being taken on non-unix platforms at runtime, it *does not* eliminate that branch at compile time. Thus any use of unix-specific APIs within those blocks will cause compilation failure on non-unix platforms. The repair is to create unix and non-unix functions that are resolved at compile time.
1 parent 0f34279 commit a35783e

File tree

2 files changed

+34
-21
lines changed

2 files changed

+34
-21
lines changed

src/hook.rs

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,9 @@ pub(crate) fn run_pre_commit_hook(repo: &git2::Repository, use_editor: bool) ->
4444
return Ok(());
4545
}
4646

47-
if cfg!(unix) {
48-
use std::os::unix::fs::MetadataExt;
49-
// Ignore non-executable hooks
50-
if hook_meta.mode() & 0o111 == 0 {
51-
return Ok(());
52-
}
47+
// Ignore non-executable hooks
48+
if !is_executable(&hook_meta) {
49+
return Ok(());
5350
}
5451

5552
let mut hook_command = std::process::Command::new(hook_path);
@@ -105,12 +102,9 @@ pub(crate) fn run_commit_msg_hook<'repo>(
105102
return Ok(message);
106103
}
107104

108-
if cfg!(unix) {
109-
use std::os::unix::fs::MetadataExt;
110-
// Ignore non-executable hooks
111-
if hook_meta.mode() & 0o111 == 0 {
112-
return Ok(message);
113-
}
105+
// Ignore non-executable hooks
106+
if !is_executable(&hook_meta) {
107+
return Ok(message);
114108
}
115109

116110
let mut msg_file = tempfile::NamedTempFile::new()?;
@@ -151,3 +145,14 @@ pub(crate) fn run_commit_msg_hook<'repo>(
151145
))
152146
}
153147
}
148+
149+
#[cfg(unix)]
150+
fn is_executable(meta: &std::fs::Metadata) -> bool {
151+
use std::os::unix::fs::MetadataExt;
152+
meta.mode() & 0o111 != 0
153+
}
154+
155+
#[cfg(not(unix))]
156+
fn is_executable(_meta: &std::fs::Metadata) -> bool {
157+
true
158+
}

src/stupid.rs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ use std::{
2020
ffi::{OsStr, OsString},
2121
io::Write,
2222
path::Path,
23-
process::{Child, Command, Output, Stdio},
23+
process::{Child, Command, Output, ExitStatus, Stdio},
2424
};
2525

2626
use anyhow::{anyhow, Context, Result};
@@ -638,14 +638,11 @@ impl<'repo, 'index> StupidContext<'repo, 'index> {
638638
command.args(pathspecs);
639639
}
640640
let output = command.stdout(Stdio::inherit()).output_git()?;
641-
if cfg!(unix) {
642-
use std::os::unix::process::ExitStatusExt;
643-
if output.status.signal() == Some(13) {
644-
// `git log` process was killed by SIGPIPE, probably due to pager exiting before
645-
// all log output could be written. This is normal, but `git log` does not print an
646-
// error message to stderr, so we inject our own error string.
647-
return Err(git_command_error("log", b"broken pipe"));
648-
}
641+
if is_status_signal(&output.status, 13) {
642+
// `git log` process was killed by SIGPIPE, probably due to pager exiting before
643+
// all log output could be written. This is normal, but `git log` does not print an
644+
// error message to stderr, so we inject our own error string.
645+
return Err(git_command_error("log", b"broken pipe"));
649646
}
650647
output.require_success("log")?;
651648
Ok(())
@@ -1172,3 +1169,14 @@ fn parse_oid(output: &[u8]) -> Result<git2::Oid> {
11721169
fn map_color_opt(opt: Option<&str>) -> Option<&str> {
11731170
opt.map(|o| if o == "ansi" { "always" } else { o })
11741171
}
1172+
1173+
#[cfg(unix)]
1174+
fn is_status_signal(status: &ExitStatus, signum: i32) -> bool {
1175+
use std::os::unix::process::ExitStatusExt;
1176+
status.signal() == Some(signum)
1177+
}
1178+
1179+
#[cfg(not(unix))]
1180+
fn is_status_signal(_status: &ExitStatus, _signum: i32) -> bool {
1181+
false
1182+
}

0 commit comments

Comments
 (0)