Skip to content

Commit

Permalink
feat(hooks): add additional cargo-options
Browse files Browse the repository at this point in the history
  • Loading branch information
sivizius committed Oct 8, 2024
1 parent 1211305 commit 4c0e110
Show file tree
Hide file tree
Showing 6 changed files with 711 additions and 139 deletions.
150 changes: 11 additions & 139 deletions modules/hooks.nix
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
{ config, lib, pkgs, hookModule, ... }:
let
inherit (config) hooks tools settings;
inherit (config) hooks tools;
cfg = config;
inherit (lib) flatten mapAttrs mapAttrsToList mkDefault mkOption mkRemovedOptionModule mkRenamedOptionModule types;

cargoManifestPathArg =
lib.optionalString
(settings.rust.cargoManifestPath != null)
"--manifest-path ${lib.escapeShellArg settings.rust.cargoManifestPath}";

mkCmdArgs = predActionList:
lib.concatStringsSep
" "
Expand Down Expand Up @@ -76,7 +71,8 @@ in

# PLEASE keep this sorted alphabetically.
options.hooks =
{
import ./rust/options.nix { inherit config lib hookModule; }
// {
alejandra = mkOption {
description = "alejandra hook";
type = types.submodule {
Expand Down Expand Up @@ -201,50 +197,6 @@ in
};
};
};
clippy = mkOption {
description = "clippy hook";
type = types.submodule
({ config, ... }: {
imports = [ hookModule ];
options.packageOverrides = {
cargo = mkOption {
type = types.package;
description = "The cargo package to use";
};
clippy = mkOption {
type = types.package;
description = "The clippy package to use";
};
};
options.settings = {
denyWarnings = mkOption {
type = types.bool;
description = "Fail when warnings are present";
default = false;
};
offline = mkOption {
type = types.bool;
description = "Run clippy offline";
default = true;
};
allFeatures = mkOption {
type = types.bool;
description = "Run clippy with --all-features";
default = false;
};
extraArgs = mkOption {
type = types.str;
description = "Additional arguments to pass to clippy";
default = "";
};
};

config.extraPackages = [
config.packageOverrides.cargo
config.packageOverrides.clippy
];
});
};
cmake-format = mkOption {
description = "cmake-format hook";
type = types.submodule {
Expand Down Expand Up @@ -1372,37 +1324,6 @@ in
};
};
};
rustfmt = mkOption {
description = ''
Additional rustfmt settings
Override the `rustfmt` and `cargo` packages by setting `hooks.rustfmt.packageOverrides`.
```
hooks.rustfmt.packageOverrides.cargo = pkgs.cargo;
hooks.rustfmt.packageOverrides.rustfmt = pkgs.rustfmt;
```
'';
type = types.submodule
({ config, ... }: {
imports = [ hookModule ];
options.packageOverrides = {
cargo = mkOption {
type = types.package;
description = "The cargo package to use.";
};
rustfmt = mkOption {
type = types.package;
description = "The rustfmt package to use.";
};
};

config.extraPackages = [
config.packageOverrides.cargo
config.packageOverrides.rustfmt
];
});
};
shfmt = mkOption {
description = "shfmt hook";
type = types.submodule {
Expand Down Expand Up @@ -1738,8 +1659,10 @@ in
};
};

config.assertions = import ./rust/assertions.nix { inherit config lib; };
config.warnings =
lib.optional cfg.hooks.rome.enable ''
import ./rust/warnings.nix { inherit config lib; }
++ lib.optional cfg.hooks.rome.enable ''
The hook `hooks.rome` has been renamed to `hooks.biome`.
''
++ lib.optional cfg.hooks.nixfmt.enable ''
Expand All @@ -1749,8 +1672,9 @@ in
'';

# PLEASE keep this sorted alphabetically.
config.hooks = mapAttrs (_: mapAttrs (_: mkDefault))
rec {
config.hooks = mapAttrs (_: mapAttrs (_: mkDefault)) (
import ./rust/config.nix { inherit config lib pkgs; }
// rec {
actionlint =
{
name = "actionlint";
Expand Down Expand Up @@ -1889,15 +1813,6 @@ in
entry = "${hooks.cabal2nix.package}/bin/cabal2nix-dir";
files = "\\.cabal$";
};
cargo-check =
{
name = "cargo-check";
description = "Check the cargo package for errors";
package = tools.cargo;
entry = "${hooks.cargo-check.package}/bin/cargo check ${cargoManifestPathArg}";
files = "\\.rs$";
pass_filenames = false;
};
checkmake = {
name = "checkmake";
description = "Experimental linter/analyzer for Makefiles";
Expand Down Expand Up @@ -2060,28 +1975,6 @@ in
entry = "${hooks.clang-tidy.package}/bin/clang-tidy --fix";
types_or = [ "c" "c++" "c#" "objective-c" ];
};
clippy =
let
inherit (hooks.clippy) packageOverrides;
wrapper = pkgs.symlinkJoin {
name = "clippy-wrapped";
paths = [ packageOverrides.clippy ];
nativeBuildInputs = [ pkgs.makeWrapper ];
postBuild = ''
wrapProgram $out/bin/cargo-clippy \
--prefix PATH : ${lib.makeBinPath [ packageOverrides.cargo ]}
'';
};
in
{
name = "clippy";
description = "Lint Rust code.";
package = wrapper;
packageOverrides = { cargo = tools.cargo; clippy = tools.clippy; };
entry = "${hooks.clippy.package}/bin/cargo-clippy clippy ${cargoManifestPathArg} ${lib.optionalString hooks.clippy.settings.offline "--offline"} ${lib.optionalString hooks.clippy.settings.allFeatures "--all-features"} ${hooks.clippy.settings.extraArgs} -- ${lib.optionalString hooks.clippy.settings.denyWarnings "-D warnings"}";
files = "\\.rs$";
pass_filenames = false;
};
cljfmt =
{
name = "cljfmt";
Expand Down Expand Up @@ -3259,28 +3152,6 @@ lib.escapeShellArgs (lib.concatMap (ext: [ "--ghc-opt" "-X${ext}" ]) hooks.ormol
entry = "${hooks.ruff.package}/bin/ruff format";
types = [ "python" ];
};
rustfmt =
let
inherit (hooks.rustfmt) packageOverrides;
wrapper = pkgs.symlinkJoin {
name = "rustfmt-wrapped";
paths = [ packageOverrides.rustfmt ];
nativeBuildInputs = [ pkgs.makeWrapper ];
postBuild = ''
wrapProgram $out/bin/cargo-fmt \
--prefix PATH : ${lib.makeBinPath [ packageOverrides.cargo packageOverrides.rustfmt ]}
'';
};
in
{
name = "rustfmt";
description = "Format Rust code.";
package = wrapper;
packageOverrides = { cargo = tools.cargo; rustfmt = tools.rustfmt; };
entry = "${hooks.rustfmt.package}/bin/cargo-fmt fmt ${cargoManifestPathArg} --all -- --color always";
files = "\\.rs$";
pass_filenames = false;
};
shellcheck =
{
name = "shellcheck";
Expand Down Expand Up @@ -3640,5 +3511,6 @@ lib.escapeShellArgs (lib.concatMap (ext: [ "--ghc-opt" "-X${ext}" ]) hooks.ormol
types_or = [ "clojure" "clojurescript" "edn" ];
};

};
}
);
}
75 changes: 75 additions & 0 deletions modules/rust/assertions.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
{ config, lib, ... }:

let
cargoHooks = { inherit (config.hooks) cargo-bench cargo-check cargo-test clippy; };

forAllCargoHooks = assertions:
lib.mapAttrsToList
(hook: { settings, ... }: assertions "${hook}.settings" settings)
cargoHooks;
in
[ ]
++ forAllCargoHooks (hook: { profile ? null, release ? false, ... }: {
assertion = release -> profile == null;
message = "Options `${hook}.release` and `${hook}.profile` are mutually exclusive";
})
++ forAllCargoHooks (hook: { exclude ? [ ], workspace ? false, ... }: {
assertion = exclude != [ ] -> workspace;
message = "Option `${hook}.exclude` requires `${hook}.workspace == true`";
})
++ forAllCargoHooks (hook: { package ? [ ], workspace ? false, ... }: {
assertion = package != [ ] -> workspace;
message = "Option `${hook}.package` requires `${hook}.workspace == true`";
})
++ forAllCargoHooks (hook: { bench ? [ ], benches ? false, ... }: {
assertion = benches -> bench == [ ];
message = "Options `${hook}.bench` and `${hook}.benches` are mutually exclusive";
})
++ forAllCargoHooks (hook: { bin ? [ ], bins ? false, ... }: {
assertion = bins -> bin == [ ];
message = "Options `${hook}.bin` and `${hook}.bins` are mutually exclusive";
})
++ forAllCargoHooks (hook: { example ? [ ], examples ? false, ... }: {
assertion = examples -> example == [ ];
message = "Options `${hook}.example` and `${hook}.examples` are mutually exclusive";
})
++ forAllCargoHooks (hook: { test ? [ ], tests ? false, ... }: {
assertion = tests -> test == [ ];
message = "Options `${hook}.test` and `${hook}.tests` are mutually exclusive";
})
++ forAllCargoHooks (
hook:
{ all-targets ? false
, bench ? [ ]
, benches ? false
, bin ? [ ]
, bins ? false
, example ? [ ]
, examples ? false
, lib ? false
, test ? [ ]
, tests ? false
, ...
}: {
assertion = all-targets -> (
!lib
&& bench == [ ] && !benches
&& bin == [ ] && !bins
&& example == [ ] && !examples
&& test == [ ] && !tests
);
message = "The `${hook}.all-targets` option and other target options are mutually exclusive";
}
)
++ forAllCargoHooks (hook: { all-features ? false, features ? [ ], ... }: {
assertion = all-features -> features == [ ];
message = "Options `${hook}.all-features` and `${hook}.features` are mutually exclusive";
})
++ forAllCargoHooks (hook: { all-features ? false, no-default-features ? false, ... }: {
assertion = all-features -> !no-default-features;
message = "Options `${hook}.all-features` and `${hook}.no-default-features` are mutually exclusive";
})
++ forAllCargoHooks (hook: { frozen ? false, locked ? false, ... }: {
assertion = locked -> !frozen;
message = "Options `${hook}.locked` and `${hook}.frozen` are mutually exclusive";
})
Loading

0 comments on commit 4c0e110

Please sign in to comment.