Skip to content

Improve hix flake check #2413

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 14, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
115 changes: 73 additions & 42 deletions hix/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,87 @@ let
cmd=$1
shift
case $cmd in
update)
nix-env -iA hix -f https://github.com/input-output-hk/haskell.nix/tarball/master
init|init-hix)
if [ "$cmd" == "init" ]; then
FLAKE_NIX="$(mktemp -d)/flake.nix"
sed 's|EVAL_SYSTEM|${pkgs.stdenv.hostPlatform.system}|' < ${hixInit}/flake.nix > $FLAKE_NIX
if [ -e flake.nix ]; then
if ! diff -u flake.nix $FLAKE_NIX; then
echo 'ERROR: Not replacing existing `flake.nix`.'
exit 1
fi
else
cp $FLAKE_NIX flake.nix
echo '`flake.nix` file created.'
fi
fi
HIX_NIX="$(mktemp -d)/hix.nix"
sed 's|EVAL_SYSTEM|${pkgs.stdenv.hostPlatform.system}|' < ${hixInit}/nix/hix.nix > $HIX_NIX
if [ -e nix/hix.nix ]; then
echo '`nix/hix.nix` project configuration already exists:'
else
mkdir -p nix
cp $HIX_NIX nix/hix.nix
echo '`nix/hix.nix` project configuation:'
fi
${pkgs.bat}/bin/bat nix/hix.nix
;;
dump-path|eval|log|path-info|search|show-derivation|sign-paths|verify|why-depends)
nix $cmd -f ${hixProject} ${args} "$@"
help)
cat <<EOF
Usage: hix <command> [args...]

hix is a wrapper around for the nix command that allows you
to work on haskell projects using nix without the need to add
nix files to the project.

Any nix <command> that takes 'installables' as an argumnet should
work and behave as if the project had a 'flake.nix' file that
was set up to work with haskell.nix.

You can add a 'nix/hix.nix' file to your project and 'hix' will
include that file as nix module containing project arguments.

Other commands:
init Add flake.nix and nix/hix.nix file to allow
nix commands to work (without hix).
help This message

Advanced options:
--projectArgs <nix> Haskell.nix arguments as Nix expression
--supportedSystems <nix> Supported systems as Nix expression
--overlays <nix> Overlay definitions
--config <nix> Custom nix configuration

Examples:
hix flake show .
hix build '.#hello:exe:hello'
hix run '.#hello:exe:hello'
hix flake check --projectArgs '{ compiler-nix-name = "ghc9122"; }'

EOF
;;
flake|build|develop|run|profile)
*)
# Put the flake files for remote URLs in $HOME/.hix by default
HIX_DIR="''${HIX_DIR:-$HOME/.hix}"
HIX_TMPDIR="$(mktemp -d)"
projectArgs=""
args=("--option" "allow-import-from-derivation" "true")
while(($#)); do
arg=$1
case $arg in
--projectArgs)
projectArgs="$2"
args+=(--override-input projectArgs "$HIX_TMPDIR")
printf %s "$2" > "$HIX_TMPDIR/projectArgs.nix"
shift
;;
--supportedSystems)
printf %s "$2" > "$HIX_TMPDIR/supportedSystems.nix"
shift
;;
--overlays)
printf %s "$2" > "$HIX_TMPDIR/overlays.nix"
shift
;;
--config)
printf %s "$2" > "$HIX_TMPDIR/config.nix"
shift
;;
--out-link|-o|--eval-store|--include|-I|--inputs-from|--expr|--file|-f|--keep|-k|--phase|--profile|--unset|-u)
Expand Down Expand Up @@ -102,42 +166,9 @@ let
cp $HIX_FLAKE $FLAKE/flake.nix
chmod +w $FLAKE/flake.nix
fi
if [ "$projectArgs" != "" ]; then
printf %s "$projectArgs" > "$HIX_TMPDIR/projectArgs.nix"
fi
args+=(--override-input projectArgs "$(realpath "$HIX_TMPDIR")")
nix $cmd "''${args[@]}"
;;
init|init-hix)
if [ "$cmd" == "init" ]; then
FLAKE_NIX="$(mktemp -d)/flake.nix"
sed 's|EVAL_SYSTEM|${pkgs.stdenv.hostPlatform.system}|' < ${hixInit}/flake.nix > $FLAKE_NIX
if [ -e flake.nix ]; then
if ! diff -u flake.nix $FLAKE_NIX; then
echo 'ERROR: Not replacing existing `flake.nix`.'
exit 1
fi
else
cp $FLAKE_NIX flake.nix
echo '`flake.nix` file created.'
fi
fi
HIX_NIX="$(mktemp -d)/hix.nix"
sed 's|EVAL_SYSTEM|${pkgs.stdenv.hostPlatform.system}|' < ${hixInit}/nix/hix.nix > $HIX_NIX
if [ -e nix/hix.nix ]; then
echo '`nix/hix.nix` project configuration already exists:'
else
mkdir -p nix
cp $HIX_NIX nix/hix.nix
echo '`nix/hix.nix` project configuation:'
fi
${pkgs.bat}/bin/bat nix/hix.nix
;;
repl)
nix $cmd ${hixProject} ${args} "$@"
;;
*)
nix $cmd "$@"
;;
esac
'';
in (pkgs.symlinkJoin {
Expand Down
26 changes: 18 additions & 8 deletions hix/project/flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,30 @@
inputs.projectArgs.flake = false;
inputs.src.flake = false;
outputs = { self, src, nixpkgs, flake-utils, haskellNix, projectArgs }:
flake-utils.lib.eachSystem [ "EVAL_SYSTEM" ] (system:
flake-utils.lib.eachSystem (
if builtins.pathExists (projectArgs + "/supportedSystems.nix")
then import (projectArgs + "/supportedSystems.nix")
else [ "EVAL_SYSTEM" ]) (system:
let
overlays = [ haskellNix.overlay
(final: _prev: {
hixProject =
final.haskell-nix.hix.project ({
inherit src;
} // (
if builtins.pathExists (projectArgs + "/projectArgs.nix")
then import (projectArgs + "/projectArgs.nix")
else {}));
(final.haskell-nix.hix.project
{ inherit src; }).appendModule (
if builtins.pathExists (projectArgs + "/projectArgs.nix")
then import (projectArgs + "/projectArgs.nix")
else {}
);
})
];
pkgs = import nixpkgs { inherit system overlays; inherit (haskellNix) config; };
pkgs = import nixpkgs { inherit system;
overlays = overlays ++ (if builtins.pathExists (projectArgs + "/overlays.nix")
then import (projectArgs + "/overlays.nix")
else []);
config = haskellNix.config // (if builtins.pathExists (projectArgs + "/config.nix")
then import (projectArgs + "/config.nix")
else {});
};
flake = pkgs.hixProject.flake {};
in flake // {
legacyPackages = pkgs;
Expand Down
2 changes: 1 addition & 1 deletion lib/check.nix
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ in stdenv.mkDerivation ((
name = (drv.name + "-check");

passthru = {
inherit (drv) identifier config configFiles executableToolDepends cleanSrc env exeName;
inherit (drv) identifier config configFiles executableToolDepends cleanSrc env exeName meta;
profiled = self drv.profiled;
dwarf = self drv.dwarf;
};
Expand Down
7 changes: 3 additions & 4 deletions lib/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -471,6 +471,7 @@ in {
${component.passthru.identifier.component-id} = {
type = "app";
program = component.exePath;
inherit (component) meta;
};
})
acc
Expand Down Expand Up @@ -531,8 +532,7 @@ in {
, apps ? mkFlakeApps haskellPackages
, checks ? mkFlakeChecks (collectChecks' haskellPackages)
, coverage ? {}
, devShell ? project.shell
, devShells ? { default = devShell; }
, devShells ? { default = project.shell; }
, checkedProject ? project.appendModule { checkMaterialization = true; }
, ciJobs ? mkFlakeCiJobs project { inherit checks coverage packages devShells checkedProject; }
, hydraJobs ? ciJobs
Expand Down Expand Up @@ -560,8 +560,7 @@ in {
ciJobs
# Used by:
# `nix develop`
devShells
devShell; # TODO remove devShell once everyone has nix that supports `devShells.default`
devShells;
};

# Adapt a standard project shell (`project.shell` or `haskell-nix.shellFor`)
Expand Down
2 changes: 1 addition & 1 deletion test/cabal.project.local
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ repository head.hackage.ghc.haskell.org
f76d08be13e9a61a377a85e2fb63f4c5435d40f8feb3e12eb05905edb8cdea89
26021a13b401500c8eb2761ca95c61f2d625bfef951b939a8124ed12ecf07329
7541f32a4ccca4f97aea3b22f5e593ba2c0267546016b992dfadcd2fe944e55d
--sha256: sha256-ywti4TWiuFGJtnHaMMPhk3Ms2hXfsXMC1LMcWnI9K6I=
--sha256: sha256-V7cPUrMNDXF+LDrNKUE+co1MEmOquGUQ19Z6dJP8bFA=

repository ghcjs-overlay
url: https://raw.githubusercontent.com/input-output-hk/hackage-overlay-ghcjs/ffb32dce467b9a4d27be759fdd2740a6edd09d0b
Expand Down
Loading