Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions .github/workflows/external-build-android-aarch64.yml
Original file line number Diff line number Diff line change
Expand Up @@ -832,13 +832,21 @@ jobs:
if [ -f "$WORKSPACE_CARGO" ]; then
python3 "host-repo/scripts/patch-reqwest-tls.py" "$WORKSPACE_CARGO"
fi
python3 "host-repo/scripts/patch-cargo-lock-deps.py" "source-repo/codex-rs/Cargo.lock"
cd source-repo/codex-rs
cargo generate-lockfile
diff /tmp/cargo-lock-before.txt Cargo.lock > /tmp/cargo-lock-diff.txt || true
echo "=== Cargo.lock diff after patch (see /tmp/cargo-lock-diff.txt) ==="
wc -l /tmp/cargo-lock-diff.txt
echo "Verifying: openssl-sys should not be in dependency graph"
cargo tree --locked --target aarch64-linux-android -i openssl-sys 2>&1 | head -5 || echo "openssl-sys not found (expected)"
OUT=$(cargo tree --locked --target aarch64-linux-android -p codex-http-client -i openssl-sys \
--format "{p} FEATURES=[{f}]" 2>&1) || {
echo "ERROR: openssl-sys not found for codex-http-client after lockfile patch" >&2
exit 1
}
echo "$OUT"
echo "$OUT" | grep '^openssl-sys ' | head -1 | grep -q 'vendored' || {
echo "ERROR: openssl-sys resolved for codex-http-client WITHOUT the vendored feature" >&2
exit 1
}

- name: Diagnose openssl-sys dependency path
run: |
Expand Down
66 changes: 66 additions & 0 deletions scripts/patch-cargo-lock-deps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
#!/usr/bin/env python3
"""Directly edit Cargo.lock to add specific dependency entries without a full
`cargo generate-lockfile` re-resolve, which can drift pinned versions of
unrelated crates (e.g. rama-* alpha pins jumping to newer stable releases
that require a newer rustc than the Android build environment has).

Applies exactly two deltas needed for the Android vendored-OpenSSL patches:
- codex-http-client gains a dependency on openssl-sys
- codex-thread-store gains a dependency on libc

Each insertion requires that exactly one matching [[package]] block exists;
otherwise it fails closed (raises) rather than silently editing the wrong
block or doing nothing.
"""
import re
import sys


def insert_dependency(lockfile_text, pkg_name, pkg_version, new_dep):
block_re = re.compile(
r'(name = "' + re.escape(pkg_name) + r'"\nversion = "' + re.escape(pkg_version) + r'"\n)'
r'((?:(?!\[\[package\]\])[^\n]*\n)*?)'
r'(dependencies = \[\n)((?:\s*"[^"]+",?\n)*)(\]\n)'
)
matches = list(block_re.finditer(lockfile_text))
if len(matches) != 1:
raise ValueError(
f"expected exactly one package block for {pkg_name} {pkg_version}, found {len(matches)}"
)
match = matches[0]
deps_block = match.group(4)
dep_lines = [l for l in deps_block.split('\n') if l.strip()]
dep_names = []
for l in dep_lines:
m = re.match(r'\s*"([^"]+)",?\s*$', l)
if not m:
raise ValueError(f"unexpected dependency line format: {l!r}")
dep_names.append(m.group(1))
if new_dep in dep_names:
raise ValueError(f"dependency already present: {new_dep}")
Comment on lines +39 to +40

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Treat already-present dependencies as a no-op

When a supported upstream release already includes either Android dependency in Cargo.lock, this exception aborts the workflow even though the surrounding manifest patches explicitly treat existing dependencies as already applied. Because the workflow accepts future rust-v0.1xx releases and invokes this script unconditionally, upstreaming either fix will turn a valid lockfile into a build failure; return the unchanged lockfile when new_dep is already present while retaining the uniqueness and format checks.

Useful? React with 👍 / 👎.

sorted_names = sorted(dep_names + [new_dep])
idx = sorted_names.index(new_dep)
new_lines = dep_lines[:idx] + [f' "{new_dep}",'] + dep_lines[idx:]
new_deps_block = '\n'.join(new_lines) + '\n'
return lockfile_text[:match.start(4)] + new_deps_block + lockfile_text[match.end(4):]


def main():
if len(sys.argv) != 2:
print(f"usage: {sys.argv[0]} <path-to-Cargo.lock>", file=sys.stderr)
sys.exit(1)
path = sys.argv[1]
with open(path, 'r', encoding='utf-8') as f:
text = f.read()

text = insert_dependency(text, 'codex-http-client', '0.0.0', 'openssl-sys')
text = insert_dependency(text, 'codex-thread-store', '0.0.0', 'libc')

with open(path, 'w', encoding='utf-8') as f:
f.write(text)

print(f"Cargo.lock patched: codex-http-client+openssl-sys, codex-thread-store+libc ({path})")


if __name__ == '__main__':
main()