scrub GIT_* environment variables in gitInTestRepo
This commit is contained in:
parent
fdd0c97480
commit
7f204747ad
2 changed files with 56 additions and 1 deletions
|
|
@ -1,5 +1,6 @@
|
|||
[tools]
|
||||
prek = "0.4.1"
|
||||
pre-commit = "4.6.0"
|
||||
zig = "0.16.0"
|
||||
zls = "0.16.0"
|
||||
"ubi:DonIsaac/zlint" = "0.7.9"
|
||||
|
|
|
|||
|
|
@ -672,8 +672,57 @@ test "loadFromBytes: all-empty bytes returns empty portfolio" {
|
|||
// Kept minimal (one happy-path, one missing-file case); the
|
||||
// bulk of the logic is in `loadFromBytes`, covered above.
|
||||
|
||||
/// Build an environment map from the parent process with the GIT_*
|
||||
/// variables stripped out.
|
||||
///
|
||||
/// When these tests run inside a git hook (pre-commit, prek, etc.),
|
||||
/// the hook runner sets `GIT_INDEX_FILE`, `GIT_DIR`, and
|
||||
/// `GIT_WORK_TREE` to point at the outer repo's staging state. Git
|
||||
/// inherits those env vars unconditionally - `git -C <tmpdir>`
|
||||
/// changes the CWD but does NOT clear these env vars. The result is
|
||||
/// that `git init` in our temp dir succeeds but subsequent `git
|
||||
/// add`/`git commit` operate against the OUTER repo's index, with
|
||||
/// blob references that don't exist in our temp dir's object store
|
||||
/// ("invalid object 100644 <hash> for '<outer-repo-path>'").
|
||||
///
|
||||
/// The hook runner can't fix this for us; per upstream guidance,
|
||||
/// hooks (and code shelled out by hooks) that run git against a
|
||||
/// different repo must explicitly opt out of the inherited env. See
|
||||
/// https://github.com/j178/prek/issues/1786 for the prek-specific
|
||||
/// instance and https://pre-commit.com/ for the analogous pre-commit
|
||||
/// guidance.
|
||||
fn buildScrubbedEnv(allocator: std.mem.Allocator) !std.process.Environ.Map {
|
||||
var map = try testing.environ.createMap(allocator);
|
||||
errdefer map.deinit();
|
||||
|
||||
// Strip every GIT_* variable. Iterating-while-removing isn't
|
||||
// supported on the underlying ArrayHashMap, so collect first
|
||||
// then remove. Keys are duped because `swapRemove` frees the
|
||||
// map's owned key buffer, which would otherwise leave us with
|
||||
// dangling pointers in `keys_to_remove`.
|
||||
var keys_to_remove: std.ArrayList([]u8) = .empty;
|
||||
defer {
|
||||
for (keys_to_remove.items) |k| allocator.free(k);
|
||||
keys_to_remove.deinit(allocator);
|
||||
}
|
||||
|
||||
var it = map.iterator();
|
||||
while (it.next()) |entry| {
|
||||
if (std.mem.startsWith(u8, entry.key_ptr.*, "GIT_")) {
|
||||
try keys_to_remove.append(allocator, try allocator.dupe(u8, entry.key_ptr.*));
|
||||
}
|
||||
}
|
||||
for (keys_to_remove.items) |key| _ = map.swapRemove(key);
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
/// Run a one-shot git command in `cwd` for test setup. Panics on
|
||||
/// failure — these tests can't proceed without a working repo.
|
||||
/// failure - these tests can't proceed without a working repo.
|
||||
///
|
||||
/// Uses `buildScrubbedEnv` to drop inherited `GIT_*` env vars; see
|
||||
/// that function's doc comment for why this matters under git
|
||||
/// hooks.
|
||||
fn gitInTestRepo(allocator: std.mem.Allocator, cwd: []const u8, argv: []const []const u8) !void {
|
||||
const full_argv = try allocator.alloc([]const u8, argv.len + 3);
|
||||
defer allocator.free(full_argv);
|
||||
|
|
@ -681,8 +730,13 @@ fn gitInTestRepo(allocator: std.mem.Allocator, cwd: []const u8, argv: []const []
|
|||
full_argv[1] = "-C";
|
||||
full_argv[2] = cwd;
|
||||
@memcpy(full_argv[3..], argv);
|
||||
|
||||
var env_map = try buildScrubbedEnv(allocator);
|
||||
defer env_map.deinit();
|
||||
|
||||
const result = try std.process.run(allocator, testing.io, .{
|
||||
.argv = full_argv,
|
||||
.environ_map = &env_map,
|
||||
.stdout_limit = .limited(64 * 1024),
|
||||
});
|
||||
defer allocator.free(result.stdout);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue