authorgravatar for hello@nektro.netMeghan <hello@nektro.net> 2020-11-21 16:14:03 -08:00
committergravatar for hello@nektro.netMeghan <hello@nektro.net> 2020-11-21 16:14:03 -08:00
log3067870757cf26d522e0bea5d99da52080da543e
treeefb9f48a91c79209f454cba232e66ee3990d69a8
parent266730c68904083e0b94edb86a925587b4339600

add the sum command


4 files changed, 92 insertions(+), 0 deletions(-)

README.md+8
...@@ -64,6 +64,14 @@ zigmod fetch...@@ -64,6 +64,14 @@ zigmod fetch
64- This command takes no parameters and will generate a `deps.zig` in the root of your project.64- This command takes no parameters and will generate a `deps.zig` in the root of your project.
65- `deps.zig` should not be checked into your source control.65- `deps.zig` should not be checked into your source control.
6666
67### `sum` command
68```
69zigmod sum
70```
71
72- This will generate a `zig.sum` file with the blake3 hashes of your modules.
73- Place that hash in the `hash: blake3:<hash>` property of a dependency to be able to check it with `verify`.
74
67### Adding `deps.zig` to `build.zig`75### Adding `deps.zig` to `build.zig`
68```diff76```diff
69const Builder = @import("std").build.Builder;77const Builder = @import("std").build.Builder;
src/cmd_sum.zig created+42
...@@ -0,0 +1,42 @@
1const std = @import("std");
2const gpa = std.heap.c_allocator;
3
4const known_folders = @import("known-folders");
5const u = @import("./util/index.zig");
6const common = @import("./common.zig");
7
8//
9//
10
11pub fn execute(args: [][]u8) !void {
12 //
13 const home = try known_folders.getPath(gpa, .home);
14 const dir = try std.fmt.allocPrint(gpa, "{}{}", .{home, "/.cache/zigmod"});
15 const top_module = try common.collect_deps(dir, "./zig.mod");
16
17 //
18 const f = try std.fs.cwd().createFile("./zig.sum", .{});
19 defer f.close();
20 const w = f.writer();
21
22 //
23 const module_list = &std.ArrayList(u.Module).init(gpa);
24 try dedupe_mod_list(module_list, top_module);
25
26 for (module_list.items) |m| {
27 const hash = try m.get_hash(dir);
28 try w.print("{} {}\n", .{m.clean_path, hash});
29 }
30}
31
32fn dedupe_mod_list(list: *std.ArrayList(u.Module), module: u.Module) anyerror!void {
33 if (u.list_contains_gen(u.Module, list, module)) {
34 return;
35 }
36 if (module.clean_path.len > 0) {
37 try list.append(module);
38 }
39 for (module.deps) |m| {
40 try dedupe_mod_list(list, m);
41 }
42}
src/main.zig+1
...@@ -10,6 +10,7 @@ const commands = struct {...@@ -10,6 +10,7 @@ const 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 const fetch = @import("./cmd_fetch.zig");
13 const sum = @import("./cmd_sum.zig");
13};14};
1415
15pub fn main() !void {16pub fn main() !void {
src/util/module.zig+41
...@@ -1,10 +1,15 @@...@@ -1,10 +1,15 @@
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
5//6//
6//7//
78
9const b = 1;
10const kb = b * 1024;
11const mb = kb * 1024;
12
8pub const Module = struct {13pub const Module = struct {
9 name: []const u8,14 name: []const u8,
10 main: []const u8,15 main: []const u8,
...@@ -26,4 +31,40 @@ pub const Module = struct {...@@ -26,4 +31,40 @@ pub const Module = struct {
26 .clean_path = try dep.clean_path(),31 .clean_path = try dep.clean_path(),
27 };32 };
28 }33 }
34
35 pub fn eql(self: Module, another: Module) bool {
36 return std.mem.eql(u8, self.clean_path, another.clean_path);
37 }
38
39 pub fn get_hash(self: Module, cdpath: []const u8) ![]const u8 {
40 const file_list_1 = &std.ArrayList([]const u8).init(gpa);
41 try u.file_list(try u.concat(&[_][]const u8{cdpath, "/", self.clean_path}), file_list_1);
42
43 const file_list_2 = &std.ArrayList([]const u8).init(gpa);
44 for (file_list_1.items) |item| {
45 const _a = u.trim_prefix(item, cdpath)[1..];
46 const _b = u.trim_prefix(_a, self.clean_path)[1..];
47 if (_b[0] == '.') continue;
48 try file_list_2.append(_b);
49 }
50
51 std.sort.sort([]const u8, file_list_2.items, void{}, struct {
52 pub fn lt(context: void, lhs: []const u8, rhs: []const u8) bool {
53 return std.mem.lessThan(u8, lhs, rhs);
54 }
55 }.lt);
56
57 const h = &std.crypto.hash.Blake3.init(.{});
58 for (file_list_2.items) |item| {
59 const abs_path = try u.concat(&[_][]const u8{cdpath, "/", self.clean_path, "/", item});
60 const file = try std.fs.openFileAbsolute(abs_path, .{});
61 defer file.close();
62 const input = try file.reader().readAllAlloc(gpa, mb);
63 h.update(input);
64 }
65 var out: [32]u8 = undefined;
66 h.final(&out);
67 const hex = try std.fmt.allocPrint(gpa, "{x}", .{out});
68 return hex;
69 }
29};70};