authorgravatar for christofer@nolander.meChristofer Nolander <christofer@nolander.me> 2024-03-21 07:54:08+01:00
committergravatar for christofer@nolander.meChristofer Nolander <christofer@nolander.me> 2024-03-21 07:54:08+01:00
logdcffa7b2990046926aae782819a53dcd505aa4a3
treec5b210c306d627f52ba5a373650c1d3f2a06deb5
parent57cfe0778c41565223ddc2abf4508a4ad43f1923

`zig fetch`: resolve ref to commit by default

Stores the original ref as a query parameter in the URL so that it is possible to automatically check the upstream if there are any newer commits. Also adds a flag which opts-out of the new behaivour, restoring the old.

1 files changed, 35 insertions(+), 15 deletions(-)

src/main.zig+35-15
...@@ -6759,7 +6759,7 @@ const usage_fetch =...@@ -6759,7 +6759,7 @@ const usage_fetch =
6759 \\ --debug-hash Print verbose hash information to stdout6759 \\ --debug-hash Print verbose hash information to stdout
6760 \\ --save Add the fetched package to build.zig.zon6760 \\ --save Add the fetched package to build.zig.zon
6761 \\ --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 SHA6762 \\ --preserve-url Store a verbatim copy of the URL in build.zig.zon
6763 \\6763 \\
6764;6764;
67656765
...@@ -6775,7 +6775,7 @@ fn cmdFetch(...@@ -6775,7 +6775,7 @@ fn cmdFetch(
6775 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);
6776 var debug_hash: bool = false;6776 var debug_hash: bool = false;
6777 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;6778 var preserve_url: bool = false;
67796779
6780 {6780 {
6781 var i: usize = 0;6781 var i: usize = 0;
...@@ -6796,8 +6796,8 @@ fn cmdFetch(...@@ -6796,8 +6796,8 @@ fn cmdFetch(
6796 save = .yes;6796 save = .yes;
6797 } else if (mem.startsWith(u8, arg, "--save=")) {6797 } else if (mem.startsWith(u8, arg, "--save=")) {
6798 save = .{ .name = arg["--save=".len..] };6798 save = .{ .name = arg["--save=".len..] };
6799 } else if (mem.eql(u8, arg, "--resolve-commit")) {6799 } else if (mem.startsWith(u8, arg, "--preserve-url")) {
6800 resolve_commit = true;6800 preserve_url = true;
6801 } else {6801 } else {
6802 fatal("unrecognized parameter: '{s}'", .{arg});6802 fatal("unrecognized parameter: '{s}'", .{arg});
6803 }6803 }
...@@ -6809,8 +6809,7 @@ fn cmdFetch(...@@ -6809,8 +6809,7 @@ fn cmdFetch(
6809 }6809 }
6810 }6810 }
68116811
6812 if (resolve_commit and save == .no)6812 if (preserve_url and save == .no) fatal("use of '--preserve-url' requires '--save'", .{});
6813 warn("'--resolve-commit' has no effect unless used with '--save'", .{});
68146813
6815 const path_or_url = opt_path_or_url orelse fatal("missing url or path parameter", .{});6814 const path_or_url = opt_path_or_url orelse fatal("missing url or path parameter", .{});
68166815
...@@ -6860,7 +6859,7 @@ fn cmdFetch(...@@ -6860,7 +6859,7 @@ fn cmdFetch(
6860 .job_queue = &job_queue,6859 .job_queue = &job_queue,
6861 .omit_missing_hash_error = true,6860 .omit_missing_hash_error = true,
6862 .allow_missing_paths_field = false,6861 .allow_missing_paths_field = false,
6863 .use_latest_commit = resolve_commit,6862 .use_latest_commit = true,
68646863
6865 .package_root = undefined,6864 .package_root = undefined,
6866 .error_bundle = undefined,6865 .error_bundle = undefined,
...@@ -6926,14 +6925,35 @@ fn cmdFetch(...@@ -6926,14 +6925,35 @@ fn cmdFetch(
6926 var fixups: Ast.Fixups = .{};6925 var fixups: Ast.Fixups = .{};
6927 defer fixups.deinit(gpa);6926 defer fixups.deinit(gpa);
69286927
6929 const saved_path_or_url = if (resolve_commit) blk: {6928 var saved_path_or_url = path_or_url;
6930 // replace the refspec with the latest commit SHA6929
6930 if (fetch.latest_commit) |*latest_commit| {
6931 var uri = try std.Uri.parse(path_or_url);6931 var uri = try std.Uri.parse(path_or_url);
6932 uri.fragment = try std.fmt.allocPrint(arena, "{}", .{6932 const target_ref = uri.fragment orelse "";
6933 std.fmt.fmtSliceHexLower(&fetch.latest_commit.?),6933 if (!std.mem.eql(u8, target_ref, latest_commit)) {
6934 });6934 std.log.info("resolved ref '{s}' to commit {s}", .{
6935 break :blk try std.fmt.allocPrint(arena, "{}", .{uri});6935 target_ref,
6936 } else path_or_url;6936 std.fmt.fmtSliceHexLower(latest_commit),
6937 });
6938
6939 if (!preserve_url) {
6940 if (target_ref.len != 0) {
6941 // include the target ref in a query parameter
6942 var query = try std.ArrayList(u8).initCapacity(arena, 4 + target_ref.len);
6943 try std.Uri.writeEscapedQuery(query.writer(), "ref=");
6944 try std.Uri.writeEscapedQuery(query.writer(), target_ref);
6945 uri.query = try query.toOwnedSlice();
6946 }
6947
6948 // replace the refspec with the resolved commit SHA
6949 uri.fragment = try std.fmt.allocPrint(arena, "{}", .{
6950 std.fmt.fmtSliceHexLower(latest_commit),
6951 });
6952
6953 saved_path_or_url = try std.fmt.allocPrint(arena, "{}", .{uri});
6954 }
6955 }
6956 }
69376957
6938 const new_node_init = try std.fmt.allocPrint(arena,6958 const new_node_init = try std.fmt.allocPrint(arena,
6939 \\.{{6959 \\.{{
...@@ -6961,7 +6981,7 @@ fn cmdFetch(...@@ -6961,7 +6981,7 @@ fn cmdFetch(
6961 if (dep.hash) |h| {6981 if (dep.hash) |h| {
6962 switch (dep.location) {6982 switch (dep.location) {
6963 .url => |u| {6983 .url => |u| {
6964 if (mem.eql(u8, h, &hex_digest) and mem.eql(u8, u, path_or_url)) {6984 if (mem.eql(u8, h, &hex_digest) and mem.eql(u8, u, saved_path_or_url)) {
6965 std.log.info("existing dependency named '{s}' is up-to-date", .{name});6985 std.log.info("existing dependency named '{s}' is up-to-date", .{name});
6966 process.exit(0);6986 process.exit(0);
6967 }6987 }