diff --git a/lib/default.nix b/lib/default.nix index cfa151cac..724fb3d9a 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -32,7 +32,7 @@ lib.fix (clanLib: { jsonschema = import ./jsonschema { inherit lib; }; facts = import ./facts.nix { inherit lib; }; - # Passthrough from self.inputs - # TODO: Can we make these agnostic from the name of the input? - inherit (self.inputs.nix-select.lib) parseSelector applySelectors select; + # deprecated + # remove when https://git.clan.lol/clan/clan-core/pulls/3212 is implemented + inherit (self.inputs.nix-select.lib) select; }) diff --git a/pkgs/clan-cli/clan_cli/dirs.py b/pkgs/clan-cli/clan_cli/dirs.py index 443096df2..7aed170db 100644 --- a/pkgs/clan-cli/clan_cli/dirs.py +++ b/pkgs/clan-cli/clan_cli/dirs.py @@ -140,3 +140,7 @@ def nixpkgs_flake() -> Path: def nixpkgs_source() -> Path: return (module_root() / "nixpkgs" / "path").resolve() + + +def select_source() -> Path: + return (module_root() / "select").resolve() diff --git a/pkgs/clan-cli/clan_cli/flake.py b/pkgs/clan-cli/clan_cli/flake.py index 93eb3a83d..b25ef5170 100644 --- a/pkgs/clan-cli/clan_cli/flake.py +++ b/pkgs/clan-cli/clan_cli/flake.py @@ -8,7 +8,7 @@ from tempfile import NamedTemporaryFile from typing import Any from clan_cli.cmd import Log, RunOpts, run -from clan_cli.dirs import user_cache_dir +from clan_cli.dirs import select_source, user_cache_dir from clan_cli.errors import ClanError from clan_cli.nix import ( nix_build, @@ -700,12 +700,23 @@ class Flake: str_selectors.append(selectors_as_json(parse_selector(selector))) config = nix_config() + + select_hash = "@select_hash@" + if not select_hash.startswith("sha256-"): + select_flake = Flake(str(select_source())) + select_flake.invalidate_cache() + assert select_flake.hash is not None, ( + "this should be impossible as invalidate_cache() should always set `hash`" + ) + select_hash = select_flake.hash + nix_code = f""" let - flake = builtins.getFlake("path:{self.store_path}?narHash={self.hash}"); + flake = builtins.getFlake "path:{self.store_path}?narHash={self.hash}"; + selectLib = (builtins.getFlake "{select_source()}?narHash={select_hash}").lib; in flake.inputs.nixpkgs.legacyPackages.{config["system"]}.writeText "clan-flake-select" ( - builtins.toJSON [ {" ".join([f"(flake.clanInternals.clanLib.applySelectors (builtins.fromJSON ''{attr}'') flake)" for attr in str_selectors])} ] + builtins.toJSON [ {" ".join([f"(selectLib.applySelectors (builtins.fromJSON ''{attr}'') flake)" for attr in str_selectors])} ] ) """ if tmp_store := nix_test_store(): diff --git a/pkgs/clan-cli/default.nix b/pkgs/clan-cli/default.nix index 964fce2c1..409a94cd7 100644 --- a/pkgs/clan-cli/default.nix +++ b/pkgs/clan-cli/default.nix @@ -2,15 +2,16 @@ # callPackage args gnupg, installShellFiles, + jq, lib, nix, pkgs, runCommand, stdenv, - nixVersions, # custom args clan-core-path, nixpkgs, + nix-select, includedRuntimeDeps, pythonRuntime, templateDerivation, @@ -52,22 +53,31 @@ let (pythonRuntime.withPackages pyTestDeps) ]; - source = runCommand "clan-cli-source" { } '' - cp -r ${./.} $out - chmod -R +w $out - # In cases where the devshell created this file, this will already exist - rm -f $out/clan_cli/nixpkgs + source = + runCommand "clan-cli-source" + { + nativeBuildInputs = [ jq ]; + } + '' + cp -r ${./.} $out + chmod -R +w $out - ln -sf ${nixpkgs'} $out/clan_cli/nixpkgs - cp -r ${../../templates} $out/clan_cli/templates - ''; + # In cases where the devshell created this file, this will already exist + rm -f $out/clan_cli/nixpkgs + + substituteInPlace $out/clan_cli/flake.py \ + --replace-fail '@select_hash@' "$(jq -r '.nodes."nix-select".locked.narHash' ${../../flake.lock})" + ln -sf ${nixpkgs'} $out/clan_cli/nixpkgs + ln -sf ${nix-select} $out/clan_cli/select + cp -r ${../../templates} $out/clan_cli/templates + ''; # Create a custom nixpkgs for use within the project nixpkgs' = runCommand "nixpkgs" { # Not all versions have `nix flake update --flake` option - nativeBuildInputs = [ nixVersions.stable ]; + nativeBuildInputs = [ nix ]; } '' mkdir $out @@ -121,14 +131,12 @@ pythonRuntime.pkgs.buildPythonApplication { propagatedBuildInputs = [ pythonRuntimeWithDeps ] ++ bundledRuntimeDependencies; - # Define and expose the tests and checks to run in CI passthru.tests = { clan-deps = pkgs.runCommand "clan-deps" { } '' # ${builtins.toString (builtins.attrValues testRuntimeDependenciesMap)} touch $out ''; - # disabled on macOS until we fix all remaining issues clan-pytest-without-core = runCommand "clan-pytest-without-core" { @@ -140,7 +148,7 @@ pythonRuntime.pkgs.buildPythonApplication { }; } '' - set -u -o pipefail + set -euo pipefail cp -r ${source} ./src chmod +w -R ./src cd ./src @@ -160,6 +168,7 @@ pythonRuntime.pkgs.buildPythonApplication { ''; } // lib.optionalAttrs (!stdenv.isDarwin) { + # disabled on macOS until we fix all remaining issues clan-pytest-with-core = runCommand "clan-pytest-with-core" { @@ -182,7 +191,7 @@ pythonRuntime.pkgs.buildPythonApplication { }; } '' - set -u -o pipefail + set -euo pipefail cp -r ${source} ./src chmod +w -R ./src cd ./src @@ -215,8 +224,14 @@ pythonRuntime.pkgs.buildPythonApplication { passthru.testRuntimeDependencies = testRuntimeDependencies; passthru.testRuntimeDependenciesMap = testRuntimeDependenciesMap; + # Nixpkgs doesn't get copied from `src` as it's not in `package-data` in `pyproject.toml` + # as it significantly slows down the build so we copy it again here + # We don't copy `select` using `package-data` as Python globs don't include hidden directories + # leading to a different NAR hash and copying it here would also lead to `patchShebangs` + # changing the contents postInstall = '' cp -r ${nixpkgs'} $out/${pythonRuntime.sitePackages}/clan_cli/nixpkgs + ln -sf ${nix-select} $out/${pythonRuntime.sitePackages}/clan_cli/select installShellCompletion --bash --name clan \ <(${pythonRuntimeWithDeps.pkgs.argcomplete}/bin/register-python-argcomplete --shell bash clan) installShellCompletion --fish --name clan.fish \ diff --git a/pkgs/clan-cli/flake-module.nix b/pkgs/clan-cli/flake-module.nix index ce736765c..49115ec20 100644 --- a/pkgs/clan-cli/flake-module.nix +++ b/pkgs/clan-cli/flake-module.nix @@ -129,10 +129,11 @@ devShells.clan-cli = pkgs.callPackage ./shell.nix { inherit (self'.packages) clan-cli; inherit self'; + inherit (inputs) nix-select; }; packages = { clan-cli = pkgs.callPackage ./default.nix { - inherit (inputs) nixpkgs; + inherit (inputs) nixpkgs nix-select; templateDerivation = templateDerivation; pythonRuntime = pkgs.python3; clan-core-path = clanCoreWithVendoredDeps; @@ -142,7 +143,7 @@ ]; }; clan-cli-full = pkgs.callPackage ./default.nix { - inherit (inputs) nixpkgs; + inherit (inputs) nixpkgs nix-select; clan-core-path = clanCoreWithVendoredDeps; templateDerivation = templateDerivation; pythonRuntime = pkgs.python3; diff --git a/pkgs/clan-cli/shell.nix b/pkgs/clan-cli/shell.nix index 563246064..69aec4625 100644 --- a/pkgs/clan-cli/shell.nix +++ b/pkgs/clan-cli/shell.nix @@ -1,6 +1,7 @@ { lib, nix-unit, + nix-select, clan-cli, mkShell, ruff, @@ -43,6 +44,7 @@ mkShell { # Needed for impure tests ln -sfT ${clan-cli.nixpkgs} "$PKG_ROOT/clan_cli/nixpkgs" + ln -sfT ${nix-select} "$PKG_ROOT/clan_cli/select" # Generate classes.py from inventory schema # This file is in .gitignore