mirror of
https://github.com/hanzoai/dev.git
synced 2026-10-25 03:32:32 +00:00
fix(login): remove rand deprecation warnings by using rand::rng().fill_bytes()
Policy: treat warnings as failures. Switched from thread_rng() to rng() in PKCE and login state generation. Build remains clean.
This commit is contained in:
+8
-5
@@ -10,7 +10,7 @@ Usage: ./build-fast.sh [env flags]
|
||||
Environment flags:
|
||||
PROFILE=dev-fast|dev|release-prod Build profile (default: dev-fast)
|
||||
TRACE_BUILD=1 Print toolchain/env and artifact SHA
|
||||
KEEP_ENV=1 Do NOT sanitize env (use your current env)
|
||||
KEEP_ENV=0 Sanitize env for reproducible builds (default skips)
|
||||
DETERMINISTIC=1 Add -C debuginfo=0; promotes to release-prod unless DETERMINISTIC_FORCE_RELEASE=0
|
||||
DETERMINISTIC_FORCE_RELEASE=0|1 Keep dev-fast (0) or switch to release-prod (1, default)
|
||||
DETERMINISTIC_NO_UUID=1 macOS only: strip LC_UUID on final executables
|
||||
@@ -39,6 +39,9 @@ cd "${SCRIPT_DIR}/codex-rs"
|
||||
# where the parent folder may be owned by a different user.
|
||||
REPO_ROOT="${SCRIPT_DIR}"
|
||||
|
||||
# Default to preserving caller environment unless explicitly disabled
|
||||
KEEP_ENV="${KEEP_ENV:-1}"
|
||||
|
||||
# Use dev-fast profile by default for quick iteration
|
||||
# Can override with: PROFILE=release ./build-fast.sh
|
||||
PROFILE="${PROFILE:-dev-fast}"
|
||||
@@ -110,9 +113,9 @@ else
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Canonicalize build environment so everyone shares the same cache by default.
|
||||
# Set KEEP_ENV=1 to skip this sanitization.
|
||||
if [ "${KEEP_ENV:-}" != "1" ]; then
|
||||
# Canonicalize build environment only when requested.
|
||||
# Set KEEP_ENV=0 to force sanitization.
|
||||
if [ "${KEEP_ENV}" != "1" ]; then
|
||||
# Only define RUSTFLAGS via feature flags like DETERMINISTIC=1; otherwise clear.
|
||||
if [ -z "${DETERMINISTIC:-}" ]; then
|
||||
export RUSTFLAGS=""
|
||||
@@ -199,7 +202,7 @@ if [ "${TRACE_BUILD:-}" = "1" ]; then
|
||||
rustup run "$TOOLCHAIN" rustc -vV || true
|
||||
rustup run "$TOOLCHAIN" cargo -vV || true
|
||||
fi
|
||||
echo "CANONICAL_ENV_APPLIED: ${CANONICAL_ENV_APPLIED} (KEEP_ENV=${KEEP_ENV:-})"
|
||||
echo "CANONICAL_ENV_APPLIED: ${CANONICAL_ENV_APPLIED} (KEEP_ENV=${KEEP_ENV})"
|
||||
echo "Filtered env (CARGO|RUST*|PROFILE|CODE_HOME|CODEX_HOME):"
|
||||
env | egrep '^(CARGO|RUST|RUSTUP|PROFILE|CODE_HOME|CODEX_HOME)=' | sort || true
|
||||
echo "--------------------------------"
|
||||
|
||||
Generated
+2
-3
@@ -828,9 +828,8 @@ dependencies = [
|
||||
"chromiumoxide_types",
|
||||
"chrono",
|
||||
"futures",
|
||||
"image 0.25.8",
|
||||
"once_cell",
|
||||
"rand 0.8.5",
|
||||
"rand 0.9.2",
|
||||
"regex",
|
||||
"reqwest",
|
||||
"serde",
|
||||
@@ -1056,7 +1055,7 @@ dependencies = [
|
||||
"chrono",
|
||||
"codex-core",
|
||||
"codex-protocol",
|
||||
"rand 0.8.5",
|
||||
"rand 0.9.2",
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
|
||||
@@ -13,15 +13,14 @@ workspace = true
|
||||
[dependencies]
|
||||
anyhow = "1"
|
||||
async-trait = "0.1"
|
||||
base64 = "0.22"
|
||||
base64 = "0.22.1"
|
||||
bytes = "1"
|
||||
chromiumoxide = { version = "0.7", features = ["tokio-runtime"], default-features = false }
|
||||
chromiumoxide_types = "0.7"
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
futures = "0.3"
|
||||
image = "0.25"
|
||||
once_cell = "1.20"
|
||||
rand = "0.8"
|
||||
rand = "0.9"
|
||||
regex = "1"
|
||||
reqwest = { version = "0.12", default-features = false, features = ["json", "rustls-tls"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
|
||||
@@ -15,7 +15,7 @@ workspace = true
|
||||
anyhow = "1"
|
||||
askama = "0.12"
|
||||
async-channel = "2.3.1"
|
||||
base64 = "0.22"
|
||||
base64 = "0.22.1"
|
||||
bytes = "1.10.1"
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
codex-apply-patch = { path = "../apply-patch" }
|
||||
|
||||
@@ -210,38 +210,6 @@ pub async fn upsert_agent_config(
|
||||
let mut doc = match tokio::fs::read_to_string(&config_path).await {
|
||||
Ok(s) => s.parse::<DocumentMut>()?,
|
||||
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
|
||||
async fn persist_overrides_with_behavior(
|
||||
codex_home: &Path,
|
||||
profile: Option<&str>,
|
||||
overrides: &[(&[&str], Option<&str>)],
|
||||
none_behavior: NoneBehavior,
|
||||
) -> Result<()> {
|
||||
if overrides.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let should_skip = match none_behavior {
|
||||
NoneBehavior::Skip => overrides.iter().all(|(_, value)| value.is_none()),
|
||||
NoneBehavior::Remove => false,
|
||||
};
|
||||
|
||||
if should_skip {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let config_path = codex_home.join(CONFIG_TOML_FILE);
|
||||
|
||||
let read_result = tokio::fs::read_to_string(&config_path).await;
|
||||
let mut doc = match read_result {
|
||||
Ok(contents) => contents.parse::<DocumentMut>()?,
|
||||
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
|
||||
if overrides
|
||||
.iter()
|
||||
.all(|(_, value)| value.is_none() && matches!(none_behavior, NoneBehavior::Remove))
|
||||
{
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
tokio::fs::create_dir_all(codex_home).await?;
|
||||
DocumentMut::new()
|
||||
}
|
||||
@@ -338,6 +306,91 @@ async fn write_new_or_append(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
// Internal helper to support persist_* variants above.
|
||||
async fn persist_overrides_with_behavior(
|
||||
codex_home: &Path,
|
||||
profile: Option<&str>,
|
||||
overrides: &[(&[&str], Option<&str>)],
|
||||
none_behavior: NoneBehavior,
|
||||
) -> Result<()> {
|
||||
if overrides.is_empty() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let should_skip = match none_behavior {
|
||||
NoneBehavior::Skip => overrides.iter().all(|(_, value)| value.is_none()),
|
||||
NoneBehavior::Remove => false,
|
||||
};
|
||||
|
||||
if should_skip {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let config_path = codex_home.join(CONFIG_TOML_FILE);
|
||||
let read_result = tokio::fs::read_to_string(&config_path).await;
|
||||
let mut doc = match read_result {
|
||||
Ok(contents) => contents.parse::<DocumentMut>()?,
|
||||
Err(e) if e.kind() == std::io::ErrorKind::NotFound => {
|
||||
if overrides.iter().all(|(_, value)| value.is_none() && matches!(none_behavior, NoneBehavior::Remove)) {
|
||||
return Ok(());
|
||||
}
|
||||
tokio::fs::create_dir_all(codex_home).await?;
|
||||
DocumentMut::new()
|
||||
}
|
||||
Err(e) => return Err(e.into()),
|
||||
};
|
||||
|
||||
let effective_profile = if let Some(p) = profile { Some(p.to_owned()) } else { doc.get("profile").and_then(|i| i.as_str()).map(|s| s.to_string()) };
|
||||
|
||||
let mut mutated = false;
|
||||
for (segments, value) in overrides.iter().copied() {
|
||||
let mut seg_buf: Vec<&str> = Vec::new();
|
||||
let segments_to_apply: &[&str];
|
||||
if let Some(ref name) = effective_profile {
|
||||
if segments.first().copied() == Some("profiles") {
|
||||
segments_to_apply = segments;
|
||||
} else {
|
||||
seg_buf.reserve(2 + segments.len());
|
||||
seg_buf.push("profiles");
|
||||
seg_buf.push(name.as_str());
|
||||
seg_buf.extend_from_slice(segments);
|
||||
segments_to_apply = seg_buf.as_slice();
|
||||
}
|
||||
} else {
|
||||
segments_to_apply = segments;
|
||||
}
|
||||
match value {
|
||||
Some(v) => {
|
||||
let item_value = toml_edit::value(v);
|
||||
apply_toml_edit_override_segments(&mut doc, segments_to_apply, item_value);
|
||||
mutated = true;
|
||||
}
|
||||
None => {
|
||||
if matches!(none_behavior, NoneBehavior::Remove) && remove_toml_edit_segments(&mut doc, segments_to_apply) {
|
||||
mutated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !mutated { return Ok(()); }
|
||||
let tmp_file = NamedTempFile::new_in(codex_home)?;
|
||||
tokio::fs::write(tmp_file.path(), doc.to_string()).await?;
|
||||
tmp_file.persist(config_path)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn remove_toml_edit_segments(doc: &mut DocumentMut, segments: &[&str]) -> bool {
|
||||
use toml_edit::Item;
|
||||
if segments.is_empty() { return false; }
|
||||
let mut current = doc.as_table_mut();
|
||||
for seg in &segments[..segments.len() - 1] {
|
||||
let Some(item) = current.get_mut(seg) else { return false };
|
||||
match item { Item::Table(table) => { current = table; } _ => { return false; } }
|
||||
}
|
||||
current.remove(segments[segments.len() - 1]).is_some()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -7,11 +7,11 @@ version = { workspace = true }
|
||||
workspace = true
|
||||
|
||||
[dependencies]
|
||||
base64 = "0.22"
|
||||
base64 = "0.22.1"
|
||||
chrono = { version = "0.4", features = ["serde"] }
|
||||
codex-core = { path = "../core" }
|
||||
codex-protocol = { path = "../protocol" }
|
||||
rand = "0.8"
|
||||
rand = "0.9"
|
||||
reqwest = { version = "0.12", default-features = false, features = ["json", "blocking", "rustls-tls"] }
|
||||
serde = { version = "1", features = ["derive"] }
|
||||
serde_json = "1"
|
||||
|
||||
@@ -11,7 +11,7 @@ pub struct PkceCodes {
|
||||
|
||||
pub fn generate_pkce() -> PkceCodes {
|
||||
let mut bytes = [0u8; 64];
|
||||
rand::thread_rng().fill_bytes(&mut bytes);
|
||||
rand::rng().fill_bytes(&mut bytes);
|
||||
|
||||
// Verifier: URL-safe base64 without padding (43..128 chars)
|
||||
let code_verifier = base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(bytes);
|
||||
|
||||
@@ -324,7 +324,7 @@ fn build_authorize_url(
|
||||
|
||||
fn generate_state() -> String {
|
||||
let mut bytes = [0u8; 32];
|
||||
rand::thread_rng().fill_bytes(&mut bytes);
|
||||
rand::rng().fill_bytes(&mut bytes);
|
||||
base64::engine::general_purpose::URL_SAFE_NO_PAD.encode(bytes)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user