Skip to content

Commit 98babd8

Browse files
committed
fix: check for bool_to_result
1 parent 7e99f76 commit 98babd8

File tree

7 files changed

+307
-27
lines changed

7 files changed

+307
-27
lines changed

Cargo.toml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ version = "0.1.1"
99
authors = ["Brandon LeBlanc <brandon@leblanc.codes>"]
1010
repository = "https://github.com/demosdemon/git-remote-codecommit"
1111
homepage = "https://github.com/demosdemon/git-remote-codecommit"
12-
edition = "2021"
12+
edition = "2024"
1313
license = "MIT OR Apache-2.0"
1414
readme = "README.md"
1515
keywords = ["git", "git-remote", "codecommit"]
@@ -21,7 +21,7 @@ let_underscore_drop = "warn"
2121
# unused_crate_dependencies = "warn" # use `cargo udeps` instead
2222
non_ascii_idents = "deny"
2323
rust_2024_compatibility = { level = "warn", priority = -1 }
24-
24+
2525
[workspace.lints.clippy]
2626
# struct_excessive_bools = "allow"
2727
missing_panics_doc = "allow"
@@ -32,7 +32,7 @@ cargo_common_metadata = "warn"
3232
negative_feature_names = "warn"
3333
redundant_feature_names = "warn"
3434
unwrap_used = "warn"
35-
35+
3636
[profile.release-lto]
3737
inherits = "release"
3838
lto = "fat"
Lines changed: 253 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,253 @@
1+
use std::ffi::OsString;
2+
use std::fmt;
3+
use std::fmt::Write;
4+
use std::fs;
5+
use std::io::ErrorKind;
6+
use std::path::Path;
7+
use std::process::Command;
8+
9+
macro_rules! die {
10+
($($arg:tt)*) => {{
11+
eprintln!("ERROR: {}", format_args!($($arg)*));
12+
std::process::exit(1);
13+
}};
14+
}
15+
16+
fn main() {
17+
println!("cargo:rustc-check-cfg=cfg(build_feature_probe)");
18+
println!("cargo:rustc-check-cfg=cfg(bool_to_result)");
19+
20+
let bool_to_result;
21+
println!("cargo:rerun-if-changed=src/nightly.rs");
22+
23+
let consider_rustc_bootstrap;
24+
if compile_probe(false) {
25+
// This is a nightly or dev compiler, so it supports unstable
26+
// features regardless of RUSTC_BOOTSTRAP. No need to rerun build
27+
// script if RUSTC_BOOTSTRAP is changed.
28+
bool_to_result = true;
29+
consider_rustc_bootstrap = false;
30+
} else if let Some(rustc_bootstrap) = std::env::var_os("RUSTC_BOOTSTRAP") {
31+
if compile_probe(true) {
32+
// This is a stable or beta compiler for which the user has set
33+
// RUSTC_BOOTSTRAP to turn on unstable features. Rerun build
34+
// script if they change it.
35+
bool_to_result = true;
36+
consider_rustc_bootstrap = true;
37+
} else if rustc_bootstrap == "1" {
38+
// This compiler does not support the generic member access API
39+
// in the form that anyhow expects. No need to pay attention to
40+
// RUSTC_BOOTSTRAP.
41+
bool_to_result = false;
42+
consider_rustc_bootstrap = false;
43+
} else {
44+
// This is a stable or beta compiler for which RUSTC_BOOTSTRAP
45+
// is set to restrict the use of unstable features by this
46+
// crate.
47+
bool_to_result = false;
48+
consider_rustc_bootstrap = true;
49+
}
50+
} else {
51+
// Without RUSTC_BOOTSTRAP, this compiler does not support the
52+
// generic member access API in the form that anyhow expects, but
53+
// try again if the user turns on unstable features.
54+
bool_to_result = false;
55+
consider_rustc_bootstrap = true;
56+
}
57+
58+
if bool_to_result {
59+
println!("cargo:rustc-cfg=bool_to_result");
60+
}
61+
62+
if consider_rustc_bootstrap {
63+
println!("cargo:rerun-if-env-changed=RUSTC_BOOTSTRAP");
64+
}
65+
}
66+
67+
fn compile_probe(rustc_bootstrap: bool) -> bool {
68+
if std::env::var_os("RUSTC_STAGE").is_some() {
69+
println!("cargo:rerun-if-env-changed=RUSTC_STAGE");
70+
// We are running inside rustc bootstrap. This is a highly non-standard
71+
// environment with issues such as:
72+
//
73+
// https://github.com/rust-lang/cargo/issues/11138
74+
// https://github.com/rust-lang/rust/issues/114839
75+
//
76+
// Let's just not use nightly features here.
77+
return false;
78+
}
79+
80+
let probe_dir = ["probe-stable", "probe"][usize::from(rustc_bootstrap)];
81+
82+
let out_dir = cargo_required_env_var_os("OUT_DIR");
83+
let out_subdir = Path::new(&out_dir).join(probe_dir);
84+
mkdir(&out_subdir);
85+
86+
let probefile = Path::new("src").join("nightly.rs");
87+
88+
let mut cmd = rustc_command();
89+
90+
if !rustc_bootstrap {
91+
cmd.env_remove("RUSTC_BOOTSTRAP");
92+
}
93+
94+
let stderr = out_subdir.join("probe-stderr");
95+
let stderr = fs::File::create(&stderr)
96+
.unwrap_or_else(|err| die!("filed to create stderr file {}: {}", stderr.display(), err));
97+
98+
cmd.stderr(stderr)
99+
.arg("--cfg=build_feature_probe")
100+
.arg("--edition=2024")
101+
.arg("--crate-name=git_remote_codecommit")
102+
.arg("--crate-type=lib")
103+
.arg("--emit=dep-info,metadata")
104+
.arg("--cap-lints=allow")
105+
.arg("--out-dir")
106+
.arg(&out_subdir)
107+
.arg(probefile);
108+
109+
if let Some(target) = std::env::var_os("TARGET") {
110+
cmd.arg("--target").arg(target);
111+
}
112+
113+
// If Cargo wants to set RUSTFLAGS, use that.
114+
if let Ok(rustflags) = std::env::var("CARGO_ENCODED_RUSTFLAGS") {
115+
for arg in rustflags.split('\x1f').filter(|s| !s.is_empty()) {
116+
cmd.arg(arg);
117+
}
118+
}
119+
120+
let debug = rustc_probe_debug();
121+
if debug {
122+
let mut msg = String::new();
123+
write_command(&mut msg, &cmd).expect("write to string does not fail");
124+
std::fs::write(out_subdir.join("probe-command"), msg)
125+
.unwrap_or_else(|err| die!("failed to write probe command: {err}"));
126+
}
127+
128+
let success = match cmd.status() {
129+
Ok(status) => status.success(),
130+
Err(_) => false,
131+
};
132+
133+
// Clean up to avoid leaving nondeterministic absolute paths in the dep-info
134+
// file in OUT_DIR, which causes nonreproducible builds in build systems
135+
// that treat the entire OUT_DIR as an artifact.
136+
if !debug {
137+
rmrf(&out_subdir);
138+
}
139+
140+
success
141+
}
142+
143+
fn mkdir(path: &Path) {
144+
match fs::create_dir_all(path) {
145+
Ok(()) => {}
146+
Err(err) if err.kind() == ErrorKind::AlreadyExists => {}
147+
Err(err) => die!("failed to create {}: {err}", path.display()),
148+
}
149+
}
150+
151+
fn rmrf(path: &Path) {
152+
match fs::remove_dir_all(path) {
153+
Ok(()) => {}
154+
Err(err) if err.kind() == ErrorKind::NotFound => {}
155+
Err(err) => die!("failed to remove {}: {err}", path.display()),
156+
}
157+
}
158+
159+
fn cargo_required_env_var_os(key: &str) -> OsString {
160+
std::env::var_os(key).unwrap_or_else(|| {
161+
die!("Environment variable ${key} is not set during execution of build script")
162+
})
163+
}
164+
165+
fn rustc_command() -> Command {
166+
let mut cmd = None;
167+
168+
if let Some(path) = std::env::var_os("RUSTC_WRAPPER") {
169+
// this is implicit, but included for debugging
170+
println!("cargo:rerun-if-env-changed=RUSTC_WRAPPER");
171+
cmd = Some(Command::new(path));
172+
}
173+
174+
if let Some(path) = std::env::var_os("RUSTC_WORKSPACE_WRAPPER") {
175+
// this is implicit, but included for debugging
176+
println!("cargo:rerun-if-env-changed=RUSTC_WORKSPACE_WRAPPER");
177+
if let Some(ref mut cmd) = cmd {
178+
cmd.arg(path);
179+
} else {
180+
cmd = Some(Command::new(path));
181+
}
182+
}
183+
184+
let path = cargo_required_env_var_os("RUSTC");
185+
if let Some(mut cmd) = cmd {
186+
cmd.arg(path);
187+
cmd
188+
} else {
189+
Command::new(path)
190+
}
191+
}
192+
193+
fn rustc_probe_debug() -> bool {
194+
fn is_falsy(mut s: OsString) -> bool {
195+
if s.len() <= 5 {
196+
s.make_ascii_lowercase();
197+
s.is_empty() || s == "0" || s == "false" || s == "no" || s == "off"
198+
} else {
199+
// otherwise it's too long to be a falsy value and a waste to lowercase
200+
false
201+
}
202+
}
203+
204+
println!("cargo:rerun-if-env-changed=RUSTC_PROBE_KEEP_PROBE");
205+
match std::env::var_os("RUSTC_PROBE_KEEP_PROBE") {
206+
Some(v) => !is_falsy(v),
207+
None => false,
208+
}
209+
}
210+
211+
fn write_command(out: &mut impl Write, cmd: &Command) -> fmt::Result {
212+
writeln!(out, "Running RUSTC command:")?;
213+
if let Some(cwd) = cmd.get_current_dir() {
214+
writeln!(out, " cwd : {}", cwd.display())?;
215+
} else if let Ok(cwd) = std::env::current_dir() {
216+
writeln!(out, " cwd : {}", cwd.display())?;
217+
} else {
218+
writeln!(out, " cwd : <unknown>")?;
219+
}
220+
221+
writeln!(out, " prog: {}", cmd.get_program().display())?;
222+
223+
let mut args = cmd.get_args();
224+
if let Some(arg) = args.next() {
225+
writeln!(out, " args: - {}", arg.display())?;
226+
for arg in args {
227+
writeln!(out, " - {}", arg.display())?;
228+
}
229+
} else {
230+
writeln!(out, " args: <none>")?;
231+
}
232+
233+
let mut envs = cmd.get_envs();
234+
if let Some((env, opt)) = envs.next() {
235+
if let Some(value) = opt {
236+
writeln!(out, " env : {}={}", env.display(), value.display())?;
237+
} else {
238+
writeln!(out, " env : {}=<removed>", env.display())?;
239+
}
240+
241+
for (env, opt) in envs {
242+
if let Some(value) = opt {
243+
writeln!(out, " {}={}", env.display(), value.display())?;
244+
} else {
245+
writeln!(out, " {}=<removed>", env.display())?;
246+
}
247+
}
248+
} else {
249+
writeln!(out, " env : <none>")?;
250+
}
251+
252+
Ok(())
253+
}

crates/git-remote-codecommit/src/credential_scope.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::time::SystemTime;
22

3-
use crate::TimestampExt;
43
use crate::SERVICE;
4+
use crate::TimestampExt;
55

66
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
77
pub struct CredentialScope<'a> {

crates/git-remote-codecommit/src/main.rs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
11
#![cfg_attr(windows, feature(windows_process_exit_code_from))]
2+
#![cfg_attr(bool_to_result, feature(bool_to_result))]
23

34
mod canonical_request;
45
mod credential_scope;
56
mod datetime;
67
mod hex;
78
mod hostname;
89
mod logging;
10+
mod nightly;
911
mod sdk_context;
1012
mod string_to_sign;
1113
mod uri;
@@ -17,8 +19,8 @@ use std::time::SystemTime;
1719

1820
use anyhow::Context;
1921
use clap::Parser;
20-
use hmac::digest::FixedOutput;
2122
use hmac::Mac;
23+
use hmac::digest::FixedOutput;
2224
use tracing::debug;
2325
use tracing::trace;
2426

@@ -293,7 +295,10 @@ mod tests {
293295

294296
let url = generate_url(SystemTime::UNIX_EPOCH, &parsed_url, None, &sdk_context);
295297

296-
assert_eq!(url, "https://ANOTREAL:19700101T000000Zf840ae3ff903ddb92c450d0e3567fe97ef4aa98bd6636905df48c3beee97d21d@git-codecommit.us-east-1.amazonaws.com/v1/repos/my-repo");
298+
assert_eq!(
299+
url,
300+
"https://ANOTREAL:19700101T000000Zf840ae3ff903ddb92c450d0e3567fe97ef4aa98bd6636905df48c3beee97d21d@git-codecommit.us-east-1.amazonaws.com/v1/repos/my-repo"
301+
);
297302
}
298303

299304
#[test]
@@ -317,7 +322,10 @@ mod tests {
317322
&sdk_context,
318323
);
319324

320-
assert_eq!(url, "https://ANOTREAL:19700101T000000Za305b3ce69941e8f0773a2257d9059df41dfc3a4d2563a42948e84ec4825ec06@localhost:8443/v1/repos/my-repo");
325+
assert_eq!(
326+
url,
327+
"https://ANOTREAL:19700101T000000Za305b3ce69941e8f0773a2257d9059df41dfc3a4d2563a42948e84ec4825ec06@localhost:8443/v1/repos/my-repo"
328+
);
321329
}
322330

323331
#[test]
@@ -336,7 +344,10 @@ mod tests {
336344

337345
let url = generate_url(SystemTime::UNIX_EPOCH, &parsed_url, None, &sdk_context);
338346

339-
assert_eq!(url, "https://ANOTREAL%25notarealsessiontoken:19700101T000000Zf840ae3ff903ddb92c450d0e3567fe97ef4aa98bd6636905df48c3beee97d21d@git-codecommit.us-east-1.amazonaws.com/v1/repos/my-repo");
347+
assert_eq!(
348+
url,
349+
"https://ANOTREAL%25notarealsessiontoken:19700101T000000Zf840ae3ff903ddb92c450d0e3567fe97ef4aa98bd6636905df48c3beee97d21d@git-codecommit.us-east-1.amazonaws.com/v1/repos/my-repo"
350+
);
340351
}
341352

342353
#[test]
@@ -360,6 +371,9 @@ mod tests {
360371
&sdk_context,
361372
);
362373

363-
assert_eq!(url, "https://ANOTREAL%25notarealsessiontoken:19700101T000000Za305b3ce69941e8f0773a2257d9059df41dfc3a4d2563a42948e84ec4825ec06@localhost:8443/v1/repos/my-repo");
374+
assert_eq!(
375+
url,
376+
"https://ANOTREAL%25notarealsessiontoken:19700101T000000Za305b3ce69941e8f0773a2257d9059df41dfc3a4d2563a42948e84ec4825ec06@localhost:8443/v1/repos/my-repo"
377+
);
364378
}
365379
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#![cfg_attr(build_feature_probe, feature(bool_to_result))]
2+
3+
#[cfg(build_feature_probe)]
4+
const _: () = {
5+
enum Void {}
6+
fn _probe() -> Result<Void, ()> {
7+
(false).ok_or(())?;
8+
unreachable!();
9+
}
10+
};
11+
12+
#[cfg(build_feature_probe)]
13+
const _: Option<&str> = option_env!("RUSTC_BOOTSTRAP");
14+
15+
#[cfg(not(bool_to_result))]
16+
pub(crate) trait BoolExt {
17+
fn ok_or<E>(self, or: E) -> Result<(), E>;
18+
}
19+
20+
#[cfg(not(bool_to_result))]
21+
impl BoolExt for bool {
22+
fn ok_or<E>(self, or: E) -> Result<(), E> {
23+
if self { Ok(()) } else { Err(or) }
24+
}
25+
}

0 commit comments

Comments
 (0)