authorgravatar for hello@nektro.netMeghan <hello@nektro.net> 2020-11-14 14:02:34 -08:00
committergravatar for hello@nektro.netMeghan <hello@nektro.net> 2020-11-14 14:02:34 -08:00
log72105b7cc5052fa63e544b9f76902c083523349f
tree88187841458da1018b2531fe97e718237a9bef72
parent766af13fc830794816a9f3560e705843d0e26be7

zig: add cmd_fetch


6 files changed, 153 insertions(+), 0 deletions(-)

.gitmodules+3
...@@ -1,3 +1,6 @@...@@ -1,3 +1,6 @@
1[submodule "libs/yaml"]1[submodule "libs/yaml"]
2 path = libs/yaml2 path = libs/yaml
3 url = https://github.com/yaml/libyaml3 url = https://github.com/yaml/libyaml
4[submodule "libs/zig-known-folders"]
5 path = libs/zig-known-folders
6 url = https://github.com/ziglibs/known-folders
build.zig+2
...@@ -22,6 +22,8 @@ pub fn build(b: *Builder) void {...@@ -22,6 +22,8 @@ pub fn build(b: *Builder) void {
22 exe.addIncludeDir("./libs/yaml/include");22 exe.addIncludeDir("./libs/yaml/include");
23 exe.linkSystemLibrary("yaml");23 exe.linkSystemLibrary("yaml");
2424
25 exe.addPackagePath("known-folders", "./libs/zig-known-folders/known-folders.zig");
26
25 exe.install();27 exe.install();
2628
27 const run_cmd = exe.run();29 const run_cmd = exe.run();
src/cmd_fetch.zig created+92
...@@ -0,0 +1,92 @@
1const std = @import("std");
2const gpa = std.heap.c_allocator;
3
4const known_folders = @import("known-folders");
5const u = @import("./util/index.zig");
6
7//
8//
9
10pub 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
33fn 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
60fn 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
69fn 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}
src/main.zig+1
...@@ -9,6 +9,7 @@ const u = @import("./util/index.zig");...@@ -9,6 +9,7 @@ const u = @import("./util/index.zig");
9const commands = struct {9const commands = struct {
10 const init = @import("./cmd_init.zig");10 const init = @import("./cmd_init.zig");
11 const add = @import("./cmd_add.zig");11 const add = @import("./cmd_add.zig");
12 const fetch = @import("./cmd_fetch.zig");
12};13};
1314
14pub fn main() !void {15pub fn main() !void {
src/util/dep.zig+10
...@@ -1,4 +1,5 @@...@@ -1,4 +1,5 @@
1const std = @import("std");1const std = @import("std");
2const gpa = std.heap.c_allocator;
23
3const u = @import("index.zig");4const u = @import("index.zig");
45
...@@ -10,4 +11,13 @@ pub const Dep = struct {...@@ -10,4 +11,13 @@ pub const Dep = struct {
1011
11 type: u.DepType,12 type: u.DepType,
12 path: []const u8,13 path: []const u8,
14
15 pub fn clean_path(self: Dep) ![]const u8 {
16 var p = self.path;
17 p = u.trim_prefix(p, "https://");
18 p = u.trim_prefix(p, "https://");
19 p = u.trim_suffix(u8, p, ".git");
20 p = try std.fmt.allocPrint(gpa, "{}{}{}", .{@tagName(self.type), "/", p});
21 return p;
22 }
13};23};
src/util/funcs.zig+45
...@@ -58,3 +58,48 @@ pub fn _join(comptime delim: []const u8, comptime xs: [][]const u8) []const u8 {...@@ -58,3 +58,48 @@ pub fn _join(comptime delim: []const u8, comptime xs: [][]const u8) []const u8 {
58 }58 }
59 return buf;59 return buf;
60}60}
61
62pub fn trim_suffix(comptime T: type, in: []const T, suffix: []const T) []const T {
63 if (std.mem.endsWith(T, in, suffix)) {
64 return in[0..in.len-suffix.len];
65 }
66 return in;
67}
68
69pub fn repeat(s: []const u8, times: i32) ![]const u8 {
70 const list = &std.ArrayList([]const u8).init(gpa);
71 var i: i32 = 0;
72 while (i < times) : (i += 1) {
73 try list.append(s);
74 }
75 return join(list.items, "");
76}
77
78pub fn join(xs: [][]const u8, delim: []const u8) ![]const u8 {
79 var res: []const u8 = "";
80 for (xs) |x, i| {
81 res = try std.fmt.allocPrint(gpa, "{}{}{}", .{res, x, if (i < xs.len-1) delim else ""});
82 }
83 return res;
84}
85
86pub fn concat(items: [][]const u8) ![]const u8 {
87 var buf: []const u8 = "";
88 for (items) |x| {
89 buf = try std.fmt.allocPrint(gpa, "{}{}", .{buf, x});
90 }
91 return buf;
92}
93
94pub fn print_all(w: std.fs.File.Writer, items: anytype, ln: bool) !void {
95 inline for (items) |x, i| {
96 if (i == 0) {
97 try w.print("{}", .{x});
98 } else {
99 try w.print(" {}", .{x});
100 }
101 }
102 if (ln) {
103 try w.print("\n", .{});
104 }
105}