From 416c4377ee97d3e775d5a3b112783119684fc987 Mon Sep 17 00:00:00 2001 From: Morgan Jones Date: Wed, 4 Dec 2024 23:35:15 -0800 Subject: [PATCH] nix: support reproducible builds Nix lets anyone build this glorious repo without even cloning it. --- .gitignore | 1 + README.md | 32 ++++++++++++++++++++++- build.nix | 47 ++++++++++++++++++++++++++++++++++ default.nix | 13 ++++++++++ develop.nix | 14 ++++++++++ flake.lock | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++ flake.nix | 33 ++++++++++++++++++++++++ shell.nix | 13 ++++++++++ 8 files changed, 225 insertions(+), 1 deletion(-) create mode 100644 build.nix create mode 100644 default.nix create mode 100644 develop.nix create mode 100644 flake.lock create mode 100644 flake.nix create mode 100644 shell.nix diff --git a/.gitignore b/.gitignore index b9a52bd..57d9c33 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ target/ *.falsemetal *.joeydecaio +/result diff --git a/README.md b/README.md index beaa596..5d92cfe 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,37 @@ The `HelloWorldMainLauncherClass` performs the following tasks: - Java Development Kit (JDK) 8 or higher. - A Java IDE (like IntelliJ IDEA, Eclipse, or NetBeans) or a command-line environment to compile and run the Java program. -## Installation +## Running with Nix + +Nix is a way to reproducibly manage dependencies without using containers. Now everyone can run the same version of Nanowar Of Steel's glorious Hello World program. + +1. First, [get Nix](https://nixos.org/). + +2. Clone the repository: + ```bash + git clone https://github.com/NanowarOfSteel/HelloWorld.git + ``` + +3. Run `nix-shell` to drop into a shell with all the development dependencies like Maven and the JDK, or run `nix-build` to build the program. + +4. Output is at `result/bin/HelloWorld`. + +### Flakes + +If you have [Flakes](https://wiki.nixos.org/wiki/Flakes) enabled via methods like the [Determinate Nix Installer](https://github.com/DeterminateSystems/nix-installer), +you can run this project without even cloning it: + +1. Enable Flakes via the [wiki](https://wiki.nixos.org/wiki/Flakes) or the [Determinate Nix Installer](https://github.com/DeterminateSystems/nix-installer). + +2. Build and run it: + ```bash + nix run github:NanowarOfSteel/HelloWorld + ``` + +With flakes, you can also use `nix develop` instead of `nix-shell` and `nix build` instead of `nix-build`. +`nix flake update` will update the version of nixpkgs used. + +## Manual Installation To set up and run this project locally, follow these steps: diff --git a/build.nix b/build.nix new file mode 100644 index 0000000..0025fcd --- /dev/null +++ b/build.nix @@ -0,0 +1,47 @@ +{ + jre, + jdk, + makeWrapper, + maven, +}: + +maven.buildMavenPackage { + pname = "it.nanowar.ofsteel.helloworld"; + version = "0.0.1"; + src = ./.; + + mvnHash = "sha256-QVRwMC4FREgwojlX5JzTap2eg7HPFNgElIeCVycPOAI="; + + buildInputs = [ jre ]; + nativeBuildInputs = [ jdk makeWrapper maven ]; + + installPhase = '' + mkdir -p $out/bin $out/share/HelloWorld + jar="$(echo target/HelloWorld-*.jar)" + install -Dm644 "$jar" $out/share/HelloWorld + + makeWrapper ${jre}/bin/java $out/bin/HelloWorld \ + --add-flags "-cp $out/share/HelloWorld/$(basename -- "$jar")" \ + --add-flags "it.nanowar.ofsteel.helloworld.HelloWorldMainLauncherClass" + ''; + + doInstallCheck = true; + installCheckPhase = '' + result="$({ $out/bin/HelloWorld || true; } 2>&1)" + + echo "Result:" >&2 + echo "--------" >&2 + echo "$result" >&2 + echo "--------" >&2 + + if [ "$(echo "$result" | grep 'Hello World!' | wc -l)" != 4 ]; then + echo "Incorrect number of hello world lines" >&2 + exit 1 + fi + + if [ -z "$(echo "$result" | grep NullPointerException | grep joeyDeCaio)" ]; then + echo "Program should have failed with the correct error message" >&2 + exit 1 + fi + ''; +} diff --git a/default.nix b/default.nix new file mode 100644 index 0000000..85cb538 --- /dev/null +++ b/default.nix @@ -0,0 +1,13 @@ +(import + ( + let + lock = builtins.fromJSON (builtins.readFile ./flake.lock); + nodeName = lock.nodes.root.inputs.flake-compat; + in + fetchTarball { + url = lock.nodes.${nodeName}.locked.url or "https://github.com/edolstra/flake-compat/archive/${lock.nodes.${nodeName}.locked.rev}.tar.gz"; + sha256 = lock.nodes.${nodeName}.locked.narHash; + } + ) + { src = ./.; } +).defaultNix diff --git a/develop.nix b/develop.nix new file mode 100644 index 0000000..2c680a6 --- /dev/null +++ b/develop.nix @@ -0,0 +1,14 @@ +{ + mkShell, + HelloWorld, + cowsay +}: + +mkShell { + inherit (HelloWorld) pname version; + inputsFrom = [ HelloWorld ]; + buildInputs = [ cowsay ]; + shellHook = '' + echo "nanowar of steel rulez" | cowsay -f dragon >&2 + ''; +} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..617cb12 --- /dev/null +++ b/flake.lock @@ -0,0 +1,73 @@ +{ + "nodes": { + "flake-compat": { + "locked": { + "lastModified": 1696426674, + "narHash": "sha256-kvjfFW7WAETZlt09AgDn1MrtKzP7t90Vf7vypd3OL1U=", + "rev": "0f9255e01c2351cc7d116c072cb317785dd33b33", + "revCount": 57, + "type": "tarball", + "url": "https://api.flakehub.com/f/pinned/edolstra/flake-compat/1.0.1/018afb31-abd1-7bff-a5e4-cff7e18efb7a/source.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz" + } + }, + "flake-parts": { + "inputs": { + "nixpkgs-lib": "nixpkgs-lib" + }, + "locked": { + "lastModified": 1733312601, + "narHash": "sha256-4pDvzqnegAfRkPwO3wmwBhVi/Sye1mzps0zHWYnP88c=", + "owner": "hercules-ci", + "repo": "flake-parts", + "rev": "205b12d8b7cd4802fbcb8e8ef6a0f1408781a4f9", + "type": "github" + }, + "original": { + "owner": "hercules-ci", + "repo": "flake-parts", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1733261153, + "narHash": "sha256-eq51hyiaIwtWo19fPEeE0Zr2s83DYMKJoukNLgGGpek=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b681065d0919f7eb5309a93cea2cfa84dec9aa88", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixos-24.11", + "repo": "nixpkgs", + "type": "github" + } + }, + "nixpkgs-lib": { + "locked": { + "lastModified": 1733096140, + "narHash": "sha256-1qRH7uAUsyQI7R1Uwl4T+XvdNv778H0Nb5njNrqvylY=", + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz" + }, + "original": { + "type": "tarball", + "url": "https://github.com/NixOS/nixpkgs/archive/5487e69da40cbd611ab2cadee0b4637225f7cfae.tar.gz" + } + }, + "root": { + "inputs": { + "flake-compat": "flake-compat", + "flake-parts": "flake-parts", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..30e5eaa --- /dev/null +++ b/flake.nix @@ -0,0 +1,33 @@ +{ + description = "https://www.youtube.com/watch?v=yup8gIXxWDU"; + inputs = { + flake-parts.url = "github:hercules-ci/flake-parts"; + flake-compat.url = "https://flakehub.com/f/edolstra/flake-compat/1.tar.gz"; + nixpkgs.url = "github:NixOS/nixpkgs/nixos-24.11"; + }; + outputs = + inputs@{ flake-parts, ... }: + flake-parts.lib.mkFlake { inherit inputs; } { + systems = [ + "x86_64-linux" + "aarch64-linux" + "aarch64-darwin" + "x86_64-darwin" + ]; + perSystem = + { + config, + self', + inputs', + pkgs, + system, + ... + }: + rec { + packages.default = pkgs.callPackage ./build.nix { }; + devShells.default = pkgs.callPackage ./develop.nix { + HelloWorld = packages.default; + }; + }; + }; +} diff --git a/shell.nix b/shell.nix new file mode 100644 index 0000000..ea7b69b --- /dev/null +++ b/shell.nix @@ -0,0 +1,13 @@ +(import + ( + let + lock = builtins.fromJSON (builtins.readFile ./flake.lock); + nodeName = lock.nodes.root.inputs.flake-compat; + in + fetchTarball { + url = lock.nodes.${nodeName}.locked.url or "https://github.com/edolstra/flake-compat/archive/${lock.nodes.${nodeName}.locked.rev}.tar.gz"; + sha256 = lock.nodes.${nodeName}.locked.narHash; + } + ) + { src = ./.; } +).shellNix