Commit 5555def5 authored by MatthewCroughan's avatar MatthewCroughan
Browse files

Merge branch 'staging' into 'overengineered'

Merge staging into overengineered

See merge request nix/lint-utils!8
parents 09fb5bb7 727e661a
......@@ -8,12 +8,19 @@
let
pkgs = nixpkgs.legacyPackages.${system};
lib = import ./lib.nix { inherit pkgs; };
in
{
apps = lib.apps;
linters = lib.linters;
checks = {
nixpkgs-fmt = lib.linters.nixpkgs-fmt ./.;
# Linting done by this project (lint-utils.git) itself.
projectLinters = {
nixpkgs-fmt = { };
};
in
rec {
mkConcatShellWithNamePrefix = lib.mkConcatShellWithNamePrefix;
mkShellWithNamePrefix = lib.mkShellWithNamePrefix;
mkShell = lib.mkShell;
mkApp = lib.mkApp;
mkChecks = lib.mkChecks;
apps.format = lib.mkApp projectLinters;
checks = lib.mkChecks projectLinters ./.;
});
}
{ pkgs }:
let
attrsets = pkgs.lib.attrsets;
in
rec {
porcelainOrDieScript = cmd: advice: pkgs.writers.writeBashBin "lint" ''
......@@ -28,86 +31,125 @@ rec {
'';
};
lint-app = app: {
lint-app = name: app: {
type = "app";
program = "${app}/bin/lint";
program = "${app}/bin/${name}";
};
lint-bin = cmd: pkgs.writers.writeBashBin "lint" cmd;
lint-bin = name: cmd: pkgs.writers.writeBashBin name cmd;
cabal-fmt = lint-bin
"find . -name '*.cabal' | xargs ${pkgs.haskellPackages.cabal-fmt}/bin/cabal-fmt -i";
lint-bin-prefix = name: cmd: prefix: pkgs.writers.writeBashBin "${prefix}-${name}" cmd;
dhall-format = lint-bin
"find . -name '*.dhall' | xargs -I{} ${pkgs.dhall}/bin/dhall format {} --unicode";
nixpkgs-fmt = lint-bin
"find . -name '*.nix' | xargs ${pkgs.nixpkgs-fmt}/bin/nixpkgs-fmt";
hpack = lint-bin
"find . -name 'package.yaml' | xargs ${pkgs.hpack}/bin/hpack";
fourmoluWithOpts = opts: lint-bin
"find . -name '*.hs' | xargs ${pkgs.haskellPackages.fourmolu}/bin/fourmolu -m inplace ${opts}";
ormoluWithOpts = opts: lint-bin
"find . -name '*.hs' | xargs ${pkgs.ormolu}/bin/ormolu -i ${opts}";
ormoluStandardGhc8107 = ormoluWithOpts "-o-XTypeApplications";
fourmoluStandardGhc8107 = fourmoluWithOpts "-o-XTypeApplications";
ormoluStandardGhc921 = ormoluWithOpts "-o-XTypeApplications -o-XQualifiedDo -o-XOverloadedRecordDot";
fourmoluStandardGhc921 = fourmoluWithOpts "-o-XTypeApplications -o-XQualifiedDo -o-XOverloadedRecordDot";
stylish-haskell = lint-bin
"find . -name '*.hs' | xargs ${pkgs.stylish-haskell}/bin/stylish-haskell -i";
lint-prefix = name: cmd: prefix: pkgs.writers.writeBash "${prefix}-${name}" cmd;
lint-error = name: app:
"Found errors with ${name}, try running ${app}/bin/lint";
"Found errors with ${name}, try running ${app}/bin/${name}";
porcelainLinter = name: app: src:
porcelainOrDie src name "${app}/bin/lint" (lint-error name app);
hlint = src: pkgs.stdenv.mkDerivation {
name = "hlint";
src = src;
meta = { description = "Run hlint"; };
dontBuild = true;
installPhase = ''
${pkgs.hlint}/bin/hlint | tee $out
'';
};
apps = {
cabal-fmt = lint-app cabal-fmt;
dhall-format = lint-app dhall-format;
fourmolu = opts: lint-app (fourmoluWithOpts opts);
fourmoluStandardGhc8107 = lint-app fourmoluStandardGhc8107;
fourmoluStandardGhc921 = lint-app fourmoluStandardGhc921;
hpack = lint-app hpack;
nixpkgs-fmt = lint-app nixpkgs-fmt;
ormolu = opts: lint-app (ormoluWithOpts opts);
ormoluStandardGhc8107 = lint-app ormoluStandardGhc8107;
ormoluStandardGhc921 = lint-app ormoluStandardGhc921;
stylish-haskell = lint-app stylish-haskell;
};
linters = {
cabal-fmt = porcelainLinter "cabal-fmt" cabal-fmt;
dhall-format = porcelainLinter "dhall-format" dhall-format;
fourmolu = src: opts: porcelainLinter "fourmolu" (fourmoluWithOpts opts) src;
fourmoluStandardGhc8107 = porcelainLinter "fourmolu-standard-ghc-8107" fourmoluStandardGhc8107;
fourmoluStandardGhc921 = porcelainLinter "fourmolu-standard-ghc-921" fourmoluStandardGhc921;
hlint = hlint;
hpack = porcelainLinter "hpack" hpack;
nixpkgs-fmt = porcelainLinter "nixpkgs-fmt" nixpkgs-fmt;
ormolu = src: opts: porcelainLinter "ormolu" (ormoluWithOpts opts) src;
ormoluStandardGhc8107 = porcelainLinter "ormolu-standard-ghc-8107" ormoluStandardGhc8107;
ormoluStandardGhc921 = porcelainLinter "ormolu-standard-ghc-921" ormoluStandardGhc921;
stylish-haskell = porcelainLinter "stylish-haskell" stylish-haskell;
porcelainOrDie src name "${app}/bin/${name}" (lint-error name app);
cli = {
cabal-fmt = opts:
"find . -name '*.cabal' | xargs ${pkgs.haskellPackages.cabal-fmt}/bin/cabal-fmt -i";
dhall-format = opts:
"find . -name '*.dhall' | xargs -I{} ${pkgs.dhall}/bin/dhall format {} --unicode";
nixpkgs-fmt = opts:
"find . -name '*.nix' | xargs ${pkgs.nixpkgs-fmt}/bin/nixpkgs-fmt";
hpack = opts:
"find . -name 'package.yaml' | xargs ${pkgs.hpack}/bin/hpack";
fourmolu = opts:
let ghcOpts = attrsets.attrByPath [ "ghcOpts" ] "" opts;
in "find . -name '*.hs' | xargs ${pkgs.haskellPackages.fourmolu}/bin/fourmolu -m inplace ${ghcOpts}";
ormolu = opts:
let ghcOpts = attrsets.attrByPath [ "ghcOpts" ] "" opts;
in "find . -name '*.hs' | xargs ${pkgs.ormolu}/bin/ormolu -i ${ghcOpts}";
stylish-haskell = opts:
"find . -name '*.hs' | xargs ${pkgs.stylish-haskell}/bin/stylish-haskell -i";
hlint = opts:
let path = attrsets.attrByPath [ "path" ] "." opts;
in "${pkgs.hlint}/bin/hlint ${path}";
};
getCli = name: opts: (builtins.getAttr name cli opts);
# Make a shell from the given lint spec and prefix the script names with a
# string, useful for tab completing and discoverability.
#
# Example:
# mkShellWithNamePrefix { cabal-fmt = { # extra arguments } } "myProjectName"
#
mkShellWithNamePrefix = lintSpec: prefix:
let
getDrv = name: args: lint-bin-prefix name (getCli name args) prefix;
in
pkgs.mkShell { buildInputs = [ (attrsets.mapAttrsToList getDrv lintSpec) ]; };
# Make a shell from the given lint spec and concatenate all linters into a
# single shell script to be ran consecutively. The script name is prefixed
# with a string, useful for tab completing and discoverability.
#
# Example:
# mkConcatShellWithNamePrefix { cabal-fmt = { # extra arguments } } "myProjectName"
#
mkConcatShellWithNamePrefix = lintSpec: prefix:
let
getDrv = name: args: lint-prefix name (getCli name args) prefix;
listOfLinters = (attrsets.mapAttrsToList getDrv lintSpec);
concatLinters = linters:
checkedDerivation "${prefix}-lint"
(pkgs.lib.strings.concatMapStringsSep
"\n"
(linter: linter)
linters);
in
pkgs.mkShell { buildInputs = [ (concatLinters listOfLinters) ]; };
# Make a shell from the given lint spec.
#
# Example:
# mkShell { cabal-fmt = { # extra arguments } }
#
mkShell = lintSpec:
let
getDrv = name: args: lint-bin name (getCli name args);
in
pkgs.mkShell { buildInputs = [ (attrsets.mapAttrsToList getDrv lintSpec) ]; };
# Make a flake app from the given lint spec.
mkApp = lintSpec:
let
getApp = name: args: lint-app name (lint-bin name (getCli name args));
in
concatApps (attrsets.mapAttrsToList getApp lintSpec);
# Make a set of flake checks from the given lint spec.
mkChecks = lintSpec: src:
let
getCheck = name: args: porcelainLinter name (lint-bin name (getCli name args)) src;
in
attrsets.mapAttrs getCheck lintSpec;
# Concat a list of Flake apps to produce a new app that runs all of them
# in sequence.
concatApps = apps:
{
type = "app";
program = checkedShellScript "concatApps"
(pkgs.lib.strings.concatMapStringsSep
"\n"
(app: app.program)
apps);
};
# Checks the derivation using ShellCheck
checkedDerivation = name: text:
(pkgs.writeShellApplication {
inherit name text;
});
# Checks the shell script using ShellCheck
checkedShellScript = name: text:
(pkgs.writeShellApplication {
inherit name text;
}) + "/bin/${name}";
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment