# flake.nix - Nix-defined package and devel env for the Mercurial project. # # Copyright 2021-2023 Pacien TRAN-GIRARD # # This software may be used and distributed according to the terms of the # GNU General Public License version 2 or any later version. # Usage summary, from the root of this repository: # # Enter a shell with development tools: # nix develop 'hg+file:.?dir=contrib/nix' # # Running mercurial: # nix run 'hg+file:.?dir=contrib/nix' -- version # # Running the test suite in a sandbox: # nix build 'hg+file:.?dir=contrib/nix#mercurial-tests' -L { inputs = { nixpkgs.url = "github:NixOS/nixpkgs/nixos-22.11"; nixpkgs-black.url = "github:NixOS/nixpkgs/c7cb72b0"; # black 20.8b1 # rust-overlay.url = "github:oxalica/rust-overlay"; flake-utils.url = "github:numtide/flake-utils"; flaky-utils.url = "git+https://cgit.pacien.net/libs/flaky-utils"; }; outputs = { self , nixpkgs , nixpkgs-black # , rust-overlay , flake-utils , flaky-utils }: flake-utils.lib.eachDefaultSystem (system: let # overlays = [ (import rust-overlay) ]; pkgs = import nixpkgs { inherit system; }; # We're in the contrib/nix sub-directory. src = ../..; # For snapshots, to satisfy extension minimum version requirements. dummyVersion = "99.99"; pin = { # The test suite has issues with the latest/current versions of Python. # Use an older recommended version instead, matching the CI. python = pkgs.python39; # The project uses a pinned version (rust/clippy.toml) for compiling, # but uses formatter features from nightly. # TODO: make cargo use the formatter from nightly automatically # (not supported by rustup/cargo yet? workaround?) # rustPlatform = pkgs.rust-bin.stable."1.61.0".default; # rustPlatformFormatter = pkgs.rust-bin.nightly."2023-04-20".default; # The CI uses an old version of the Black code formatter, # itself depending on old Python libraries. # The formatting rules have changed in more recent versions. inherit (import nixpkgs-black { inherit system; }) black; }; in rec { apps.mercurial = apps.mercurial-rust; apps.default = apps.mercurial; apps.mercurial-c = flake-utils.lib.mkApp { drv = packages.mercurial-c; }; apps.mercurial-rust = flake-utils.lib.mkApp { drv = packages.mercurial-rust; }; packages.mercurial = packages.mercurial-rust; packages.default = packages.mercurial; packages.mercurial-c = pin.python.pkgs.buildPythonApplication { format = "other"; pname = "mercurial"; version = "SNAPSHOT"; passthru.exePath = "/bin/hg"; inherit src; postPatch = '' echo 'version = b"${toString dummyVersion}"' \ > mercurial/__version__.py patchShebangs . for f in **/*.{py,c,t}; do # not only used in shebangs substituteAllInPlace "$f" '/bin/sh' '${pkgs.stdenv.shell}' done ''; buildInputs = with pin.python.pkgs; [ docutils ]; nativeBuildInputs = with pkgs; [ gettext installShellFiles ]; makeFlags = [ "PREFIX=$(out)" ]; buildPhase = '' make local ''; # Test suite is huge ; run on-demand in a separate package instead. doCheck = false; }; packages.mercurial-rust = packages.mercurial-c.overrideAttrs (super: { cargoRoot = "rust"; cargoDeps = pkgs.rustPlatform.importCargoLock { lockFile = "${src}/rust/Cargo.lock"; }; nativeBuildInputs = (super.nativeBuildInputs or []) ++ ( with pkgs.rustPlatform; [ cargoSetupHook rust.cargo rust.rustc ] ); makeFlags = (super.makeFlags or []) ++ [ "PURE=--rust" ]; }); packages.mercurial-tests = pkgs.stdenv.mkDerivation { pname = "mercurial-tests"; version = "SNAPSHOT"; inherit src; buildInputs = with pkgs; [ pin.python pin.black unzip which sqlite ]; postPatch = (packages.mercurial.postPatch or "") + '' # * paths emitted by our wrapped hg look like ..hg-wrapped-wrapped # * 'hg' is a wrapper; don't run using python directly for f in **/*.t; do substituteInPlace 2>/dev/null "$f" \ --replace '*/hg:' '*/*hg*:' \ --replace '"$PYTHON" "$BINDIR"/hg' '"$BINDIR"/hg' done ''; buildPhase = '' export HGTEST_REAL_HG="${packages.mercurial}/bin/hg" export HGMODULEPOLICY="rust+c" export HGTESTFLAGS="--blacklist blacklists/nix" make check 2>&1 | tee "$out" ''; }; devShell = flaky-utils.lib.mkDevShell { inherit pkgs; tools = [ pin.python pin.black ]; }; }); }