##// END OF EJS Templates
configitems: declare items in a TOML file...
configitems: declare items in a TOML file Mercurial ships with Rust code that also needs to read from the config. Having a way of presenting `configitems` to both Python and Rust is needed to prevent duplication, drift, and have the appropriate devel warnings. Abstracting away from Python means choosing a config format. No single format is perfect, and I have yet to come across a developer that doesn't hate all of them in some way. Since we have a strict no-dependencies policy for Mercurial, we either need to use whatever comes with Python, vendor a library, or implement a custom format ourselves. Python stdlib means using JSON, which doesn't support comments and isn't great for humans, or `configparser` which is an obscure, untyped format that nobody uses and doesn't have a commonplace Rust parser. Implementing a custom format is error-prone, tedious and subject to the same issues as picking an existing format. Vendoring opens us to the vast array of common config formats. The ones being picked for most modern software are YAML and TOML. YAML is older and common in the Python community, but TOML is much simpler and less error-prone. I would much rather be responsible for the <1000 lines of `tomli`, on top of TOML being the choice of the Rust community, with robust crates for reading it. The structure of `configitems.toml` is explained inline.

File last commit:

r51342:be676c31 default
r51655:c51b178b default
Show More
flake.nix
177 lines | 4.8 KiB | text/x-nix | NixLexer
# flake.nix - Nix-defined package and devel env for the Mercurial project.
#
# Copyright 2021-2023 Pacien TRAN-GIRARD <pacien.trangirard@pacien.net>
#
# 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
];
};
});
}