diff options
Diffstat (limited to 'tools/embed_zig_sources.zig')
| -rw-r--r-- | tools/embed_zig_sources.zig | 75 |
1 files changed, 55 insertions, 20 deletions
diff --git a/tools/embed_zig_sources.zig b/tools/embed_zig_sources.zig index a832798c..61427415 100644 --- a/tools/embed_zig_sources.zig +++ b/tools/embed_zig_sources.zig @@ -13,15 +13,12 @@ pub fn main(init: std.process.Init) !void { const root = args[1]; const output_path = args[2]; - var paths: std.ArrayList([]const u8) = .empty; + const paths = (try gitTrackedZigFiles(gpa, io, root)) orelse try walkedZigFiles(gpa, io, root); defer { - for (paths.items) |path| gpa.free(path); - paths.deinit(gpa); + for (paths) |path| gpa.free(path); + gpa.free(paths); } - - if (!try gitTrackedZigFiles(gpa, io, root, &paths)) - try walkedZigFiles(gpa, io, root, &paths); - std.mem.sort([]const u8, paths.items, {}, lessThanPath); + std.mem.sort([]const u8, paths, {}, lessThanPath); var generated: std.Io.Writer.Allocating = .init(gpa); defer generated.deinit(); @@ -32,7 +29,7 @@ pub fn main(init: std.process.Init) !void { \\ ); - for (paths.items) |path| { + for (paths) |path| { const full_path = try std.Io.Dir.path.join(gpa, &.{ root, path }); defer gpa.free(full_path); const contents = try std.Io.Dir.cwd().readFileAlloc(io, full_path, gpa, .limited(64 * 1024 * 1024)); @@ -52,40 +49,75 @@ pub fn main(init: std.process.Init) !void { try output.writeStreamingAll(io, generated.written()); } -/// Returns true only when Git ran successfully. The working-tree contents are -/// read later; Git supplies the tracked path filter, not historical blobs. +/// Returns null only when Git cannot supply the tracked-file list. Working-tree +/// contents are read later; Git supplies the path filter, not historical blobs. fn gitTrackedZigFiles( gpa: std.mem.Allocator, io: std.Io, root: []const u8, - paths: *std.ArrayList([]const u8), -) !bool { +) !?[][]const u8 { const result = std.process.run(gpa, io, .{ .argv = &.{ "git", "-C", root, "ls-files", "-z", "--", "*.zig" }, .stdout_limit = .limited(16 * 1024 * 1024), .stderr_limit = .limited(1024 * 1024), - }) catch return false; + }) catch return null; defer gpa.free(result.stdout); defer gpa.free(result.stderr); switch (result.term) { - .exited => |code| if (code != 0) return false, - else => return false, + .exited => |code| if (code != 0) return null, + else => return null, + } + + var count: usize = 0; + var count_it = std.mem.splitScalar(u8, result.stdout, 0); + while (count_it.next()) |raw_path| { + if (raw_path.len == 0 or !std.mem.endsWith(u8, raw_path, ".zig")) continue; + count += 1; } + const paths = try gpa.alloc([]const u8, count); + errdefer gpa.free(paths); + var index: usize = 0; + errdefer for (paths[0..index]) |path| gpa.free(path); var it = std.mem.splitScalar(u8, result.stdout, 0); while (it.next()) |raw_path| { if (raw_path.len == 0 or !std.mem.endsWith(u8, raw_path, ".zig")) continue; - try paths.append(gpa, try normalizedPath(gpa, raw_path)); + paths[index] = try normalizedPath(gpa, raw_path); + index += 1; } - return true; + std.debug.assert(index == paths.len); + return paths; } fn walkedZigFiles( gpa: std.mem.Allocator, io: std.Io, root: []const u8, - paths: *std.ArrayList([]const u8), -) !void { +) ![][]const u8 { + var count: usize = 0; + { + var dir = if (std.Io.Dir.path.isAbsolute(root)) + try std.Io.Dir.openDirAbsolute(io, root, .{ .iterate = true }) + else + try std.Io.Dir.cwd().openDir(io, root, .{ .iterate = true }); + defer dir.close(io); + var walker = try dir.walk(gpa); + defer walker.deinit(); + + while (try walker.next(io)) |entry| { + if (entry.kind == .directory and ignoredFallbackDir(entry.path)) { + walker.leave(io); + continue; + } + if ((entry.kind != .file and entry.kind != .sym_link) or !std.mem.endsWith(u8, entry.path, ".zig")) continue; + count += 1; + } + } + + const paths = try gpa.alloc([]const u8, count); + errdefer gpa.free(paths); + var index: usize = 0; + errdefer for (paths[0..index]) |path| gpa.free(path); var dir = if (std.Io.Dir.path.isAbsolute(root)) try std.Io.Dir.openDirAbsolute(io, root, .{ .iterate = true }) else @@ -100,8 +132,11 @@ fn walkedZigFiles( continue; } if ((entry.kind != .file and entry.kind != .sym_link) or !std.mem.endsWith(u8, entry.path, ".zig")) continue; - try paths.append(gpa, try normalizedPath(gpa, entry.path)); + paths[index] = try normalizedPath(gpa, entry.path); + index += 1; } + std.debug.assert(index == paths.len); + return paths; } fn ignoredFallbackDir(path: []const u8) bool { |
