diff --git a/docs/commands/install.md b/docs/commands/install.md new file mode 100644 index 0000000000000000000000000000000000000000..b61222f7f99cb29185cc8c0f8cd3e8d225f3279c --- /dev/null +++ b/docs/commands/install.md @@ -0,0 +1,27 @@ +## `install` command + +``` +zigmod install +``` + +Installs a command from any remote compatible repository into `$HOME/.zigmod/bin/`. + +``` +zigmod install [git|hg|http] [url] +``` + +- The `git` type for [Git](https://git-scm.com/) requires having `git` in $PATH. +- The `hg` type for [Mercurial](https://www.mercurial-scm.org/) requires having `hg` in $PATH. +- The `http` type requires having `wget` and ( `tar` or `unzip` ) in `$PATH`. + +`[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). + +> 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. +> 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. + +``` +$ zigmod install git https://github.com/nektro/zigmod +debug: modpath: /home/me/.cache/zigmod/deps/git/github.com/nektro/zigmod +debug: argv: { /home/me/.local/share/zig/0.14.0/zig, build, --prefix, /home/me/.zigmod } +info: success! +``` diff --git a/docs/tutorial.md b/docs/tutorial.md index 73e450ce8e4fa3b6d068869e8c048ce689f1ae2b..13dbc858ef5212430fd3975b915c3b9949a85476 100644 --- a/docs/tutorial.md +++ b/docs/tutorial.md @@ -194,3 +194,4 @@ Given the project https://github.com/kristoff-it/bork, at the time of writing th ## Installing online programs to your local machine Adding `~/.zigmod/bin` to your `$PATH` enables you to install Zig-written command line utilities to your machine with Zigmod. +> Ref: See [`zigmod install`](commands/install.md) reference for more info. diff --git a/src/cmd/install.zig b/src/cmd/install.zig new file mode 100644 index 0000000000000000000000000000000000000000..3b79ecfd6dbe5133888ff66edb1fcbfdab2e5ea3 --- /dev/null +++ b/src/cmd/install.zig @@ -0,0 +1,85 @@ +const std = @import("std"); +const string = []const u8; +const gpa = std.heap.c_allocator; +const knownfolders = @import("known-folders"); +const extras = @import("extras"); + +const zigmod = @import("./../lib.zig"); +const u = @import("./../util/funcs.zig"); +const common = @import("./../common.zig"); + +pub fn execute(self_name: []const u8, args: [][:0]u8) !void { + _ = self_name; + + if (args.len < 2) u.fail("usage: zigmod install [git|hg|http] [url]", .{}); + + const homepath = try knownfolders.getPath(gpa, .home) orelse u.fail("failed to read HOME", .{}); + const cache = try knownfolders.getPath(gpa, .cache); + const datapath = try knownfolders.getPath(gpa, .data) orelse u.fail("failed to read XDG_DATA_HOME", .{}); + + const RemoteType = enum { + git, + hg, + http, + }; + const rty_s = args[0]; + const rty = std.meta.stringToEnum(RemoteType, rty_s) orelse u.fail("usage: zigmod install [git|hg|http] [url]", .{}); + const ty: zigmod.Dep.Type = switch (rty) { + .git => .git, + .hg => .hg, + .http => .http, + }; + const dep: zigmod.Dep = .{ + .type = ty, + .path = args[1], + .id = u.random_string(48), + .name = "(name)", + .main = "", + .version = "", + .c_include_dirs = &.{}, + .c_source_flags = &.{}, + .c_source_files = &.{}, + .only_os = &.{}, + .except_os = &.{}, + .yaml = null, + .deps = &.{}, + .keep = false, + .for_build = false, + }; + const clean_path = try dep.clean_path(gpa); + const cachepath = try std.fs.path.join(gpa, &.{ cache.?, "zigmod", "deps" }); + const modpath = try std.fs.path.join(gpa, &.{ cachepath, clean_path }); + std.log.debug("modpath: {s}", .{modpath}); + + if (!try extras.doesFolderExist(null, modpath)) { + try dep.type.pull(gpa, dep.path, modpath); + } else { + try dep.type.update(gpa, modpath, ""); + } + + const moddir = try std.fs.cwd().openDir(modpath, .{}); + const ci = @import("./ci.zig"); + try ci.do(gpa, cachepath, moddir); + + const modfile = try zigmod.ModFile.from_dir(gpa, moddir, modpath); + const zigversion_sv = modfile.min_zig_version orelse u.fail("zigmod manifest requires min_zig_version field", .{}); + const zigversion = try std.fmt.allocPrint(gpa, "{}", .{zigversion_sv}); + const zigpath = try std.fs.path.join(gpa, &.{ datapath, "zig", zigversion, "zig" }); + + // zig build + const argv: []const string = &.{ + zigpath, "build", + "--prefix", try std.fs.path.join(gpa, &.{ homepath, ".zigmod" }), + }; + std.log.debug("argv: {s}", .{argv}); + var proc = std.process.Child.init(argv, gpa); + proc.cwd = modpath; + const term = try proc.spawnAndWait(); + switch (term) { + .Exited => |v| u.assert(v == 0, "zig build failed with exit code: {d}", .{v}), + .Signal => |v| u.fail("zig build was stopped with signal: {d}", .{v}), + .Stopped => |v| u.fail("zig build was stopped with code: {d}", .{v}), + .Unknown => |v| u.fail("zig build encountered unknown: {d}", .{v}), + } + std.log.info("success!", .{}); +} diff --git a/src/lib.zig b/src/lib.zig index 8116ca41ee469c9f7f10346d3d7016088e5f2c40..2da2e07468c568ada1b6602643abc3d86d9e5055 100644 --- a/src/lib.zig +++ b/src/lib.zig @@ -14,6 +14,7 @@ pub const commands = struct { pub const license = @import("./cmd/license.zig"); pub const generate = @import("./cmd/generate.zig"); pub const explain = @import("./cmd/explain.zig"); + pub const install = @import("./cmd/install.zig"); }; pub fn init() !void { diff --git a/src/main.zig b/src/main.zig index d6b8ce6031a94b47a3511faa199f168dbe27e435..c0fbaad11e58151504333438f1df36a788cd2b66 100644 --- a/src/main.zig +++ b/src/main.zig @@ -8,6 +8,10 @@ const win32 = @import("win32"); // // +pub const std_options: std.Options = .{ + .log_level = std.log.Level.debug, +}; + pub fn main() !void { const gpa = std.heap.c_allocator;