From 2c278b0501433da1a76e22dd42024b098b599d2c Mon Sep 17 00:00:00 2001 From: Daylin Morgan Date: Sun, 31 Mar 2024 16:40:21 -0500 Subject: [PATCH] oizys-zig because I can --- flake.lock | 63 +++++++++- flake.nix | 3 + lib/default.nix | 7 +- modules/languages/misc.nix | 1 + modules/nix.nix | 2 +- pkgs/oizys/oizys-rs/default.nix | 2 + pkgs/oizys/oizys-zig/.gitignore | 13 +++ pkgs/oizys/oizys-zig/build.zig | 36 ++++++ pkgs/oizys/oizys-zig/build.zig.zon | 11 ++ pkgs/oizys/oizys-zig/build.zig.zon2json-lock | 7 ++ pkgs/oizys/oizys-zig/default.nix | 12 ++ pkgs/oizys/oizys-zig/src/Cli.zig | 35 ++++++ pkgs/oizys/oizys-zig/src/Oizys.zig | 114 +++++++++++++++++++ pkgs/oizys/oizys-zig/src/main.zig | 22 ++++ 14 files changed, 320 insertions(+), 8 deletions(-) create mode 100644 pkgs/oizys/oizys-zig/.gitignore create mode 100644 pkgs/oizys/oizys-zig/build.zig create mode 100644 pkgs/oizys/oizys-zig/build.zig.zon create mode 100644 pkgs/oizys/oizys-zig/build.zig.zon2json-lock create mode 100644 pkgs/oizys/oizys-zig/default.nix create mode 100644 pkgs/oizys/oizys-zig/src/Cli.zig create mode 100644 pkgs/oizys/oizys-zig/src/Oizys.zig create mode 100644 pkgs/oizys/oizys-zig/src/main.zig diff --git a/flake.lock b/flake.lock index 3556822..ee402c5 100644 --- a/flake.lock +++ b/flake.lock @@ -55,6 +55,24 @@ "type": "github" } }, + "flake-utils_2": { + "inputs": { + "systems": "systems_4" + }, + "locked": { + "lastModified": 1705309234, + "narHash": "sha256-uNRRNRKmJyCRC/8y1RqBkqWBLM034y4qN7EprSdmgyA=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "1ef2e671c3b0c19053962c07dbda38332dcebf26", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, "hyprcursor": { "inputs": { "hyprlang": "hyprlang", @@ -94,11 +112,11 @@ "xdph": "xdph" }, "locked": { - "lastModified": 1711985879, - "narHash": "sha256-Gv0GD7NqsO6M4WeORRTK+LCfNjZD7LGhAZTapoZortw=", + "lastModified": 1712070655, + "narHash": "sha256-EJpuvOfX6F1Hm7SynhRFy98m0WL62abz7GAZiPalnVo=", "owner": "hyprwm", "repo": "Hyprland", - "rev": "db1506130b507f92e0daf3a36495fb985e242bbc", + "rev": "fc0a7af7ba5c52f7a70309020f5cb27c19d068e6", "type": "github" }, "original": { @@ -382,7 +400,8 @@ "nixpkgs-wayland": "nixpkgs-wayland", "pinix": "pinix", "stable": "stable", - "tsm": "tsm" + "tsm": "tsm", + "zig2nix": "zig2nix" } }, "stable": { @@ -446,6 +465,21 @@ "type": "github" } }, + "systems_4": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, "treefmt-nix": { "inputs": { "nixpkgs": [ @@ -541,6 +575,27 @@ "repo": "xdg-desktop-portal-hyprland", "type": "github" } + }, + "zig2nix": { + "inputs": { + "flake-utils": "flake-utils_2", + "nixpkgs": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1712020996, + "narHash": "sha256-MwPoFX6e87DEs93VFIYe43bpNjXz/90kvwNYjctjfwA=", + "owner": "Cloudef", + "repo": "zig2nix", + "rev": "2b33861efe56118d50bc04a2a9165e9f1f50d350", + "type": "github" + }, + "original": { + "owner": "Cloudef", + "repo": "zig2nix", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index 89a212e..a582665 100644 --- a/flake.nix +++ b/flake.nix @@ -22,6 +22,9 @@ nix-index-database.url = "github:nix-community/nix-index-database"; nix-index-database.inputs.nixpkgs.follows = "nixpkgs"; + + zig2nix.url = "github:Cloudef/zig2nix"; + zig2nix.inputs.nixpkgs.follows = "nixpkgs"; }; nixConfig = { diff --git a/lib/default.nix b/lib/default.nix index 5385591..4f31f44 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -10,7 +10,7 @@ inputs: let #supportedSystems = ["x86_64-linux" "x86_64-darwin" "aarch64-linux" "aarch64-darwin"]; supportedSystems = ["x86_64-linux"]; in rec { - forAllSystems = f: genAttrs supportedSystems (system: f nixpkgs.legacyPackages.${system}); + forAllSystems = f: genAttrs supportedSystems (system: f (import nixpkgs {inherit system;})); nixosModules = listToAttrs (findModulesList ../modules); @@ -32,9 +32,10 @@ in rec { oizysHosts = mapAttrs (name: _: mkSystem name) (readDir ../hosts); oizysPkg = forAllSystems ( pkgs: rec { + oizys-zig = pkgs.callPackage ../pkgs/oizys/oizys-zig { zig2nix = inputs.zig2nix;}; oizys-nim = pkgs.callPackage ../pkgs/oizys/oizys-nim {}; - oizys = pkgs.callPackage ../pkgs/oizys/oizys-rs {}; - default = oizys; + oizys-rs = pkgs.callPackage ../pkgs/oizys/oizys-rs {}; + default = oizys-zig; } ); devShells = forAllSystems ( diff --git a/modules/languages/misc.nix b/modules/languages/misc.nix index e2cf5d4..1c72c73 100644 --- a/modules/languages/misc.nix +++ b/modules/languages/misc.nix @@ -9,6 +9,7 @@ in { config = mkIfIn "misc" cfg { environment.systemPackages = with pkgs; [ + zig go rustup ]; diff --git a/modules/nix.nix b/modules/nix.nix index 57f2dba..596233d 100644 --- a/modules/nix.nix +++ b/modules/nix.nix @@ -25,7 +25,7 @@ nil alejandra - self.packages.${pkgs.system}.oizys + self.packages.${pkgs.system}.default inputs.pinix.packages.${pkgs.system}.default ]; diff --git a/pkgs/oizys/oizys-rs/default.nix b/pkgs/oizys/oizys-rs/default.nix index 4f32b66..d9e9580 100644 --- a/pkgs/oizys/oizys-rs/default.nix +++ b/pkgs/oizys/oizys-rs/default.nix @@ -1,6 +1,7 @@ { installShellFiles, rustPlatform, + nix-output-monitor, }: rustPlatform.buildRustPackage { pname = "oizys"; @@ -11,6 +12,7 @@ rustPlatform.buildRustPackage { }; nativeBuildInputs = [installShellFiles]; + buildInputs = [nix-output-monitor]; postInstall = '' installShellCompletion --cmd oizys \ diff --git a/pkgs/oizys/oizys-zig/.gitignore b/pkgs/oizys/oizys-zig/.gitignore new file mode 100644 index 0000000..7dc0ebe --- /dev/null +++ b/pkgs/oizys/oizys-zig/.gitignore @@ -0,0 +1,13 @@ +# Created by https://www.toptal.com/developers/gitignore/api/zig +# Edit at https://www.toptal.com/developers/gitignore?templates=zig + +### zig ### +# Zig programming language + +zig-cache/ +zig-out/ +build/ +build-*/ +docgen_tmp/ + +# End of https://www.toptal.com/developers/gitignore/api/zig diff --git a/pkgs/oizys/oizys-zig/build.zig b/pkgs/oizys/oizys-zig/build.zig new file mode 100644 index 0000000..6107bd4 --- /dev/null +++ b/pkgs/oizys/oizys-zig/build.zig @@ -0,0 +1,36 @@ +const std = @import("std"); + +pub fn build(b: *std.Build) void { + b.release_mode = .safe; + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + const exe = b.addExecutable(.{ + .name = "oizys", + .root_source_file = .{ .path = "src/main.zig" }, + .target = target, + .optimize = optimize, + }); + exe.root_module.addImport("yazap", b.dependency("yazap", .{ .target = target }).module("yazap")); + b.installArtifact(exe); + + const run_cmd = b.addRunArtifact(exe); + run_cmd.step.dependOn(b.getInstallStep()); + if (b.args) |args| { + run_cmd.addArgs(args); + } + const run_step = b.step("run", "Run the app"); + run_step.dependOn(&run_cmd.step); + + // I haven't written any... + // const exe_unit_tests = b.addTest(.{ + // .root_source_file = .{ .path = "src/main.zig" }, + // .target = target, + // .optimize = optimize, + // }); + // + // const run_exe_unit_tests = b.addRunArtifact(exe_unit_tests); + // const test_step = b.step("test", "Run unit tests"); + // test_step.dependOn(&run_exe_unit_tests.step); + // +} diff --git a/pkgs/oizys/oizys-zig/build.zig.zon b/pkgs/oizys/oizys-zig/build.zig.zon new file mode 100644 index 0000000..cfed9c0 --- /dev/null +++ b/pkgs/oizys/oizys-zig/build.zig.zon @@ -0,0 +1,11 @@ +.{ + .name = "oizys-zig", + .version = "0.0.0", + .dependencies = .{ + .yazap = .{ + .url = "git+https://github.com/cdmistman/yazap.git#1ae1a5b562f5c66caf8e87e04313094f16e327fc", + .hash = "1220fa71798c994044a987cbde6e73af76bfc402117a61971ccf48f4af4b7154e8d3", + }, + }, + .paths = .{""}, +} diff --git a/pkgs/oizys/oizys-zig/build.zig.zon2json-lock b/pkgs/oizys/oizys-zig/build.zig.zon2json-lock new file mode 100644 index 0000000..0f22025 --- /dev/null +++ b/pkgs/oizys/oizys-zig/build.zig.zon2json-lock @@ -0,0 +1,7 @@ +{ + "1220fa71798c994044a987cbde6e73af76bfc402117a61971ccf48f4af4b7154e8d3": { + "name": "yazap", + "url": "git+https://github.com/cdmistman/yazap.git#1ae1a5b562f5c66caf8e87e04313094f16e327fc", + "hash": "sha256-nNhFpay+xk0Ix3GAT1fZ2q/bD9AAx7Xkl4X7QxlzK0M=" + } +} diff --git a/pkgs/oizys/oizys-zig/default.nix b/pkgs/oizys/oizys-zig/default.nix new file mode 100644 index 0000000..c29bd7d --- /dev/null +++ b/pkgs/oizys/oizys-zig/default.nix @@ -0,0 +1,12 @@ +{ + pkgs, + zig2nix, + lib, + ... +}: + (zig2nix.outputs.zig-env.${pkgs.system} { + zig = zig2nix.outputs.packages.${pkgs.system}.zig.master.bin; + }).package { + name = "oizys"; + src = lib.cleanSource ./.; +} diff --git a/pkgs/oizys/oizys-zig/src/Cli.zig b/pkgs/oizys/oizys-zig/src/Cli.zig new file mode 100644 index 0000000..9814cb0 --- /dev/null +++ b/pkgs/oizys/oizys-zig/src/Cli.zig @@ -0,0 +1,35 @@ +const Cli = @This(); +const std = @import("std"); +const yazap = @import("yazap"); +const App = yazap.App; +const Arg = yazap.Arg; + +const Allocator = std.mem.Allocator; +app: App, + +pub fn init(allocator: Allocator) !Cli { + var app = App.init(allocator, "oizys", "nix begat oizys"); + + const oizys = app.rootCommand(); + var cmd_dry = app.createCommand("dry", "poor man's nix flake check"); + var cmd_build = app.createCommand("build", "build nixos (w/nix build)"); + var cmd_cache = app.createCommand("cache", "build and push to cachix"); + var cmd_output = app.createCommand("output", "show system flake output path"); + var cmd_boot = app.createCommand("boot", "nixos rebuild boot"); + var cmd_switch = app.createCommand("switch", "nixos rebuild switch"); + const commands = .{ &cmd_dry, &cmd_build, &cmd_cache, &cmd_output, &cmd_switch, &cmd_boot }; + + try cmd_cache.addArg(Arg.singleValueOption("name", 'n', "name of cachix cache")); + inline for (commands) |subcmd| { + try subcmd.addArg(Arg.singleValueOption("flake", 'f', "path to flake")); + try subcmd.addArg(Arg.singleValueOption("host", null, "hostname (default: current host)")); + try subcmd.addArg(Arg.booleanOption("no-pinix", null, "don't use pinix")); + try oizys.addSubcommand(subcmd.*); + } + + return Cli{ .app = app }; +} + +pub fn deinit(self: *Cli) void { + self.app.deinit(); +} diff --git a/pkgs/oizys/oizys-zig/src/Oizys.zig b/pkgs/oizys/oizys-zig/src/Oizys.zig new file mode 100644 index 0000000..47dddb6 --- /dev/null +++ b/pkgs/oizys/oizys-zig/src/Oizys.zig @@ -0,0 +1,114 @@ +const Oizys = @This(); +const std = @import("std"); +const ArgMatches = @import("yazap").ArgMatches; +const Allocator = std.mem.Allocator; + +allocator: Allocator, +flake: []const u8, +host: []const u8, +cache_name: []const u8, +output: []const u8, +cmd: OizysCmd, +debug: bool = false, +no_pinix: bool = false, + +pub const OizysCmd = enum { + dry, + @"switch", + boot, + cache, + output, + build, +}; + +pub fn init(allocator: std.mem.Allocator, matches: *const ArgMatches) !Oizys { + const cmd = matches.subcommand.?.name; + const flags = matches.subcommandMatches(cmd).?; + const host = flags.getSingleValue("host") orelse try Oizys.getDefaultHostName(allocator); + const flake = flags.getSingleValue("flake") orelse try Oizys.getDefaultFlake(allocator); + const cache_name = flags.getSingleValue("cache") orelse "daylin"; + + return Oizys{ + .allocator = allocator, + .host = host, + .flake = flake, + .output = try std.fmt.allocPrint(allocator, "{s}#nixosConfigurations.{s}.config.system.build.toplevel", .{ flake, host }), + .cmd = std.meta.stringToEnum(OizysCmd, cmd).?, + .cache_name = cache_name, + }; +} + +pub fn deinit(self: *Oizys) void { + self.allocator.free(self.flake); + self.allocator.free(self.host); + self.allocator.free(self.output); +} + +pub fn nix(self: *Oizys) []const u8 { + return if (self.no_pinix) "nix" else "pix"; +} + +pub fn nixos_rebuild(self: *Oizys) []const u8 { + return if (self.no_pinix) "nixos-rebuild" else "pixos-rebuild"; +} + +pub fn getDefaultHostName(allocator: Allocator) ![]const u8 { + var name_buffer: [std.posix.HOST_NAME_MAX]u8 = undefined; + const hostname = try std.posix.gethostname(&name_buffer); + return std.fmt.allocPrint(allocator, "{s}", .{hostname}); +} + +pub fn getDefaultFlake(allocator: Allocator) ![]const u8 { + return std.process.getEnvVarOwned(allocator, "OIZYS_DIR") catch { + const homedir = try std.process.getEnvVarOwned(allocator, "HOME"); + defer allocator.free(homedir); + return try std.fmt.allocPrint(allocator, "{s}/oizys", .{homedir}); + }; +} + +pub fn getOutputPath(self: *Oizys) ![]const u8 { + return std.fmt.allocPrint(self.allocator, "{s}#nixosConfigurations.{s}.config.system.build.toplevel", .{ self.flake, self.host }); +} + +pub const NixCmd = enum { Nix, NixosRebuild }; + +pub fn runNixCmd(self: *Oizys, cmd: NixCmd, argv: []const []const u8) !void { + var args = std.ArrayList([]const u8).init(self.allocator); + defer args.deinit(); + + switch (cmd) { + NixCmd.Nix => try args.append(self.nix()), + NixCmd.NixosRebuild => try args.appendSlice(&.{ "sudo", self.nixos_rebuild() }), + } + try args.appendSlice(argv); + var p = std.ChildProcess.init(args.items, self.allocator); + _ = try p.spawnAndWait(); +} + +pub fn cache(self: *Oizys) !void { + var p = std.ChildProcess.init(&.{ "cachix", "watch-exec", self.cache_name,"--verbose" ,"--", "nix", "build", self.flake, "--print-build-logs", "--accept-flake-config" }, self.allocator); + _ = try p.spawnAndWait(); +} + +pub fn run(self: *Oizys) !void { + switch (self.cmd) { + .@"switch" => { + try self.runNixCmd(NixCmd.NixosRebuild, &.{ "switch", "--flake", self.flake }); + }, + .boot => { + try self.runNixCmd(NixCmd.NixosRebuild, &.{ "boot", "--flake", self.flake }); + }, + .dry => { + try self.runNixCmd(NixCmd.Nix, &.{ "build", self.output, "--dry-run" }); + }, + .build => { + try self.runNixCmd(NixCmd.Nix, &.{ "build", self.output }); + }, + .output => { + std.debug.print("{s}", .{self.output}); + }, + .cache => { + try self.cache(); + }, + } +} diff --git a/pkgs/oizys/oizys-zig/src/main.zig b/pkgs/oizys/oizys-zig/src/main.zig new file mode 100644 index 0000000..22a6e21 --- /dev/null +++ b/pkgs/oizys/oizys-zig/src/main.zig @@ -0,0 +1,22 @@ +const std = @import("std"); +const Oizys = @import("Oizys.zig"); +const Cli = @import("Cli.zig"); + +pub fn main() !void { + // memory management isn't hard :P + var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator); + defer arena.deinit(); + const allocator = arena.allocator(); + + var cli = try Cli.init(allocator); + const matches = try cli.app.parseProcess(); + + if (!matches.containsArgs()) { + try cli.app.displayHelp(); + return; + } + + var oizys = try Oizys.init(allocator, matches); + try oizys.run(); + +}