authorgravatar for christofer@nolander.meChristofer Nolander <christofer@nolander.me> 2024-03-18 19:48:11+01:00
committergravatar for christofer@nolander.meChristofer Nolander <christofer@nolander.me> 2024-03-18 19:48:11+01:00
log57cfe0778c41565223ddc2abf4508a4ad43f1923
treeeb071e46f27499cdfd2290112bf5cf713eb46b21
parent8e7d9afdacef9d3a9443fc4b70cfe6aa229ecee5

`zig fetch`: resolve branch/tag names to commit SHA


2 files changed, 30 insertions(+), 2 deletions(-)

src/Package/Fetch.zig+9-1
...@@ -44,6 +44,8 @@ omit_missing_hash_error: bool,...@@ -44,6 +44,8 @@ omit_missing_hash_error: bool,
44/// which specifies inclusion rules. This is intended to be true for the first44/// which specifies inclusion rules. This is intended to be true for the first
45/// fetch task and false for the recursive dependencies.45/// fetch task and false for the recursive dependencies.
46allow_missing_paths_field: bool,46allow_missing_paths_field: bool,
47/// If true and URL points to a Git repository, will use the latest commit.
48use_latest_commit: bool,
4749
48// Above this are fields provided as inputs to `run`.50// Above this are fields provided as inputs to `run`.
49// Below this are fields populated by `run`.51// Below this are fields populated by `run`.
...@@ -59,6 +61,8 @@ actual_hash: Manifest.Digest,...@@ -59,6 +61,8 @@ actual_hash: Manifest.Digest,
59has_build_zig: bool,61has_build_zig: bool,
60/// Indicates whether the task aborted due to an out-of-memory condition.62/// Indicates whether the task aborted due to an out-of-memory condition.
61oom_flag: bool,63oom_flag: bool,
64/// If `use_latest_commit` was true, this will be the commit that was used.
65latest_commit: ?git.Oid,
6266
63// This field is used by the CLI only, untouched by this file.67// This field is used by the CLI only, untouched by this file.
6468
...@@ -687,6 +691,7 @@ fn queueJobsForDeps(f: *Fetch) RunError!void {...@@ -687,6 +691,7 @@ fn queueJobsForDeps(f: *Fetch) RunError!void {
687 .job_queue = f.job_queue,691 .job_queue = f.job_queue,
688 .omit_missing_hash_error = false,692 .omit_missing_hash_error = false,
689 .allow_missing_paths_field = true,693 .allow_missing_paths_field = true,
694 .use_latest_commit = false,
690695
691 .package_root = undefined,696 .package_root = undefined,
692 .error_bundle = undefined,697 .error_bundle = undefined,
...@@ -695,6 +700,7 @@ fn queueJobsForDeps(f: *Fetch) RunError!void {...@@ -695,6 +700,7 @@ fn queueJobsForDeps(f: *Fetch) RunError!void {
695 .actual_hash = undefined,700 .actual_hash = undefined,
696 .has_build_zig = false,701 .has_build_zig = false,
697 .oom_flag = false,702 .oom_flag = false,
703 .latest_commit = undefined,
698704
699 .module = null,705 .module = null,
700 };706 };
...@@ -987,7 +993,9 @@ fn initResource(f: *Fetch, uri: std.Uri, server_header_buffer: []u8) RunError!Re...@@ -987,7 +993,9 @@ fn initResource(f: *Fetch, uri: std.Uri, server_header_buffer: []u8) RunError!Re
987 }993 }
988 return f.fail(f.location_tok, try eb.printString("ref not found: {s}", .{want_ref}));994 return f.fail(f.location_tok, try eb.printString("ref not found: {s}", .{want_ref}));
989 };995 };
990 if (uri.fragment == null) {996 if (f.use_latest_commit) {
997 f.latest_commit = want_oid;
998 } else if (uri.fragment == null) {
991 const notes_len = 1;999 const notes_len = 1;
992 try eb.addRootErrorMessage(.{1000 try eb.addRootErrorMessage(.{
993 .msg = try eb.addString("url field is missing an explicit ref"),1001 .msg = try eb.addString("url field is missing an explicit ref"),
src/main.zig+21-1
...@@ -5098,6 +5098,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -5098,6 +5098,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
5098 .job_queue = &job_queue,5098 .job_queue = &job_queue,
5099 .omit_missing_hash_error = true,5099 .omit_missing_hash_error = true,
5100 .allow_missing_paths_field = false,5100 .allow_missing_paths_field = false,
5101 .use_latest_commit = false,
51015102
5102 .package_root = undefined,5103 .package_root = undefined,
5103 .error_bundle = undefined,5104 .error_bundle = undefined,
...@@ -5106,6 +5107,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {...@@ -5106,6 +5107,7 @@ fn cmdBuild(gpa: Allocator, arena: Allocator, args: []const []const u8) !void {
5106 .actual_hash = undefined,5107 .actual_hash = undefined,
5107 .has_build_zig = true,5108 .has_build_zig = true,
5108 .oom_flag = false,5109 .oom_flag = false,
5110 .latest_commit = undefined,
51095111
5110 .module = build_mod,5112 .module = build_mod,
5111 };5113 };
...@@ -6757,6 +6759,7 @@ const usage_fetch =...@@ -6757,6 +6759,7 @@ const usage_fetch =
6757 \\ --debug-hash Print verbose hash information to stdout6759 \\ --debug-hash Print verbose hash information to stdout
6758 \\ --save Add the fetched package to build.zig.zon6760 \\ --save Add the fetched package to build.zig.zon
6759 \\ --save=[name] Add the fetched package to build.zig.zon as name6761 \\ --save=[name] Add the fetched package to build.zig.zon as name
6762 \\ --resolve-commit Before saving, replace the name of a Git branch/tag with its commit SHA
6760 \\6763 \\
6761;6764;
67626765
...@@ -6772,6 +6775,7 @@ fn cmdFetch(...@@ -6772,6 +6775,7 @@ fn cmdFetch(
6772 var override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);6775 var override_global_cache_dir: ?[]const u8 = try EnvVar.ZIG_GLOBAL_CACHE_DIR.get(arena);
6773 var debug_hash: bool = false;6776 var debug_hash: bool = false;
6774 var save: union(enum) { no, yes, name: []const u8 } = .no;6777 var save: union(enum) { no, yes, name: []const u8 } = .no;
6778 var resolve_commit: bool = false;
67756779
6776 {6780 {
6777 var i: usize = 0;6781 var i: usize = 0;
...@@ -6792,6 +6796,8 @@ fn cmdFetch(...@@ -6792,6 +6796,8 @@ fn cmdFetch(
6792 save = .yes;6796 save = .yes;
6793 } else if (mem.startsWith(u8, arg, "--save=")) {6797 } else if (mem.startsWith(u8, arg, "--save=")) {
6794 save = .{ .name = arg["--save=".len..] };6798 save = .{ .name = arg["--save=".len..] };
6799 } else if (mem.eql(u8, arg, "--resolve-commit")) {
6800 resolve_commit = true;
6795 } else {6801 } else {
6796 fatal("unrecognized parameter: '{s}'", .{arg});6802 fatal("unrecognized parameter: '{s}'", .{arg});
6797 }6803 }
...@@ -6803,6 +6809,9 @@ fn cmdFetch(...@@ -6803,6 +6809,9 @@ fn cmdFetch(
6803 }6809 }
6804 }6810 }
68056811
6812 if (resolve_commit and save == .no)
6813 warn("'--resolve-commit' has no effect unless used with '--save'", .{});
6814
6806 const path_or_url = opt_path_or_url orelse fatal("missing url or path parameter", .{});6815 const path_or_url = opt_path_or_url orelse fatal("missing url or path parameter", .{});
68076816
6808 var thread_pool: ThreadPool = undefined;6817 var thread_pool: ThreadPool = undefined;
...@@ -6851,6 +6860,7 @@ fn cmdFetch(...@@ -6851,6 +6860,7 @@ fn cmdFetch(
6851 .job_queue = &job_queue,6860 .job_queue = &job_queue,
6852 .omit_missing_hash_error = true,6861 .omit_missing_hash_error = true,
6853 .allow_missing_paths_field = false,6862 .allow_missing_paths_field = false,
6863 .use_latest_commit = resolve_commit,
68546864
6855 .package_root = undefined,6865 .package_root = undefined,
6856 .error_bundle = undefined,6866 .error_bundle = undefined,
...@@ -6859,6 +6869,7 @@ fn cmdFetch(...@@ -6859,6 +6869,7 @@ fn cmdFetch(
6859 .actual_hash = undefined,6869 .actual_hash = undefined,
6860 .has_build_zig = false,6870 .has_build_zig = false,
6861 .oom_flag = false,6871 .oom_flag = false,
6872 .latest_commit = undefined,
68626873
6863 .module = null,6874 .module = null,
6864 };6875 };
...@@ -6915,13 +6926,22 @@ fn cmdFetch(...@@ -6915,13 +6926,22 @@ fn cmdFetch(
6915 var fixups: Ast.Fixups = .{};6926 var fixups: Ast.Fixups = .{};
6916 defer fixups.deinit(gpa);6927 defer fixups.deinit(gpa);
69176928
6929 const saved_path_or_url = if (resolve_commit) blk: {
6930 // replace the refspec with the latest commit SHA
6931 var uri = try std.Uri.parse(path_or_url);
6932 uri.fragment = try std.fmt.allocPrint(arena, "{}", .{
6933 std.fmt.fmtSliceHexLower(&fetch.latest_commit.?),
6934 });
6935 break :blk try std.fmt.allocPrint(arena, "{}", .{uri});
6936 } else path_or_url;
6937
6918 const new_node_init = try std.fmt.allocPrint(arena,6938 const new_node_init = try std.fmt.allocPrint(arena,
6919 \\.{{6939 \\.{{
6920 \\ .url = "{}",6940 \\ .url = "{}",
6921 \\ .hash = "{}",6941 \\ .hash = "{}",
6922 \\ }}6942 \\ }}
6923 , .{6943 , .{
6924 std.zig.fmtEscapes(path_or_url),6944 std.zig.fmtEscapes(saved_path_or_url),
6925 std.zig.fmtEscapes(&hex_digest),6945 std.zig.fmtEscapes(&hex_digest),
6926 });6946 });
69276947