Skip to content

Commit 3445fcb

Browse files
committed
Manifest: add top-level paths field for inclusion rules
See #14311
1 parent 04337eb commit 3445fcb

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

src/Manifest.zig

+30
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
pub const max_bytes = 10 * 1024 * 1024;
12
pub const basename = "build.zig.zon";
23
pub const Hash = std.crypto.hash.sha2.Sha256;
34

@@ -50,6 +51,7 @@ pub const multihash_len = 1 + 1 + Hash.digest_length;
5051
name: []const u8,
5152
version: std.SemanticVersion,
5253
dependencies: std.StringArrayHashMapUnmanaged(Dependency),
54+
paths: std.StringArrayHashMapUnmanaged(void),
5355

5456
errors: []ErrorMessage,
5557
arena_state: std.heap.ArenaAllocator.State,
@@ -74,11 +76,13 @@ pub fn parse(gpa: Allocator, ast: std.zig.Ast) Error!Manifest {
7476
.name = undefined,
7577
.version = undefined,
7678
.dependencies = .{},
79+
.paths = .{},
7780
.buf = .{},
7881
};
7982
defer p.buf.deinit(gpa);
8083
defer p.errors.deinit(gpa);
8184
defer p.dependencies.deinit(gpa);
85+
defer p.paths.deinit(gpa);
8286

8387
p.parseRoot(main_node_index) catch |err| switch (err) {
8488
error.ParseFailure => assert(p.errors.items.len > 0),
@@ -89,6 +93,7 @@ pub fn parse(gpa: Allocator, ast: std.zig.Ast) Error!Manifest {
8993
.name = p.name,
9094
.version = p.version,
9195
.dependencies = try p.dependencies.clone(p.arena),
96+
.paths = try p.paths.clone(p.arena),
9297
.errors = try p.arena.dupe(ErrorMessage, p.errors.items),
9398
.arena_state = arena_instance.state,
9499
};
@@ -143,6 +148,7 @@ const Parse = struct {
143148
name: []const u8,
144149
version: std.SemanticVersion,
145150
dependencies: std.StringArrayHashMapUnmanaged(Dependency),
151+
paths: std.StringArrayHashMapUnmanaged(void),
146152

147153
const InnerError = error{ ParseFailure, OutOfMemory };
148154

@@ -158,6 +164,7 @@ const Parse = struct {
158164

159165
var have_name = false;
160166
var have_version = false;
167+
var have_included_paths = false;
161168

162169
for (struct_init.ast.fields) |field_init| {
163170
const name_token = ast.firstToken(field_init) - 2;
@@ -167,6 +174,8 @@ const Parse = struct {
167174
// that is desirable on a per-field basis.
168175
if (mem.eql(u8, field_name, "dependencies")) {
169176
try parseDependencies(p, field_init);
177+
} else if (mem.eql(u8, field_name, "paths")) {
178+
try parseIncludedPaths(p, field_init);
170179
} else if (mem.eql(u8, field_name, "name")) {
171180
p.name = try parseString(p, field_init);
172181
have_name = true;
@@ -190,6 +199,10 @@ const Parse = struct {
190199
if (!have_version) {
191200
try appendError(p, main_token, "missing top-level 'version' field", .{});
192201
}
202+
203+
if (!have_included_paths) {
204+
try appendError(p, main_token, "missing top-level 'paths' field", .{});
205+
}
193206
}
194207

195208
fn parseDependencies(p: *Parse, node: Ast.Node.Index) !void {
@@ -277,6 +290,23 @@ const Parse = struct {
277290
return dep;
278291
}
279292

293+
fn parseIncludedPaths(p: *Parse, node: Ast.Node.Index) !void {
294+
const ast = p.ast;
295+
const main_tokens = ast.nodes.items(.main_token);
296+
297+
var buf: [2]Ast.Node.Index = undefined;
298+
const array_init = ast.fullArrayInit(&buf, node) orelse {
299+
const tok = main_tokens[node];
300+
return fail(p, tok, "expected paths expression to be a struct", .{});
301+
};
302+
303+
for (array_init.ast.elements) |elem_node| {
304+
const path_string = try parseString(p, elem_node);
305+
const normalized = try std.fs.path.resolve(p.arena, &.{path_string});
306+
try p.paths.put(p.gpa, normalized, {});
307+
}
308+
}
309+
280310
fn parseString(p: *Parse, node: Ast.Node.Index) ![]const u8 {
281311
const ast = p.ast;
282312
const node_tags = ast.nodes.items(.tag);

0 commit comments

Comments
 (0)