From 5d7802cdfdb06df1e48852487cdc922da0148c61 Mon Sep 17 00:00:00 2001 From: RGBCube Date: Wed, 15 May 2024 13:02:25 +0300 Subject: [PATCH] Initial commit --- .gitignore | 10 ++++++++++ build.zig | 41 +++++++++++++++++++++++++++++++++++++++++ build.zig.zon | 10 ++++++++++ build.zig.zon.nix | 6 ++++++ flake.lock | 27 +++++++++++++++++++++++++++ flake.nix | 28 ++++++++++++++++++++++++++++ package.nix | 41 +++++++++++++++++++++++++++++++++++++++++ src/main.zig | 26 ++++++++++++++++++++++++++ 8 files changed, 189 insertions(+) create mode 100644 .gitignore create mode 100644 build.zig create mode 100644 build.zig.zon create mode 100644 build.zig.zon.nix create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 package.nix create mode 100644 src/main.zig diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..9bb20ad --- /dev/null +++ b/.gitignore @@ -0,0 +1,10 @@ +* + +!src/ + +!.gitignore + +!*.lock +!*.nix +!*.zig +!*.zon diff --git a/build.zig b/build.zig new file mode 100644 index 0000000..c88cc53 --- /dev/null +++ b/build.zig @@ -0,0 +1,41 @@ +const std = @import("std"); + +pub fn build(b: *std.Build) void { + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + const exe = b.addExecutable(.{ + .name = "crash", + .root_source_file = b.path("src/main.zig"), + .target = target, + .optimize = optimize, + }); + + const opts = b.addOptions(); + opts.addOption(?[]const u8, "fallback_shell", b.option([]const u8, "fallback_shell", "The fallback shell crash will use if it can't read the environment or the variable isn't found")); + exe.root_module.addOptions("build_options", opts); + + 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 program"); + run_step.dependOn(&run_cmd.step); + + const exe_unit_tests = b.addTest(.{ + .root_source_file = b.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/build.zig.zon b/build.zig.zon new file mode 100644 index 0000000..efa94ad --- /dev/null +++ b/build.zig.zon @@ -0,0 +1,10 @@ +.{ + .name = "crash", + .version = "0.0.1", + + .minimum_zig_version = "0.12.0", + + .paths = .{ + "", + }, +} diff --git a/build.zig.zon.nix b/build.zig.zon.nix new file mode 100644 index 0000000..441b465 --- /dev/null +++ b/build.zig.zon.nix @@ -0,0 +1,6 @@ +# generated by zon2nix (https://github.com/nix-community/zon2nix) + +{ linkFarm, fetchzip }: + +linkFarm "zig-packages" [ +] diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..f90f977 --- /dev/null +++ b/flake.lock @@ -0,0 +1,27 @@ +{ + "nodes": { + "nixpkgs": { + "locked": { + "lastModified": 1715653339, + "narHash": "sha256-7lR9tpVXviSccl07GXI0+ve/natd24HAkuy1sQp0OlI=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "abd6d48f8c77bea7dc51beb2adfa6ed3950d2585", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..eb7b337 --- /dev/null +++ b/flake.nix @@ -0,0 +1,28 @@ +{ + description = "Crash"; + + nixConfig = { + extra-substituters = "https://cache.garnix.io/"; + extra-trusted-public-keys = "cache.garnix.io:CTFPyKSLcx5RMJKfLo5EEPUObbA78b0YQ2DTCJXqr9g="; + }; + + inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + + outputs = { nixpkgs, ... }: with nixpkgs.lib; foldl' recursiveUpdate {} (map (system: let + pkgs = import nixpkgs { inherit system; }; + in { + devShell.${system} = pkgs.mkShell { + packages = with pkgs; [ + zig_0_12 + zls + zon2nix + ]; + }; + + packages.${system} = rec { + crash = pkgs.callPackage ./package.nix {}; + default = crash; + }; + + }) [ "x86_64-linux" "aarch64-linux" "riscv64-linux" ]); +} diff --git a/package.nix b/package.nix new file mode 100644 index 0000000..da12f22 --- /dev/null +++ b/package.nix @@ -0,0 +1,41 @@ +{ + lib, + stdenvNoCC, + callPackage, + + zig_0_12, + optimize ? "ReleaseFast", + + bash, + fallbackShell ? bash, +}: + +stdenvNoCC.mkDerivation { + name = "crash"; + version = lib.head (lib.strings.match ''.*\.version = "([^"]*)".*'' (lib.readFile ./build.zig.zon)); + + src = ./.; + + nativeBuildInputs = [ zig_0_12 ]; + + dontConfigure = true; + dontInstall = true; + + preBuild = '' + mkdir -p .cache + ln -s ${callPackage ./build.zig.zon.nix {}} .cache/p + ''; + + buildPhase = '' + runHook preBuild + + zig build install \ + --cache-dir $(pwd)/zig-cache \ + --global-cache-dir $(pwd)/.cache \ + --prefix $out \ + -Doptimize=${optimize} \ + -Dfallback_shell=${lib.getExe fallbackShell} + + runHook postBuild + ''; +} diff --git a/src/main.zig b/src/main.zig new file mode 100644 index 0000000..c958a89 --- /dev/null +++ b/src/main.zig @@ -0,0 +1,26 @@ +const std = @import("std"); +const fallback_shell = @import("build_options").fallback_shell orelse @compileError("fallback shell was not specified"); + +pub fn fallback(alloc: std.mem.Allocator) noreturn { + const err = std.process.execv(alloc, &[_][]const u8{fallback_shell}); + std.process.exit(@intCast(@intFromError(err))); +} + +pub fn main() noreturn { + var gpa = std.heap.GeneralPurposeAllocator(.{}){}; + const alloc = gpa.allocator(); + + const shells = std.posix.getenv("SHELLS") orelse fallback(alloc); + + var it = std.mem.split(u8, shells, ":"); + while (it.next()) |shell| { + var child = std.process.Child.init(&[_][]const u8{shell}, alloc); + + switch (child.spawnAndWait() catch fallback(alloc)) { + std.process.Child.Term.Exited => |exit_code| if (exit_code == 0) std.process.exit(0), + else => continue, + } + } + + fallback(alloc); +}