Skip to content

Commit c4d6c64

Browse files
committed
copy paths filter from zig
1 parent 93f36ce commit c4d6c64

1 file changed

Lines changed: 39 additions & 5 deletions

File tree

src/pkg-targz.zig

Lines changed: 39 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,11 +282,11 @@ pub fn process(opt: Options) !void {
282282
if (manifest) |mani| {
283283
if (std.mem.eql(u8, entry.path, "build.zig.zon")) break :include_entry;
284284
if (mani.paths) |paths| {
285-
for (paths) |p| {
286-
if (std.mem.startsWith(u8, entry.path, p)) {
287-
break :include_entry;
288-
}
289-
}
285+
var filter: Filter = .{
286+
.include_paths = paths,
287+
};
288+
289+
if (filter.includePath(entry.path)) break :include_entry;
290290
} else {
291291
for (default_ignores) |ignore| {
292292
if (std.mem.indexOf(u8, entry.path, ignore)) |_| {
@@ -350,3 +350,37 @@ pub fn writeTarEntry(arc: *std.tar.Writer, entry: *std.fs.Dir.Walker.Entry) !voi
350350
else => return,
351351
}
352352
}
353+
354+
/// exact same logic zig uses for the `paths` manifest field.
355+
/// except we use a []const []const u8 instead of a hashmap
356+
const Filter = struct {
357+
include_paths: []const []const u8,
358+
/// sub_path is relative to the package root.
359+
pub fn includePath(self: Filter, sub_path: []const u8) bool {
360+
if (self.include_paths.len == 0) return true;
361+
for (self.include_paths) |ip| {
362+
if (std.mem.eql(u8, ip, "")) return true;
363+
if (std.mem.eql(u8, ip, ".")) return true;
364+
if (std.mem.eql(u8, ip, sub_path)) return true;
365+
}
366+
367+
// Check if any included paths are parent directories of sub_path.
368+
var dirname = sub_path;
369+
while (std.fs.path.dirname(dirname)) |next_dirname| {
370+
for (self.include_paths) |ip| {
371+
if (std.mem.eql(u8, ip, next_dirname)) return true;
372+
}
373+
dirname = next_dirname;
374+
}
375+
376+
return false;
377+
}
378+
};
379+
380+
test "includePath" {
381+
var filter: Filter = .{
382+
.include_paths = &.{"src"},
383+
};
384+
try std.testing.expect(filter.includePath("src/core/unix/SDL_poll.c"));
385+
try std.testing.expect(!filter.includePath(".gitignore"));
386+
}

0 commit comments

Comments
 (0)