authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-05-29 03:32:40 -07:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-05-29 03:32:40 -07:00
logd4736db89908dda3f6c7c138670547f1795889f1
tree3bbcc170f1b30cd55ae95391f591d7e6197764f8
parentf35b2ecf00c0ed2b2bc8d2da8ce367765db0a2e3
signaturebadge-check Signed by SSH key SHA256:4hHJbtBRU58AYXwjL7fkz2fnQHdiye8x1QpTCQ0sHNw

cmd: add the install command


5 files changed, 118 insertions(+), 0 deletions(-)

docs/commands/install.md created+27
...@@ -0,0 +1,27 @@
1## `install` command
2
3```
4zigmod install
5```
6
7Installs a command from any remote compatible repository into `$HOME/.zigmod/bin/`.
8
9```
10zigmod install [git|hg|http] [url]
11```
12
13- The `git` type for [Git](https://git-scm.com/) requires having `git` in $PATH.
14- The `hg` type for [Mercurial](https://www.mercurial-scm.org/) requires having `hg` in $PATH.
15- The `http` type requires having `wget` and ( `tar` or `unzip` ) in `$PATH`.
16
17`[url]` may be the link to any remote repository that contains a Zig project with a `zigmod.yml` manifest. If your project currently does not have one, you may create one using [`zigmod init`](./init.md).
18
19> Note: It is known this this command will currently work best when the repository is compatible with the version of Zig that your version of Zigmod is built for.
20> At time of writing Zigmod is not currently capable of writing multiple versions of `deps.zig` but this may change as a result of the introduction of this command.
21
22```
23$ zigmod install git https://github.com/nektro/zigmod
24debug: modpath: /home/me/.cache/zigmod/deps/git/github.com/nektro/zigmod
25debug: argv: { /home/me/.local/share/zig/0.14.0/zig, build, --prefix, /home/me/.zigmod }
26info: success!
27```
docs/tutorial.md+1
...@@ -194,3 +194,4 @@ Given the project https://github.com/kristoff-it/bork, at the time of writing th...@@ -194,3 +194,4 @@ Given the project https://github.com/kristoff-it/bork, at the time of writing th
194## Installing online programs to your local machine194## Installing online programs to your local machine
195Adding `~/.zigmod/bin` to your `$PATH` enables you to install Zig-written command line utilities to your machine with Zigmod.195Adding `~/.zigmod/bin` to your `$PATH` enables you to install Zig-written command line utilities to your machine with Zigmod.
196196
197> Ref: See [`zigmod install`](commands/install.md) reference for more info.
src/cmd/install.zig created+85
...@@ -0,0 +1,85 @@
1const std = @import("std");
2const string = []const u8;
3const gpa = std.heap.c_allocator;
4const knownfolders = @import("known-folders");
5const extras = @import("extras");
6
7const zigmod = @import("./../lib.zig");
8const u = @import("./../util/funcs.zig");
9const common = @import("./../common.zig");
10
11pub fn execute(self_name: []const u8, args: [][:0]u8) !void {
12 _ = self_name;
13
14 if (args.len < 2) u.fail("usage: zigmod install [git|hg|http] [url]", .{});
15
16 const homepath = try knownfolders.getPath(gpa, .home) orelse u.fail("failed to read HOME", .{});
17 const cache = try knownfolders.getPath(gpa, .cache);
18 const datapath = try knownfolders.getPath(gpa, .data) orelse u.fail("failed to read XDG_DATA_HOME", .{});
19
20 const RemoteType = enum {
21 git,
22 hg,
23 http,
24 };
25 const rty_s = args[0];
26 const rty = std.meta.stringToEnum(RemoteType, rty_s) orelse u.fail("usage: zigmod install [git|hg|http] [url]", .{});
27 const ty: zigmod.Dep.Type = switch (rty) {
28 .git => .git,
29 .hg => .hg,
30 .http => .http,
31 };
32 const dep: zigmod.Dep = .{
33 .type = ty,
34 .path = args[1],
35 .id = u.random_string(48),
36 .name = "(name)",
37 .main = "",
38 .version = "",
39 .c_include_dirs = &.{},
40 .c_source_flags = &.{},
41 .c_source_files = &.{},
42 .only_os = &.{},
43 .except_os = &.{},
44 .yaml = null,
45 .deps = &.{},
46 .keep = false,
47 .for_build = false,
48 };
49 const clean_path = try dep.clean_path(gpa);
50 const cachepath = try std.fs.path.join(gpa, &.{ cache.?, "zigmod", "deps" });
51 const modpath = try std.fs.path.join(gpa, &.{ cachepath, clean_path });
52 std.log.debug("modpath: {s}", .{modpath});
53
54 if (!try extras.doesFolderExist(null, modpath)) {
55 try dep.type.pull(gpa, dep.path, modpath);
56 } else {
57 try dep.type.update(gpa, modpath, "");
58 }
59
60 const moddir = try std.fs.cwd().openDir(modpath, .{});
61 const ci = @import("./ci.zig");
62 try ci.do(gpa, cachepath, moddir);
63
64 const modfile = try zigmod.ModFile.from_dir(gpa, moddir, modpath);
65 const zigversion_sv = modfile.min_zig_version orelse u.fail("zigmod manifest requires min_zig_version field", .{});
66 const zigversion = try std.fmt.allocPrint(gpa, "{}", .{zigversion_sv});
67 const zigpath = try std.fs.path.join(gpa, &.{ datapath, "zig", zigversion, "zig" });
68
69 // zig build
70 const argv: []const string = &.{
71 zigpath, "build",
72 "--prefix", try std.fs.path.join(gpa, &.{ homepath, ".zigmod" }),
73 };
74 std.log.debug("argv: {s}", .{argv});
75 var proc = std.process.Child.init(argv, gpa);
76 proc.cwd = modpath;
77 const term = try proc.spawnAndWait();
78 switch (term) {
79 .Exited => |v| u.assert(v == 0, "zig build failed with exit code: {d}", .{v}),
80 .Signal => |v| u.fail("zig build was stopped with signal: {d}", .{v}),
81 .Stopped => |v| u.fail("zig build was stopped with code: {d}", .{v}),
82 .Unknown => |v| u.fail("zig build encountered unknown: {d}", .{v}),
83 }
84 std.log.info("success!", .{});
85}
src/lib.zig+1
...@@ -14,6 +14,7 @@ pub const commands = struct {...@@ -14,6 +14,7 @@ pub const commands = struct {
14 pub const license = @import("./cmd/license.zig");14 pub const license = @import("./cmd/license.zig");
15 pub const generate = @import("./cmd/generate.zig");15 pub const generate = @import("./cmd/generate.zig");
16 pub const explain = @import("./cmd/explain.zig");16 pub const explain = @import("./cmd/explain.zig");
17 pub const install = @import("./cmd/install.zig");
17};18};
1819
19pub fn init() !void {20pub fn init() !void {
src/main.zig+4
...@@ -8,6 +8,10 @@ const win32 = @import("win32");...@@ -8,6 +8,10 @@ const win32 = @import("win32");
8//8//
9//9//
1010
11pub const std_options: std.Options = .{
12 .log_level = std.log.Level.debug,
13};
14
11pub fn main() !void {15pub fn main() !void {
12 const gpa = std.heap.c_allocator;16 const gpa = std.heap.c_allocator;
1317