| ... | @@ -57,6 +57,7 @@ name: []const u8, | ... | @@ -57,6 +57,7 @@ name: []const u8, |
| 57 | version: std.SemanticVersion, | 57 | version: std.SemanticVersion, |
| 58 | dependencies: std.StringArrayHashMapUnmanaged(Dependency), | 58 | dependencies: std.StringArrayHashMapUnmanaged(Dependency), |
| 59 | paths: std.StringArrayHashMapUnmanaged(void), | 59 | paths: std.StringArrayHashMapUnmanaged(void), |
| | 60 | minimum_zig_version: ?std.SemanticVersion, |
| 60 | | 61 | |
| 61 | errors: []ErrorMessage, | 62 | errors: []ErrorMessage, |
| 62 | arena_state: std.heap.ArenaAllocator.State, | 63 | arena_state: std.heap.ArenaAllocator.State, |
| ... | @@ -87,6 +88,7 @@ pub fn parse(gpa: Allocator, ast: std.zig.Ast, options: ParseOptions) Error!Mani | ... | @@ -87,6 +88,7 @@ pub fn parse(gpa: Allocator, ast: std.zig.Ast, options: ParseOptions) Error!Mani |
| 87 | .dependencies = .{}, | 88 | .dependencies = .{}, |
| 88 | .paths = .{}, | 89 | .paths = .{}, |
| 89 | .allow_missing_paths_field = options.allow_missing_paths_field, | 90 | .allow_missing_paths_field = options.allow_missing_paths_field, |
| | 91 | .minimum_zig_version = null, |
| 90 | .buf = .{}, | 92 | .buf = .{}, |
| 91 | }; | 93 | }; |
| 92 | defer p.buf.deinit(gpa); | 94 | defer p.buf.deinit(gpa); |
| ... | @@ -104,6 +106,7 @@ pub fn parse(gpa: Allocator, ast: std.zig.Ast, options: ParseOptions) Error!Mani | ... | @@ -104,6 +106,7 @@ pub fn parse(gpa: Allocator, ast: std.zig.Ast, options: ParseOptions) Error!Mani |
| 104 | .version = p.version, | 106 | .version = p.version, |
| 105 | .dependencies = try p.dependencies.clone(p.arena), | 107 | .dependencies = try p.dependencies.clone(p.arena), |
| 106 | .paths = try p.paths.clone(p.arena), | 108 | .paths = try p.paths.clone(p.arena), |
| | 109 | .minimum_zig_version = p.minimum_zig_version, |
| 107 | .errors = try p.arena.dupe(ErrorMessage, p.errors.items), | 110 | .errors = try p.arena.dupe(ErrorMessage, p.errors.items), |
| 108 | .arena_state = arena_instance.state, | 111 | .arena_state = arena_instance.state, |
| 109 | }; | 112 | }; |
| ... | @@ -160,6 +163,7 @@ const Parse = struct { | ... | @@ -160,6 +163,7 @@ const Parse = struct { |
| 160 | dependencies: std.StringArrayHashMapUnmanaged(Dependency), | 163 | dependencies: std.StringArrayHashMapUnmanaged(Dependency), |
| 161 | paths: std.StringArrayHashMapUnmanaged(void), | 164 | paths: std.StringArrayHashMapUnmanaged(void), |
| 162 | allow_missing_paths_field: bool, | 165 | allow_missing_paths_field: bool, |
| | 166 | minimum_zig_version: ?std.SemanticVersion, |
| 163 | | 167 | |
| 164 | const InnerError = error{ ParseFailure, OutOfMemory }; | 168 | const InnerError = error{ ParseFailure, OutOfMemory }; |
| 165 | | 169 | |
| ... | @@ -198,6 +202,12 @@ const Parse = struct { | ... | @@ -198,6 +202,12 @@ const Parse = struct { |
| 198 | break :v undefined; | 202 | break :v undefined; |
| 199 | }; | 203 | }; |
| 200 | have_version = true; | 204 | have_version = true; |
| | 205 | } else if (mem.eql(u8, field_name, "minimum_zig_version")) { |
| | 206 | const version_text = try parseString(p, field_init); |
| | 207 | p.minimum_zig_version = std.SemanticVersion.parse(version_text) catch |err| v: { |
| | 208 | try appendError(p, main_tokens[field_init], "unable to parse semantic version: {s}", .{@errorName(err)}); |
| | 209 | break :v null; |
| | 210 | }; |
| 201 | } else { | 211 | } else { |
| 202 | // Ignore unknown fields so that we can add fields in future zig | 212 | // Ignore unknown fields so that we can add fields in future zig |
| 203 | // versions without breaking older zig versions. | 213 | // versions without breaking older zig versions. |
| ... | @@ -528,6 +538,7 @@ test "basic" { | ... | @@ -528,6 +538,7 @@ test "basic" { |
| 528 | \\.{ | 538 | \\.{ |
| 529 | \\ .name = "foo", | 539 | \\ .name = "foo", |
| 530 | \\ .version = "3.2.1", | 540 | \\ .version = "3.2.1", |
| | 541 | \\ .paths = .{""}, |
| 531 | \\ .dependencies = .{ | 542 | \\ .dependencies = .{ |
| 532 | \\ .bar = .{ | 543 | \\ .bar = .{ |
| 533 | \\ .url = "https://example.com/baz.tar.gz", | 544 | \\ .url = "https://example.com/baz.tar.gz", |
| ... | @@ -542,9 +553,10 @@ test "basic" { | ... | @@ -542,9 +553,10 @@ test "basic" { |
| 542 | | 553 | |
| 543 | try testing.expect(ast.errors.len == 0); | 554 | try testing.expect(ast.errors.len == 0); |
| 544 | | 555 | |
| 545 | var manifest = try Manifest.parse(gpa, ast); | 556 | var manifest = try Manifest.parse(gpa, ast, .{}); |
| 546 | defer manifest.deinit(gpa); | 557 | defer manifest.deinit(gpa); |
| 547 | | 558 | |
| | 559 | try testing.expect(manifest.errors.len == 0); |
| 548 | try testing.expectEqualStrings("foo", manifest.name); | 560 | try testing.expectEqualStrings("foo", manifest.name); |
| 549 | | 561 | |
| 550 | try testing.expectEqual(@as(std.SemanticVersion, .{ | 562 | try testing.expectEqual(@as(std.SemanticVersion, .{ |
| ... | @@ -557,10 +569,70 @@ test "basic" { | ... | @@ -557,10 +569,70 @@ test "basic" { |
| 557 | try testing.expectEqualStrings("bar", manifest.dependencies.keys()[0]); | 569 | try testing.expectEqualStrings("bar", manifest.dependencies.keys()[0]); |
| 558 | try testing.expectEqualStrings( | 570 | try testing.expectEqualStrings( |
| 559 | "https://example.com/baz.tar.gz", | 571 | "https://example.com/baz.tar.gz", |
| 560 | manifest.dependencies.values()[0].url, | 572 | manifest.dependencies.values()[0].location.url, |
| 561 | ); | 573 | ); |
| 562 | try testing.expectEqualStrings( | 574 | try testing.expectEqualStrings( |
| 563 | "1220f1b680b6065fcfc94fe777f22e73bcb7e2767e5f4d99d4255fe76ded69c7a35f", | 575 | "1220f1b680b6065fcfc94fe777f22e73bcb7e2767e5f4d99d4255fe76ded69c7a35f", |
| 564 | manifest.dependencies.values()[0].hash orelse return error.TestFailed, | 576 | manifest.dependencies.values()[0].hash orelse return error.TestFailed, |
| 565 | ); | 577 | ); |
| | 578 | |
| | 579 | try testing.expect(manifest.minimum_zig_version == null); |
| | 580 | } |
| | 581 | |
| | 582 | test "minimum_zig_version" { |
| | 583 | const gpa = testing.allocator; |
| | 584 | |
| | 585 | const example = |
| | 586 | \\.{ |
| | 587 | \\ .name = "foo", |
| | 588 | \\ .version = "3.2.1", |
| | 589 | \\ .paths = .{""}, |
| | 590 | \\ .minimum_zig_version = "0.11.1", |
| | 591 | \\} |
| | 592 | ; |
| | 593 | |
| | 594 | var ast = try std.zig.Ast.parse(gpa, example, .zon); |
| | 595 | defer ast.deinit(gpa); |
| | 596 | |
| | 597 | try testing.expect(ast.errors.len == 0); |
| | 598 | |
| | 599 | var manifest = try Manifest.parse(gpa, ast, .{}); |
| | 600 | defer manifest.deinit(gpa); |
| | 601 | |
| | 602 | try testing.expect(manifest.errors.len == 0); |
| | 603 | try testing.expect(manifest.dependencies.count() == 0); |
| | 604 | |
| | 605 | try testing.expect(manifest.minimum_zig_version != null); |
| | 606 | |
| | 607 | try testing.expectEqual(@as(std.SemanticVersion, .{ |
| | 608 | .major = 0, |
| | 609 | .minor = 11, |
| | 610 | .patch = 1, |
| | 611 | }), manifest.minimum_zig_version.?); |
| | 612 | } |
| | 613 | |
| | 614 | test "minimum_zig_version - invalid version" { |
| | 615 | const gpa = testing.allocator; |
| | 616 | |
| | 617 | const example = |
| | 618 | \\.{ |
| | 619 | \\ .name = "foo", |
| | 620 | \\ .version = "3.2.1", |
| | 621 | \\ .minimum_zig_version = "X.11.1", |
| | 622 | \\ .paths = .{""}, |
| | 623 | \\} |
| | 624 | ; |
| | 625 | |
| | 626 | var ast = try std.zig.Ast.parse(gpa, example, .zon); |
| | 627 | defer ast.deinit(gpa); |
| | 628 | |
| | 629 | try testing.expect(ast.errors.len == 0); |
| | 630 | |
| | 631 | var manifest = try Manifest.parse(gpa, ast, .{}); |
| | 632 | defer manifest.deinit(gpa); |
| | 633 | |
| | 634 | try testing.expect(manifest.errors.len == 1); |
| | 635 | try testing.expect(manifest.dependencies.count() == 0); |
| | 636 | |
| | 637 | try testing.expect(manifest.minimum_zig_version == null); |
| 566 | } | 638 | } |