mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-06 05:44:20 +00:00
Package.Fetch: apply inclusion rules from build.zig.zon
This commit is contained in:
parent
efbfa8ef3e
commit
4a2cf38844
2 changed files with 65 additions and 6 deletions
|
|
@ -1249,6 +1249,9 @@ fn computeHash(
|
|||
var all_files = std.ArrayList(*HashedFile).init(gpa);
|
||||
defer all_files.deinit();
|
||||
|
||||
var all_deletions = std.ArrayList(*DeletedFile).init(gpa);
|
||||
defer all_deletions.deinit();
|
||||
|
||||
var walker = try @as(fs.IterableDir, .{ .dir = tmp_directory.handle }).walk(gpa);
|
||||
defer walker.deinit();
|
||||
|
||||
|
|
@ -1267,10 +1270,25 @@ fn computeHash(
|
|||
) });
|
||||
return error.FetchFailed;
|
||||
}) |entry| {
|
||||
_ = filter; // TODO: apply filter rules here
|
||||
if (entry.kind == .directory) continue;
|
||||
|
||||
if (!filter.includePath(entry.path)) {
|
||||
// Delete instead of including in hash calculation.
|
||||
const deleted_file = try arena.create(DeletedFile);
|
||||
deleted_file.* = .{
|
||||
.fs_path = try arena.dupe(u8, entry.path),
|
||||
.failure = undefined, // to be populated by the worker
|
||||
};
|
||||
wait_group.start();
|
||||
try thread_pool.spawn(workerDeleteFile, .{
|
||||
tmp_directory.handle, deleted_file, &wait_group,
|
||||
});
|
||||
try all_deletions.append(deleted_file);
|
||||
continue;
|
||||
}
|
||||
|
||||
const kind: HashedFile.Kind = switch (entry.kind) {
|
||||
.directory => continue,
|
||||
.directory => unreachable,
|
||||
.file => .file,
|
||||
.sym_link => .sym_link,
|
||||
else => return f.fail(f.location_tok, try eb.printString(
|
||||
|
|
@ -1295,7 +1313,6 @@ fn computeHash(
|
|||
try thread_pool.spawn(workerHashFile, .{
|
||||
tmp_directory.handle, hashed_file, &wait_group,
|
||||
});
|
||||
|
||||
try all_files.append(hashed_file);
|
||||
}
|
||||
}
|
||||
|
|
@ -1315,6 +1332,17 @@ fn computeHash(
|
|||
};
|
||||
hasher.update(&hashed_file.hash);
|
||||
}
|
||||
for (all_deletions.items) |deleted_file| {
|
||||
deleted_file.failure catch |err| {
|
||||
any_failures = true;
|
||||
try eb.addRootErrorMessage(.{
|
||||
.msg = try eb.printString("failed to delete excluded path '{s}' from package: {s}", .{
|
||||
deleted_file.fs_path, @errorName(err),
|
||||
}),
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
if (any_failures) return error.FetchFailed;
|
||||
return hasher.finalResult();
|
||||
}
|
||||
|
|
@ -1324,6 +1352,11 @@ fn workerHashFile(dir: fs.Dir, hashed_file: *HashedFile, wg: *WaitGroup) void {
|
|||
hashed_file.failure = hashFileFallible(dir, hashed_file);
|
||||
}
|
||||
|
||||
fn workerDeleteFile(dir: fs.Dir, deleted_file: *DeletedFile, wg: *WaitGroup) void {
|
||||
defer wg.finish();
|
||||
deleted_file.failure = deleteFileFallible(dir, deleted_file);
|
||||
}
|
||||
|
||||
fn hashFileFallible(dir: fs.Dir, hashed_file: *HashedFile) HashedFile.Error!void {
|
||||
var buf: [8000]u8 = undefined;
|
||||
var hasher = Manifest.Hash.init(.{});
|
||||
|
|
@ -1347,6 +1380,20 @@ fn hashFileFallible(dir: fs.Dir, hashed_file: *HashedFile) HashedFile.Error!void
|
|||
hasher.final(&hashed_file.hash);
|
||||
}
|
||||
|
||||
fn deleteFileFallible(dir: fs.Dir, deleted_file: *DeletedFile) DeletedFile.Error!void {
|
||||
try dir.deleteFile(deleted_file.fs_path);
|
||||
// In case the file was the last remaining file in the parent directory, attempt to
|
||||
// remove the parent directory.
|
||||
var opt_parent = fs.path.dirname(deleted_file.fs_path);
|
||||
while (opt_parent) |parent| : (opt_parent = fs.path.dirname(parent)) {
|
||||
dir.deleteDir(parent) catch |err| switch (err) {
|
||||
error.DirNotEmpty => return,
|
||||
error.FileNotFound => return,
|
||||
else => |e| return e,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn isExecutable(file: fs.File) !bool {
|
||||
if (builtin.os.tag == .windows) {
|
||||
// TODO check the ACL on Windows.
|
||||
|
|
@ -1360,6 +1407,15 @@ fn isExecutable(file: fs.File) !bool {
|
|||
}
|
||||
}
|
||||
|
||||
const DeletedFile = struct {
|
||||
fs_path: []const u8,
|
||||
failure: Error!void,
|
||||
|
||||
const Error =
|
||||
fs.Dir.DeleteFileError ||
|
||||
fs.Dir.DeleteDirError;
|
||||
};
|
||||
|
||||
const HashedFile = struct {
|
||||
fs_path: []const u8,
|
||||
normalized_path: []const u8,
|
||||
|
|
@ -1402,7 +1458,7 @@ fn normalizePath(arena: Allocator, fs_path: []const u8) ![]const u8 {
|
|||
const Filter = struct {
|
||||
include_paths: std.StringArrayHashMapUnmanaged(void) = .{},
|
||||
|
||||
/// sub_path is relative to the tarball root.
|
||||
/// sub_path is relative to the package root.
|
||||
pub fn includePath(self: Filter, sub_path: []const u8) bool {
|
||||
if (self.include_paths.count() == 0) return true;
|
||||
if (self.include_paths.contains("")) return true;
|
||||
|
|
@ -1410,7 +1466,7 @@ const Filter = struct {
|
|||
|
||||
// Check if any included paths are parent directories of sub_path.
|
||||
var dirname = sub_path;
|
||||
while (std.fs.path.dirname(sub_path)) |next_dirname| {
|
||||
while (std.fs.path.dirname(dirname)) |next_dirname| {
|
||||
if (self.include_paths.contains(sub_path)) return true;
|
||||
dirname = next_dirname;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -318,7 +318,10 @@ const Parse = struct {
|
|||
|
||||
for (array_init.ast.elements) |elem_node| {
|
||||
const path_string = try parseString(p, elem_node);
|
||||
try p.paths.put(p.gpa, path_string, {});
|
||||
// This is normalized so that it can be used in string comparisons
|
||||
// against file system paths.
|
||||
const normalized = try std.fs.path.resolve(p.arena, &.{path_string});
|
||||
try p.paths.put(p.gpa, normalized, {});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue