| ... | ... | @@ -0,0 +1,92 @@ |
| 1 | const std = @import("std"); |
| 2 | const gpa = std.heap.c_allocator; |
| 3 | |
| 4 | const known_folders = @import("known-folders"); |
| 5 | const u = @import("./util/index.zig"); |
| 6 | |
| 7 | // |
| 8 | // |
| 9 | |
| 10 | pub fn execute(args: [][]u8) !void { |
| 11 | // |
| 12 | const home = try known_folders.getPath(gpa, .home); |
| 13 | const dir = try std.fmt.allocPrint(gpa, "{}{}", .{home, "/.cache/zigmod/deps"}); |
| 14 | |
| 15 | try fetch_deps(dir, "./zig.mod"); |
| 16 | |
| 17 | // |
| 18 | const f = try std.fs.cwd().createFile("./deps.zig", .{}); |
| 19 | defer f.close(); |
| 20 | |
| 21 | const w = f.writer(); |
| 22 | try w.print("const std = @import(\"std\");\n", .{}); |
| 23 | try w.print("const Pkg = std.build.Pkg;\n", .{}); |
| 24 | try w.print("\n", .{}); |
| 25 | try w.print("const home = \"{}\";\n", .{home}); |
| 26 | try w.print("const cache = home ++ \"/.cache/zigmod/deps\";\n", .{}); |
| 27 | try w.print("\n", .{}); |
| 28 | try w.print("pub const packages = ", .{}); |
| 29 | try print_deps(w, dir, try u.ModFile.init(gpa, "./zig.mod"), 0); |
| 30 | try w.print(";\n", .{}); |
| 31 | } |
| 32 | |
| 33 | fn fetch_deps(dir: []const u8, mpath: []const u8) anyerror!void { |
| 34 | const m = try u.ModFile.init(gpa, mpath); |
| 35 | for (m.deps) |d| { |
| 36 | const p = try std.fmt.allocPrint(gpa, "{}{}{}", .{dir, "/", try d.clean_path()}); |
| 37 | switch (d.type) { |
| 38 | .git => { |
| 39 | u.print("fetch: {}: {}: {}", .{m.name, @tagName(d.type), d.path}); |
| 40 | if (!try u.does_file_exist(p)) { |
| 41 | try run_cmd(null, &[_][]const u8{"git", "clone", d.path, p}); |
| 42 | } |
| 43 | else { |
| 44 | try run_cmd(p, &[_][]const u8{"git", "fetch"}); |
| 45 | try run_cmd(p, &[_][]const u8{"git", "pull"}); |
| 46 | } |
| 47 | }, |
| 48 | else => { |
| 49 | std.debug.panic("fetch: unhandled dep type: {}\n", .{@tagName(d.type)}); |
| 50 | } |
| 51 | } |
| 52 | switch (d.type) { |
| 53 | else => { |
| 54 | try fetch_deps(dir, try std.fmt.allocPrint(gpa, "{}{}", .{p, "/zig.mod"})); |
| 55 | }, |
| 56 | } |
| 57 | } |
| 58 | } |
| 59 | |
| 60 | fn run_cmd(dir: ?[]const u8, args: []const []const u8) !void { |
| 61 | _ = std.ChildProcess.exec(.{ .allocator = gpa, .cwd = dir, .argv = args, }) catch |e| switch(e) { |
| 62 | error.FileNotFound => { |
| 63 | u.assert(false, "\"{}\" command not found", .{args[0]}); |
| 64 | }, |
| 65 | else => return e, |
| 66 | }; |
| 67 | } |
| 68 | |
| 69 | fn print_deps(w: std.fs.File.Writer, dir: []const u8, m: u.ModFile, tabs: i32) anyerror!void { |
| 70 | if (m.deps.len == 0) { |
| 71 | try w.print("null", .{}); |
| 72 | return; |
| 73 | } |
| 74 | try u.print_all(w, .{"&[_]Pkg{"}, true); |
| 75 | const t = " "; |
| 76 | const r = try u.repeat(t, tabs); |
| 77 | for (m.deps) |d| { |
| 78 | const dcpath = try d.clean_path(); |
| 79 | const p = try u.concat(&[_][]const u8{dir, "/", dcpath}); |
| 80 | const np = try u.concat(&[_][]const u8{p, "/zig.mod"}); |
| 81 | const n = try u.ModFile.init(gpa, np); |
| 82 | |
| 83 | try w.print("{}\n", .{try u.concat(&[_][]const u8{r,t,"Pkg{"})}); |
| 84 | try w.print("{}\n", .{try u.concat(&[_][]const u8{r,t,t,".name = \"",n.name,"\","})}); |
| 85 | try w.print("{}\n", .{try u.concat(&[_][]const u8{r,t,t,".path = cache ++ \"/",dcpath,"/",n.main,"\","})}); |
| 86 | try w.print("{}", .{try u.concat(&[_][]const u8{r,t,t,".dependencies = "})}); |
| 87 | try print_deps(w, dir, n, tabs+2); |
| 88 | try w.print("{}\n", .{","}); |
| 89 | try w.print("{}\n", .{try u.concat(&[_][]const u8{r,t,"},"})}); |
| 90 | } |
| 91 | try w.print("{}", .{try u.concat(&[_][]const u8{r,"}"})}); |
| 92 | } |