diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 887258ca..b64be0aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1,6 +1,7 @@ name: "CI" on: pull_request: + merge_group: push: jobs: shellcheck: diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 48070536..e02be234 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -1,6 +1,7 @@ name: Publish on: pull_request: + merge_group: push: branches: - '*' diff --git a/flake.lock b/flake.lock index eda6a5f7..3e2769b8 100644 --- a/flake.lock +++ b/flake.lock @@ -1,5 +1,50 @@ { "nodes": { + "flake-parts": { + "inputs": { + "nixpkgs-lib": [ + "nixpkgs" + ] + }, + "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" + } + }, + "git-hooks-nix": { + "inputs": { + "flake-compat": [], + "gitignore": [], + "nixpkgs": [ + "nixpkgs" + ], + "nixpkgs-stable": [ + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1734279981, + "narHash": "sha256-NdaCraHPp8iYMWzdXAt5Nv6sA3MUzlCiGiR586TCwo0=", + "owner": "cachix", + "repo": "git-hooks.nix", + "rev": "aa9f40c906904ebd83da78e7f328cd8aeaeae785", + "type": "github" + }, + "original": { + "owner": "cachix", + "repo": "git-hooks.nix", + "type": "github" + } + }, "nixpkgs": { "locked": { "lastModified": 1731763621, @@ -18,6 +63,8 @@ }, "root": { "inputs": { + "flake-parts": "flake-parts", + "git-hooks-nix": "git-hooks-nix", "nixpkgs": "nixpkgs" } } diff --git a/flake.nix b/flake.nix index 7743c1f9..2fc6e640 100644 --- a/flake.nix +++ b/flake.nix @@ -3,8 +3,19 @@ inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + # dev tooling + inputs.flake-parts.url = "github:hercules-ci/flake-parts"; + inputs.git-hooks-nix.url = "github:cachix/git-hooks.nix"; + # work around https://github.com/NixOS/nix/issues/7730 + inputs.flake-parts.inputs.nixpkgs-lib.follows = "nixpkgs"; + inputs.git-hooks-nix.inputs.nixpkgs.follows = "nixpkgs"; + inputs.git-hooks-nix.inputs.nixpkgs-stable.follows = "nixpkgs"; + # work around 7730 and https://github.com/NixOS/nix/issues/7807 + inputs.git-hooks-nix.inputs.flake-compat.follows = ""; + inputs.git-hooks-nix.inputs.gitignore.follows = ""; + outputs = - { self, nixpkgs }: + inputs@{ self, nixpkgs, ... }: let inherit (nixpkgs) lib; @@ -38,13 +49,23 @@ patchelfFor = pkgs: - let - # this is only - in + # this is only pkgs.callPackage ./patchelf.nix { inherit version src; }; + # We don't apply flake-parts to the whole flake so that non-development attributes + # load without fetching any development inputs. + devFlake = inputs.flake-parts.lib.mkFlake { inherit inputs; } { + imports = [ ./maintainers/flake-module.nix ]; + systems = supportedSystems; + perSystem = + { system, ... }: + { + _module.args.pkgs = nixpkgs.legacyPackages.${system}; + }; + }; + in { @@ -126,18 +147,44 @@ }; - checks = forAllSystems (system: { - build = self.hydraJobs.build.${system}; - }); + checks = forAllSystems ( + system: + { + build = self.hydraJobs.build.${system}; + } + // devFlake.checks.${system} or { } + ); devShells = forAllSystems ( system: + let + mkShell = + patchelf: + patchelf.overrideAttrs ( + old: + let + pkgs = nixpkgs.legacyPackages.${system}; + modular = devFlake.getSystem pkgs.stdenv.buildPlatform.system; + in + { + env = (old.env or { }) // { + _NIX_PRE_COMMIT_HOOKS_CONFIG = "${(pkgs.formats.yaml { }).generate "pre-commit-config.yaml" + modular.pre-commit.settings.rawConfig + }"; + }; + nativeBuildInputs = (old.nativeBuildInputs or [ ]) ++ [ + modular.pre-commit.settings.package + (pkgs.writeScriptBin "pre-commit-hooks-install" modular.pre-commit.settings.installationScript) + ]; + } + ); + in { - glibc = self.packages.${system}.patchelf; + glibc = mkShell self.packages.${system}.patchelf; default = self.devShells.${system}.glibc; } // lib.optionalAttrs (system != "i686-linux") { - musl = self.packages.${system}.patchelf-musl; + musl = mkShell self.packages.${system}.patchelf-musl; } ); diff --git a/maintainers/flake-module.nix b/maintainers/flake-module.nix new file mode 100644 index 00000000..ebfd6ba1 --- /dev/null +++ b/maintainers/flake-module.nix @@ -0,0 +1,70 @@ +{ + lib, + getSystem, + inputs, + ... +}: + +{ + imports = [ + inputs.git-hooks-nix.flakeModule + ]; + + perSystem = + { config, pkgs, ... }: + { + + # https://flake.parts/options/git-hooks-nix#options + pre-commit.settings = { + hooks = { + # Conflicts are usually found by other checks, but not those in docs, + # and potentially other places. + check-merge-conflicts.enable = true; + # built-in check-merge-conflicts seems ineffective against those produced by mergify backports + check-merge-conflicts-2 = { + enable = true; + entry = "${pkgs.writeScript "check-merge-conflicts" '' + #!${pkgs.runtimeShell} + conflicts=false + for file in "$@"; do + if grep --with-filename --line-number -E '^>>>>>>> ' -- "$file"; then + conflicts=true + fi + done + if $conflicts; then + echo "ERROR: found merge/patch conflicts in files" + exit 1 + fi + ''}"; + }; + nixfmt-rfc-style = { + enable = true; + }; + clang-format = { + enable = true; + # https://github.com/cachix/git-hooks.nix/pull/532 + package = pkgs.llvmPackages_latest.clang-tools; + # Not yet formatted + excludes = [ + ''^src/elf.h$'' + ''^src/patchelf.cc$'' + ''^src/patchelf.h$'' + ''^tests/bar.c$'' + ''^tests/foo.c$'' + ''^tests/main.c$'' + ''^tests/no-rpath.c$'' + ''^tests/simple.c$'' + ''^tests/too-many-strtab.c$'' + ''^tests/void.c$'' + ]; + }; + shellcheck = { + enable = true; + }; + }; + }; + }; + + # We'll be pulling from this in the main flake + flake.getSystem = getSystem; +} diff --git a/maintainers/format.sh b/maintainers/format.sh new file mode 100755 index 00000000..b2902e6d --- /dev/null +++ b/maintainers/format.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +if ! type -p pre-commit &>/dev/null; then + echo "format.sh: pre-commit not found. Please use \`nix develop -c ./maintainers/format.sh\`."; + exit 1; +fi; +if test -z "$_NIX_PRE_COMMIT_HOOKS_CONFIG"; then + echo "format.sh: _NIX_PRE_COMMIT_HOOKS_CONFIG not set. Please use \`nix develop -c ./maintainers/format.sh\`."; + exit 1; +fi; + +while ! pre-commit run --config "$_NIX_PRE_COMMIT_HOOKS_CONFIG" --all-files; do + if [ "${1:-}" != "--until-stable" ]; then + exit 1 + fi +done