diff --git a/fixtures/basic.zon b/fixtures/basic.zon index c9ef3ea..ec4be00 100644 --- a/fixtures/basic.zon +++ b/fixtures/basic.zon @@ -15,5 +15,15 @@ .url = "https://gist.github.com/antlilja/8372900fcc09e38d7b0b6bbaddad3904/archive/6c3321e0969ff2463f8335da5601986cf2108690.tar.gz", .hash = "1220363c7e27b2d3f39de6ff6e90f9537a0634199860fea237a55ddb1e1717f5d6a5", }, + // git+https test + .ziggy = .{ + .url = "git+https://github.com/kristoff-it/ziggy#c66f47bc632c66668d61fa06eda112b41d6e5130", + .hash = "1220115ff095a3c970cc90fce115294ba67d6fbc4927472dc856abc51e2a1a9364d7", + }, + // this has deps (github.com/zigimg/zigimg and codeberg.org/atman/zg) with no deps + .vaxis = .{ + .url = "git+https://github.com/rockorager/libvaxis#1fd920a7aea1bb040c7c028f4bbf0af2ea58e1d1", + .hash = "1220feaa655e14cbb4baf59fe746f09a17fc6949be46ad64dd5044982f4fc1bb57c7", + }, }, } diff --git a/src/Dependency.zig b/src/Dependency.zig index f3e8c4f..64ccc44 100644 --- a/src/Dependency.zig +++ b/src/Dependency.zig @@ -1,3 +1,4 @@ url: []const u8, +rev: []const u8, nix_hash: []const u8, done: bool, diff --git a/src/codegen.zig b/src/codegen.zig index 0074553..b9d6f80 100644 --- a/src/codegen.zig +++ b/src/codegen.zig @@ -11,7 +11,7 @@ pub fn write(alloc: Allocator, out: anytype, deps: StringHashMap(Dependency)) !v try out.writeAll( \\# generated by zon2nix (https://github.com/nix-community/zon2nix) \\ - \\{ linkFarm, fetchzip }: + \\{ linkFarm, fetchzip, fetchgit }: \\ \\linkFarm "zig-packages" [ \\ @@ -28,16 +28,30 @@ pub fn write(alloc: Allocator, out: anytype, deps: StringHashMap(Dependency)) !v for (entries) |entry| { const key = entry.key_ptr.*; const dep = entry.value_ptr.*; - try out.print( - \\ {{ - \\ name = "{s}"; - \\ path = fetchzip {{ - \\ url = "{s}"; - \\ hash = "{s}"; - \\ }}; - \\ }} - \\ - , .{ key, dep.url, dep.nix_hash }); + if (dep.rev.len != 0) { + try out.print( + \\ {{ + \\ name = "{s}"; + \\ path = fetchgit {{ + \\ url = "{s}"; + \\ rev = "{s}"; + \\ hash = "{s}"; + \\ }}; + \\ }} + \\ + , .{ key, dep.url, dep.rev, dep.nix_hash }); + } else { + try out.print( + \\ {{ + \\ name = "{s}"; + \\ path = fetchzip {{ + \\ url = "{s}"; + \\ hash = "{s}"; + \\ }}; + \\ }} + \\ + , .{ key, dep.url, dep.nix_hash }); + } } try out.writeAll("]\n"); diff --git a/src/fetch.zig b/src/fetch.zig index 459b461..858510d 100644 --- a/src/fetch.zig +++ b/src/fetch.zig @@ -35,7 +35,13 @@ pub fn fetch(alloc: Allocator, deps: *StringHashMap(Dependency)) !void { } var child = try alloc.create(ChildProcess); - const ref = try fmt.allocPrint(alloc, "tarball+{s}", .{dep.url}); + const ref = ref: { + if (dep.rev.len == 0) { + break :ref try fmt.allocPrint(alloc, "tarball+{s}", .{dep.url}); + } else { + break :ref try fmt.allocPrint(alloc, "git+{s}?rev={s}", .{ dep.url, dep.rev }); + } + }; const argv = &[_][]const u8{ nix, "flake", "prefetch", "--json", "--extra-experimental-features", "flakes nix-command", ref }; child.* = ChildProcess.init(argv, alloc); child.stdin_behavior = .Ignore; diff --git a/src/parse.zig b/src/parse.zig index fda3b6e..fe86368 100644 --- a/src/parse.zig +++ b/src/parse.zig @@ -32,6 +32,7 @@ pub fn parse(alloc: Allocator, deps: *StringHashMap(Dependency), file: File) !vo for (deps_init.ast.fields) |dep_idx| { var dep: Dependency = .{ .url = undefined, + .rev = undefined, .nix_hash = undefined, .done = false, }; @@ -40,14 +41,25 @@ pub fn parse(alloc: Allocator, deps: *StringHashMap(Dependency), file: File) !vo var has_hash = false; const dep_init = ast.fullStructInit(&buf, dep_idx) orelse { - return error.parseError; + std.log.warn("failed to get dependencies", .{}); + continue; }; for (dep_init.ast.fields) |dep_field_idx| { const name = try parseFieldName(alloc, ast, dep_field_idx); if (mem.eql(u8, name, "url")) { - dep.url = try parseString(alloc, ast, dep_field_idx); + const url = try parseString(alloc, ast, dep_field_idx); + if (std.mem.startsWith(u8, url, "https://")) { + dep.url = url; + } else if (std.mem.startsWith(u8, url, "git+https://")) { + const url_end = std.mem.indexOf(u8, url[0..], "#").?; + const raw_url = url[4..url_end]; + const hash_start = url_end + 1; // +1 to skip the '#' + const git_hash = url[hash_start..]; + dep.url = raw_url; + dep.rev = git_hash; + } has_url = true; } else if (mem.eql(u8, name, "hash")) { hash = try parseString(alloc, ast, dep_field_idx); @@ -84,11 +96,17 @@ test parse { var deps = StringHashMap(Dependency).init(alloc); const basic = try fs.cwd().openFile("fixtures/basic.zon", .{}); + defer basic.close(); try parse(alloc, &deps, basic); - basic.close(); - try testing.expectEqual(deps.count(), 3); + try testing.expectEqual(deps.count(), 5); try testing.expectEqualStrings(deps.get("122048992ca58a78318b6eba4f65c692564be5af3b30fbef50cd4abeda981b2e7fa5").?.url, "https://github.com/ziglibs/known-folders/archive/fa75e1bc672952efa0cf06160bbd942b47f6d59b.tar.gz"); try testing.expectEqualStrings(deps.get("122089a8247a693cad53beb161bde6c30f71376cd4298798d45b32740c3581405864").?.url, "https://github.com/ziglibs/diffz/archive/90353d401c59e2ca5ed0abe5444c29ad3d7489aa.tar.gz"); try testing.expectEqualStrings(deps.get("1220363c7e27b2d3f39de6ff6e90f9537a0634199860fea237a55ddb1e1717f5d6a5").?.url, "https://gist.github.com/antlilja/8372900fcc09e38d7b0b6bbaddad3904/archive/6c3321e0969ff2463f8335da5601986cf2108690.tar.gz"); + const ziggy = deps.get("1220115ff095a3c970cc90fce115294ba67d6fbc4927472dc856abc51e2a1a9364d7").?; + try testing.expectEqualStrings(ziggy.url, "https://github.com/kristoff-it/ziggy"); + try testing.expectEqualStrings(ziggy.rev, "c66f47bc632c66668d61fa06eda112b41d6e5130"); + const vaxis = deps.get("1220feaa655e14cbb4baf59fe746f09a17fc6949be46ad64dd5044982f4fc1bb57c7").?; + try testing.expectEqualStrings(vaxis.url, "https://github.com/rockorager/libvaxis"); + try testing.expectEqualStrings(vaxis.rev, "1fd920a7aea1bb040c7c028f4bbf0af2ea58e1d1"); }