From 72105b7cc5052fa63e544b9f76902c083523349f Mon Sep 17 00:00:00 2001 From: Meghan Date: Sat, 14 Nov 2020 14:02:34 -0800 Subject: [PATCH] zig: add cmd_fetch --- .gitmodules | 3 ++ build.zig | 2 + src/cmd_fetch.zig | 92 ++++++++++++++++++++++++++++++++++++++++++++++ src/main.zig | 1 + src/util/dep.zig | 10 +++++ src/util/funcs.zig | 45 +++++++++++++++++++++++ 6 files changed, 153 insertions(+) create mode 100644 src/cmd_fetch.zig diff --git a/.gitmodules b/.gitmodules index 14062d542bba6f8abe61e8e394b1e1f12930d96b..7238731c3d220d78f1ccf65f9641e767e7b8b4cc 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "libs/yaml"] path = libs/yaml url = https://github.com/yaml/libyaml +[submodule "libs/zig-known-folders"] + path = libs/zig-known-folders + url = https://github.com/ziglibs/known-folders diff --git a/build.zig b/build.zig index 95cd3df40b747d865dac5f6b5a4810736c53b848..7885db28b8dae1148812daf926e7ebfe65a97e26 100644 --- a/build.zig +++ b/build.zig @@ -22,6 +22,8 @@ pub fn build(b: *Builder) void { exe.addIncludeDir("./libs/yaml/include"); exe.linkSystemLibrary("yaml"); + exe.addPackagePath("known-folders", "./libs/zig-known-folders/known-folders.zig"); + exe.install(); const run_cmd = exe.run(); diff --git a/src/cmd_fetch.zig b/src/cmd_fetch.zig new file mode 100644 index 0000000000000000000000000000000000000000..fb4ec864701b05085efb3b3c2a1d768d1c5ce287 --- /dev/null +++ b/src/cmd_fetch.zig @@ -0,0 +1,92 @@ +const std = @import("std"); +const gpa = std.heap.c_allocator; + +const known_folders = @import("known-folders"); +const u = @import("./util/index.zig"); + +// +// + +pub fn execute(args: [][]u8) !void { + // + const home = try known_folders.getPath(gpa, .home); + const dir = try std.fmt.allocPrint(gpa, "{}{}", .{home, "/.cache/zigmod/deps"}); + + try fetch_deps(dir, "./zig.mod"); + + // + const f = try std.fs.cwd().createFile("./deps.zig", .{}); + defer f.close(); + + const w = f.writer(); + try w.print("const std = @import(\"std\");\n", .{}); + try w.print("const Pkg = std.build.Pkg;\n", .{}); + try w.print("\n", .{}); + try w.print("const home = \"{}\";\n", .{home}); + try w.print("const cache = home ++ \"/.cache/zigmod/deps\";\n", .{}); + try w.print("\n", .{}); + try w.print("pub const packages = ", .{}); + try print_deps(w, dir, try u.ModFile.init(gpa, "./zig.mod"), 0); + try w.print(";\n", .{}); +} + +fn fetch_deps(dir: []const u8, mpath: []const u8) anyerror!void { + const m = try u.ModFile.init(gpa, mpath); + for (m.deps) |d| { + const p = try std.fmt.allocPrint(gpa, "{}{}{}", .{dir, "/", try d.clean_path()}); + switch (d.type) { + .git => { + u.print("fetch: {}: {}: {}", .{m.name, @tagName(d.type), d.path}); + if (!try u.does_file_exist(p)) { + try run_cmd(null, &[_][]const u8{"git", "clone", d.path, p}); + } + else { + try run_cmd(p, &[_][]const u8{"git", "fetch"}); + try run_cmd(p, &[_][]const u8{"git", "pull"}); + } + }, + else => { + std.debug.panic("fetch: unhandled dep type: {}\n", .{@tagName(d.type)}); + } + } + switch (d.type) { + else => { + try fetch_deps(dir, try std.fmt.allocPrint(gpa, "{}{}", .{p, "/zig.mod"})); + }, + } + } +} + +fn run_cmd(dir: ?[]const u8, args: []const []const u8) !void { + _ = std.ChildProcess.exec(.{ .allocator = gpa, .cwd = dir, .argv = args, }) catch |e| switch(e) { + error.FileNotFound => { + u.assert(false, "\"{}\" command not found", .{args[0]}); + }, + else => return e, + }; +} + +fn print_deps(w: std.fs.File.Writer, dir: []const u8, m: u.ModFile, tabs: i32) anyerror!void { + if (m.deps.len == 0) { + try w.print("null", .{}); + return; + } + try u.print_all(w, .{"&[_]Pkg{"}, true); + const t = " "; + const r = try u.repeat(t, tabs); + for (m.deps) |d| { + const dcpath = try d.clean_path(); + const p = try u.concat(&[_][]const u8{dir, "/", dcpath}); + const np = try u.concat(&[_][]const u8{p, "/zig.mod"}); + const n = try u.ModFile.init(gpa, np); + + try w.print("{}\n", .{try u.concat(&[_][]const u8{r,t,"Pkg{"})}); + try w.print("{}\n", .{try u.concat(&[_][]const u8{r,t,t,".name = \"",n.name,"\","})}); + try w.print("{}\n", .{try u.concat(&[_][]const u8{r,t,t,".path = cache ++ \"/",dcpath,"/",n.main,"\","})}); + try w.print("{}", .{try u.concat(&[_][]const u8{r,t,t,".dependencies = "})}); + try print_deps(w, dir, n, tabs+2); + try w.print("{}\n", .{","}); + try w.print("{}\n", .{try u.concat(&[_][]const u8{r,t,"},"})}); + } + try w.print("{}", .{try u.concat(&[_][]const u8{r,"}"})}); +} diff --git a/src/main.zig b/src/main.zig index 692edfa82689cdf95bc02fdbc8b989bcec9f7e7e..b7652a2d7c528c7fa0d2d1b25cc5fe83f22b437b 100644 --- a/src/main.zig +++ b/src/main.zig @@ -9,6 +9,7 @@ const u = @import("./util/index.zig"); const commands = struct { const init = @import("./cmd_init.zig"); const add = @import("./cmd_add.zig"); + const fetch = @import("./cmd_fetch.zig"); }; pub fn main() !void { diff --git a/src/util/dep.zig b/src/util/dep.zig index 8c586ef6a88aa0507002797d4042824138850b9f..7bd70262ddaa99d6f0606a56a3ceb9dbfe4a044f 100644 --- a/src/util/dep.zig +++ b/src/util/dep.zig @@ -1,4 +1,5 @@ const std = @import("std"); +const gpa = std.heap.c_allocator; const u = @import("index.zig"); @@ -10,4 +11,13 @@ pub const Dep = struct { type: u.DepType, path: []const u8, + + pub fn clean_path(self: Dep) ![]const u8 { + var p = self.path; + p = u.trim_prefix(p, "https://"); + p = u.trim_prefix(p, "https://"); + p = u.trim_suffix(u8, p, ".git"); + p = try std.fmt.allocPrint(gpa, "{}{}{}", .{@tagName(self.type), "/", p}); + return p; + } }; diff --git a/src/util/funcs.zig b/src/util/funcs.zig index 20f688a754a0a98ae3ec1aaf6fc26051a275b3fe..05d82bff573d2913dde7a1359229674e9b394819 100644 --- a/src/util/funcs.zig +++ b/src/util/funcs.zig @@ -58,3 +58,48 @@ pub fn _join(comptime delim: []const u8, comptime xs: [][]const u8) []const u8 { } return buf; } + +pub fn trim_suffix(comptime T: type, in: []const T, suffix: []const T) []const T { + if (std.mem.endsWith(T, in, suffix)) { + return in[0..in.len-suffix.len]; + } + return in; +} + +pub fn repeat(s: []const u8, times: i32) ![]const u8 { + const list = &std.ArrayList([]const u8).init(gpa); + var i: i32 = 0; + while (i < times) : (i += 1) { + try list.append(s); + } + return join(list.items, ""); +} + +pub fn join(xs: [][]const u8, delim: []const u8) ![]const u8 { + var res: []const u8 = ""; + for (xs) |x, i| { + res = try std.fmt.allocPrint(gpa, "{}{}{}", .{res, x, if (i < xs.len-1) delim else ""}); + } + return res; +} + +pub fn concat(items: [][]const u8) ![]const u8 { + var buf: []const u8 = ""; + for (items) |x| { + buf = try std.fmt.allocPrint(gpa, "{}{}", .{buf, x}); + } + return buf; +} + +pub fn print_all(w: std.fs.File.Writer, items: anytype, ln: bool) !void { + inline for (items) |x, i| { + if (i == 0) { + try w.print("{}", .{x}); + } else { + try w.print(" {}", .{x}); + } + } + if (ln) { + try w.print("\n", .{}); + } +} -- 2.54.0