1
1
mirror of https://github.com/tweag/ormolu.git synced 2024-10-06 01:47:10 +03:00
ormolu/default.nix
2022-08-17 16:45:07 +02:00

308 lines
10 KiB
Nix

{ ormoluCompiler ? "ghc8107",
ormoluLiveLink ? true
}:
let
pkgs = import ./nix/pkgs.nix;
hsPkgs = pkgs.haskell-nix.project {
src = pkgs.haskell-nix.haskellLib.cleanGit {
name = "ormolu";
src = ./.;
keepGitDir = true;
};
projectFileName = "cabal.project";
compiler-nix-name = ormoluCompiler;
modules =
let
gitTH = name: baseDir: { pkgs, lib, ... }: {
packages."${name}".components.exes."${name}" = {
build-tools =
lib.mkForce [ pkgs.buildPackages.buildPackages.gitReallyMinimal ];
extraSrcFiles = [ "${baseDir}.git/**/*" ];
};
};
in [
({ lib, ... }: {
config = {
dontStrip = false;
dontPatchELF = false;
enableDeadCodeElimination = true;
packages.ormolu.writeHieFiles = true;
};
# Make Cabal reinstallable
options.nonReinstallablePkgs =
# See https://github.com/input-output-hk/haskell.nix/issues/1177
let adapt = ps: if lib.hasPrefix "ghc9" ormoluCompiler
then ps ++ [ "exceptions" "stm" ] else ps;
in lib.mkOption { apply = ps: adapt (lib.remove "Cabal" ps); };
})
({ pkgs, lib, ... }: lib.mkIf pkgs.stdenv.hostPlatform.isGhcjs {
packages.ormolu = {
flags.fixity-th = false;
writeHieFiles = lib.mkForce false;
};
packages.ormolu-live.ghcOptions =
lib.optional (!ormoluLiveLink) "-fno-code";
})
(gitTH "ormolu" "")
(gitTH "ormolu-live" "../")
];
};
ormolu = hsPkgs.ormolu;
ormoluLib = ormolu.components.library;
ormoluExe = ormolu.components.exes.ormolu;
ormolize = import ./nix/ormolize {
inherit pkgs;
ormolu = ormoluExe;
};
extractHackageInfo = hsPkgs.extract-hackage-info.components.exes.extract-hackage-info;
ormoluLive = hsPkgs.projectCross.ghcjs.hsPkgs.ormolu-live.components.exes.ormolu-live
.overrideAttrs (_: pkgs.lib.optionalAttrs (!ormoluLiveLink) {
installPhase = ''
mkdir -p $out
'';
});
expectedFailures = [
"Agda"
"esqueleto"
"haxl"
"hlint"
"idris"
"leksah"
"pipes"
"postgrest"
];
ormolizedPackages =
let
ormolizeOverlay = self: super: { };
ormolizablePackages = pkgs.haskellPackages.override {
overrides = ormolizeOverlay;
};
in doCheck: pkgs.lib.mapAttrs (name: p: ormolize {
package = p;
inherit doCheck;
expectedFailures =
if pkgs.lib.lists.any (x: x == name) expectedFailures
then ./expected-failures + "/${name}.txt"
else null;
}) ormolizablePackages;
in {
ormoluTests = ormolu.checks.tests;
ormolu = ormoluExe; # for compatibility
inherit ormoluLib ormoluExe ormoluCompiler;
dev = let shellFor = packages: hsPkgs.shellFor {
inherit packages;
tools = {
cabal = "latest";
haskell-language-server = "latest";
};
withHoogle = false;
exactDeps = false;
}; in {
inherit hsPkgs;
ormoluShell = shellFor (ps: [ ps.ormolu ]);
ormoluLiveShell = shellFor (ps: [ ps.ormolu-live ]);
extractHackageInfoShell = shellFor (ps: [ ps.extract-hackage-info ]);
cabalAndOrmolu = pkgs.mkShell {
buildInputs = [
(hsPkgs.tool "cabal" "latest")
ormoluExe
];
};
};
hackage = ormolizedPackages false;
hackageTests = with pkgs.lib; pkgs.recurseIntoAttrs (
let ps = [
"Agda"
"QuickCheck"
"ShellCheck"
"aeson"
"attoparsec"
"aws"
"brick"
"brittany"
"capability"
"cassava"
"conduit"
"cryptonite"
"diagrams-core"
"distributed-process"
"esqueleto"
"fay"
"graphql-engine"
"hakyll"
"haxl"
"hedgehog"
"hledger"
"hlint"
"http-client"
"idris"
"intero"
"leksah"
"lens"
"megaparsec"
"optics"
"pandoc"
"parsec3"
"pipes"
"postgrest"
"purescript"
"raaz"
"servant"
"servant-server"
"stack"
"tensorflow"
"text_2_0"
"tls"
"unpacked-containers"
"yesod-core"
];
in listToAttrs (map (p: nameValuePair p (ormolizedPackages true).${p}) ps)
);
regionTests = pkgs.stdenv.mkDerivation {
name = "ormolu-region-tests";
src = ./region-tests;
buildInputs = [
ormoluExe
pkgs.diffutils
];
doCheck = true;
buildPhase = ''
cp src.hs result-all-implicit.hs
ormolu --check-idempotence --mode inplace result-all-implicit.hs
cp src.hs result-all-explicit.hs
ormolu --check-idempotence --mode inplace --start-line 1 --end-line 18 result-all-explicit.hs
cp src.hs result-only-start.hs
ormolu --check-idempotence --mode inplace --start-line 1 result-only-start.hs
cp src.hs result-only-end.hs
ormolu --check-idempotence --mode inplace --end-line 18 result-only-end.hs
cp src.hs result-6-7.hs
ormolu --check-idempotence --mode inplace --start-line 6 --end-line 7 result-6-7.hs
cp src.hs result-6-8.hs
ormolu --check-idempotence --mode inplace --start-line 6 --end-line 8 result-6-8.hs
cp src.hs result-9-12.hs
ormolu --check-idempotence --mode inplace --start-line 9 --end-line 12 result-9-12.hs
cp src.hs result-17-18.hs
ormolu --check-idempotence --mode inplace --start-line 17 --end-line 18 result-17-18.hs
'';
checkPhase = ''
echo result-all-implicit.hs
diff --color=always expected-result-all.hs result-all-implicit.hs
echo result-all-explicit.hs
diff --color=always expected-result-all.hs result-all-explicit.hs
echo result-only-start.hs
diff --color=always expected-result-all.hs result-only-start.hs
echo result-only-end.hs
diff --color=always expected-result-all.hs result-only-end.hs
echo result-6-7.hs
diff --color=always expected-result-6-7.hs result-6-7.hs
echo result-6-8.hs
diff --color=always expected-result-6-8.hs result-6-8.hs
echo result-9-12.hs
diff --color=always expected-result-9-12.hs result-9-12.hs
echo result-17-18.hs
diff --color=always expected-result-17-18.hs result-17-18.hs
'';
installPhase = ''
mkdir "$out"
find . -name '*.hs' -exec cp --parents {} $out \;
'';
};
fixityTests = pkgs.stdenv.mkDerivation {
name = "ormolu-fixity-tests";
src = ./fixity-tests;
buildInputs = [
ormoluExe
pkgs.diffutils
];
doCheck = true;
buildPhase = ''
cp test-0-input.hs test-0-no-extra-info.hs
ormolu --check-idempotence --mode inplace --no-cabal test-0-no-extra-info.hs
cp test-0-input.hs test-0-with-fixity-info-manual.hs
ormolu --check-idempotence --mode inplace --no-cabal --fixity 'infixr 8 .=' test-0-with-fixity-info-manual.hs
cp test-0-input.hs test-0-with-fixity-info-dotormolu.hs
ormolu --check-idempotence --mode inplace test-0-with-fixity-info-dotormolu.hs
cp test-1-input.hs test-1-no-extra-info.hs
ormolu --check-idempotence --mode inplace --no-cabal test-1-no-extra-info.hs
cp test-1-input.hs test-1-with-fixity-info-manual.hs
ormolu --check-idempotence --mode inplace --no-cabal --fixity 'infixr 8 .=' --fixity 'infixr 5 #' test-1-with-fixity-info-manual.hs
cp test-1-input.hs test-1-with-fixity-info-dotormolu.hs
ormolu --check-idempotence --mode inplace test-1-with-fixity-info-dotormolu.hs
'';
checkPhase = ''
echo test-0-no-extra-info.hs
diff --color=always test-0-no-extra-info-expected.hs test-0-no-extra-info.hs
echo test-0-with-fixity-info-manual.hs
diff --color=always test-0-with-fixity-info-expected.hs test-0-with-fixity-info-manual.hs
echo test-0-with-fixity-info-dotormolu.hs
diff --color=always test-0-with-fixity-info-expected.hs test-0-with-fixity-info-dotormolu.hs
echo test-1-no-extra-info.hs
diff --color=always test-1-no-extra-info-expected.hs test-1-no-extra-info.hs
echo test-1-with-fixity-info-manual.hs
diff --color=always test-1-with-fixity-info-expected.hs test-1-with-fixity-info-manual.hs
echo test-1-with-fixity-info-dotormolu.hs
diff --color=always test-1-with-fixity-info-expected.hs test-1-with-fixity-info-dotormolu.hs
'';
installPhase = ''
mkdir "$out"
find . -name '*.hs' -exec cp --parents {} $out \;
'';
};
binaries = {
Linux = hsPkgs.projectCross.musl64.hsPkgs.ormolu.components.exes.ormolu;
macOS = pkgs.runCommand "ormolu-macOS" {
buildInputs = [ pkgs.macdylibbundler ];
} ''
mkdir -p $out/bin
cp ${ormoluExe}/bin/ormolu $out/bin/ormolu
chmod 755 $out/bin/ormolu
dylibbundler -b \
-x $out/bin/ormolu \
-d $out/bin \
-p '@executable_path'
'';
Windows = hsPkgs.projectCross.mingwW64.hsPkgs.ormolu.components.exes.ormolu;
};
} // pkgs.lib.optionalAttrs (pkgs.lib.hasPrefix "ghc810" ormoluCompiler) {
inherit extractHackageInfo;
weeder = pkgs.runCommand
"ormolu-weeder" {
buildInputs = [
ormoluExe
# Weeder >= 2.3 requires an ugly workaround:
# https://github.com/ocharles/weeder/pull/81
(hsPkgs.tool "weeder" "2.2.0")
];
} ''
mkdir -p $out
export XDG_CACHE_HOME=$TMPDIR/cache
weeder --config ${./weeder.dhall} \
--hie-directory ${ormoluLib.hie} \
--hie-directory ${ormoluExe.hie} \
--hie-directory ${ormolu.components.tests.tests.hie}
'';
ormoluLive = {
inherit ormoluLive;
website = pkgs.stdenv.mkDerivation {
name = "ormolu-live-website";
src = pkgs.haskell-nix.haskellLib.cleanGit {
name = "ormolu-live-www";
src = ./.;
subDir = "ormolu-live/www";
};
buildInputs = [ pkgs.closurecompiler ];
installPhase = ''
cp -r . $out
ORMOLU_LIVE=${ormoluLive}/bin/ormolu-live.jsexe
closure-compiler \
$ORMOLU_LIVE/all.js --externs $ORMOLU_LIVE/all.js.externs \
-O ADVANCED --jscomp_off=checkVars -W QUIET \
--js_output_file $out/all.min.js
'';
};
};
}