authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-06 17:41:29-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2023-10-08 16:54:31-07:00
log1c0d6f9c0020188326560e058baf36b8034d76e5
tree08388d23839c1461cac0da48c1fc969ffd24730d
parentd0bcc390e8f61ada470b524e3fd203c1af521a99

require inclusion directives in root manifest but not deps

see #14311

3 files changed, 24 insertions(+), 9 deletions(-)

src/Manifest.zig+13-2
...@@ -59,9 +59,13 @@ paths: std.StringArrayHashMapUnmanaged(void),...@@ -59,9 +59,13 @@ paths: std.StringArrayHashMapUnmanaged(void),
59errors: []ErrorMessage,59errors: []ErrorMessage,
60arena_state: std.heap.ArenaAllocator.State,60arena_state: std.heap.ArenaAllocator.State,
6161
62pub const ParseOptions = struct {
63 allow_missing_paths_field: bool = false,
64};
65
62pub const Error = Allocator.Error;66pub const Error = Allocator.Error;
6367
64pub fn parse(gpa: Allocator, ast: std.zig.Ast) Error!Manifest {68pub fn parse(gpa: Allocator, ast: std.zig.Ast, options: ParseOptions) Error!Manifest {
65 const node_tags = ast.nodes.items(.tag);69 const node_tags = ast.nodes.items(.tag);
66 const node_datas = ast.nodes.items(.data);70 const node_datas = ast.nodes.items(.data);
67 assert(node_tags[0] == .root);71 assert(node_tags[0] == .root);
...@@ -80,6 +84,7 @@ pub fn parse(gpa: Allocator, ast: std.zig.Ast) Error!Manifest {...@@ -80,6 +84,7 @@ pub fn parse(gpa: Allocator, ast: std.zig.Ast) Error!Manifest {
80 .version = undefined,84 .version = undefined,
81 .dependencies = .{},85 .dependencies = .{},
82 .paths = .{},86 .paths = .{},
87 .allow_missing_paths_field = options.allow_missing_paths_field,
83 .buf = .{},88 .buf = .{},
84 };89 };
85 defer p.buf.deinit(gpa);90 defer p.buf.deinit(gpa);
...@@ -152,6 +157,7 @@ const Parse = struct {...@@ -152,6 +157,7 @@ const Parse = struct {
152 version: std.SemanticVersion,157 version: std.SemanticVersion,
153 dependencies: std.StringArrayHashMapUnmanaged(Dependency),158 dependencies: std.StringArrayHashMapUnmanaged(Dependency),
154 paths: std.StringArrayHashMapUnmanaged(void),159 paths: std.StringArrayHashMapUnmanaged(void),
160 allow_missing_paths_field: bool,
155161
156 const InnerError = error{ ParseFailure, OutOfMemory };162 const InnerError = error{ ParseFailure, OutOfMemory };
157163
...@@ -178,6 +184,7 @@ const Parse = struct {...@@ -178,6 +184,7 @@ const Parse = struct {
178 if (mem.eql(u8, field_name, "dependencies")) {184 if (mem.eql(u8, field_name, "dependencies")) {
179 try parseDependencies(p, field_init);185 try parseDependencies(p, field_init);
180 } else if (mem.eql(u8, field_name, "paths")) {186 } else if (mem.eql(u8, field_name, "paths")) {
187 have_included_paths = true;
181 try parseIncludedPaths(p, field_init);188 try parseIncludedPaths(p, field_init);
182 } else if (mem.eql(u8, field_name, "name")) {189 } else if (mem.eql(u8, field_name, "name")) {
183 p.name = try parseString(p, field_init);190 p.name = try parseString(p, field_init);
...@@ -204,7 +211,11 @@ const Parse = struct {...@@ -204,7 +211,11 @@ const Parse = struct {
204 }211 }
205212
206 if (!have_included_paths) {213 if (!have_included_paths) {
207 try appendError(p, main_token, "missing top-level 'paths' field", .{});214 if (p.allow_missing_paths_field) {
215 try p.paths.put(p.gpa, "", {});
216 } else {
217 try appendError(p, main_token, "missing top-level 'paths' field", .{});
218 }
208 }219 }
209 }220 }
210221
src/Package/Fetch.zig+9-2
...@@ -38,6 +38,10 @@ job_queue: *JobQueue,...@@ -38,6 +38,10 @@ job_queue: *JobQueue,
38/// If true, don't add an error for a missing hash. This flag is not passed38/// If true, don't add an error for a missing hash. This flag is not passed
39/// down to recursive dependencies. It's intended to be used only be the CLI.39/// down to recursive dependencies. It's intended to be used only be the CLI.
40omit_missing_hash_error: bool,40omit_missing_hash_error: bool,
41/// If true, don't fail when a manifest file is missing the `paths` field,
42/// which specifies inclusion rules. This is intended to be true for the first
43/// fetch task and false for the recursive dependencies.
44allow_missing_paths_field: bool,
4145
42// Above this are fields provided as inputs to `run`.46// Above this are fields provided as inputs to `run`.
43// Below this are fields populated by `run`.47// Below this are fields populated by `run`.
...@@ -365,7 +369,9 @@ fn loadManifest(f: *Fetch, pkg_root: Package.Path) RunError!void {...@@ -365,7 +369,9 @@ fn loadManifest(f: *Fetch, pkg_root: Package.Path) RunError!void {
365 return error.FetchFailed;369 return error.FetchFailed;
366 }370 }
367371
368 f.manifest = try Manifest.parse(arena, ast.*);372 f.manifest = try Manifest.parse(arena, ast.*, .{
373 .allow_missing_paths_field = f.allow_missing_paths_field,
374 });
369 const manifest = &f.manifest.?;375 const manifest = &f.manifest.?;
370376
371 if (manifest.errors.len > 0) {377 if (manifest.errors.len > 0) {
...@@ -452,6 +458,7 @@ fn queueJobsForDeps(f: *Fetch, hash: Manifest.MultiHashHexDigest) RunError!void...@@ -452,6 +458,7 @@ fn queueJobsForDeps(f: *Fetch, hash: Manifest.MultiHashHexDigest) RunError!void
452 .prog_node = f.prog_node,458 .prog_node = f.prog_node,
453 .job_queue = f.job_queue,459 .job_queue = f.job_queue,
454 .omit_missing_hash_error = false,460 .omit_missing_hash_error = false,
461 .allow_missing_paths_field = false,
455462
456 .package_root = undefined,463 .package_root = undefined,
457 .error_bundle = undefined,464 .error_bundle = undefined,
...@@ -481,7 +488,7 @@ fn queueJobsForDeps(f: *Fetch, hash: Manifest.MultiHashHexDigest) RunError!void...@@ -481,7 +488,7 @@ fn queueJobsForDeps(f: *Fetch, hash: Manifest.MultiHashHexDigest) RunError!void
481 }488 }
482}489}
483490
484fn workerRun(f: *Fetch) void {491pub fn workerRun(f: *Fetch) void {
485 defer f.job_queue.wait_group.finish();492 defer f.job_queue.wait_group.finish();
486 run(f) catch |err| switch (err) {493 run(f) catch |err| switch (err) {
487 error.OutOfMemory => f.oom_flag = true,494 error.OutOfMemory => f.oom_flag = true,
src/main.zig+2-5
...@@ -6640,7 +6640,6 @@ fn cmdFetch(...@@ -6640,7 +6640,6 @@ fn cmdFetch(
6640 std.process.hasEnvVarConstant("ZIG_BTRFS_WORKAROUND");6640 std.process.hasEnvVarConstant("ZIG_BTRFS_WORKAROUND");
6641 var opt_path_or_url: ?[]const u8 = null;6641 var opt_path_or_url: ?[]const u8 = null;
6642 var override_global_cache_dir: ?[]const u8 = try optionalStringEnvVar(arena, "ZIG_GLOBAL_CACHE_DIR");6642 var override_global_cache_dir: ?[]const u8 = try optionalStringEnvVar(arena, "ZIG_GLOBAL_CACHE_DIR");
6643 var recursive = false;
66446643
6645 {6644 {
6646 var i: usize = 0;6645 var i: usize = 0;
...@@ -6656,9 +6655,6 @@ fn cmdFetch(...@@ -6656,9 +6655,6 @@ fn cmdFetch(
6656 i += 1;6655 i += 1;
6657 override_global_cache_dir = args[i];6656 override_global_cache_dir = args[i];
6658 continue;6657 continue;
6659 } else if (mem.eql(u8, arg, "--recursive")) {
6660 recursive = true;
6661 continue;
6662 } else {6658 } else {
6663 fatal("unrecognized parameter: '{s}'", .{arg});6659 fatal("unrecognized parameter: '{s}'", .{arg});
6664 }6660 }
...@@ -6696,7 +6692,7 @@ fn cmdFetch(...@@ -6696,7 +6692,7 @@ fn cmdFetch(
6696 .http_client = &http_client,6692 .http_client = &http_client,
6697 .thread_pool = &thread_pool,6693 .thread_pool = &thread_pool,
6698 .global_cache = global_cache_directory,6694 .global_cache = global_cache_directory,
6699 .recursive = recursive,6695 .recursive = false,
6700 .work_around_btrfs_bug = work_around_btrfs_bug,6696 .work_around_btrfs_bug = work_around_btrfs_bug,
6701 };6697 };
6702 defer job_queue.deinit();6698 defer job_queue.deinit();
...@@ -6711,6 +6707,7 @@ fn cmdFetch(...@@ -6711,6 +6707,7 @@ fn cmdFetch(
6711 .prog_node = root_prog_node,6707 .prog_node = root_prog_node,
6712 .job_queue = &job_queue,6708 .job_queue = &job_queue,
6713 .omit_missing_hash_error = true,6709 .omit_missing_hash_error = true,
6710 .allow_missing_paths_field = true,
67146711
6715 .package_root = undefined,6712 .package_root = undefined,
6716 .error_bundle = undefined,6713 .error_bundle = undefined,