Skip to content

Commit c2b908c

Browse files
committed
fix(nix): use a separate option for nested devshell configurations
1 parent 58dfe24 commit c2b908c

File tree

11 files changed

+161
-122
lines changed

11 files changed

+161
-122
lines changed

flake.nix

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,21 +63,21 @@
6363
);
6464

6565
devShells = eachSystem (
66-
{ devshell, ... }:
66+
{ devshell, system, ... }:
6767
{
6868
default = devshell.mkShell {
6969
bash.extra = ''
7070
export MDBOOK_SERVER_ADDRESS="http://localhost:3000"
7171
'';
72-
commands = {
72+
commandGroups = {
7373
packages = [
7474
"diffutils" # used by golangci-lint
7575
"goreleaser"
7676
];
7777
scripts = [
7878
{
7979
prefix = "nix run .#";
80-
inherit packages;
80+
packages = packages.${system};
8181
helps.docs = ''Run mdBook server at "$MDBOOK_SERVER_ADDRESS"'';
8282
interpolates.docs = true;
8383
}
@@ -89,7 +89,7 @@
8989
utilites = [
9090
[
9191
"GitHub utility"
92-
"gitAndTools.hub"
92+
"hub"
9393
]
9494
[
9595
"golang linter"
@@ -111,10 +111,10 @@
111111
}
112112
);
113113

114-
apps.default = devShells.default.flakeApp;
114+
# apps.default = devShells.default.flakeApp;
115115

116116
checks = eachSystem (
117-
{ pkgs, ... }:
117+
{ devshell, pkgs, ... }:
118118
with pkgs.lib;
119119
pipe { } [
120120
(

modules/commands.nix

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,43 @@
77
}:
88
let
99
inherit (import ../nix/commands/lib.nix { inherit pkgs options config; })
10-
commandsType
11-
commandToPackage
10+
commandsFlatType
11+
commandsNestedType
12+
normalizeCommandsFlat
13+
normalizeCommandsNested
1214
devshellMenuCommandName
15+
commandToPackage
1316
commandsToMenu
1417
;
1518
in
1619
{
1720
options.commands = lib.mkOption {
18-
type = commandsType;
21+
type = commandsFlatType;
1922
default = [ ];
2023
description = ''
2124
Add commands to the environment.
2225
'';
26+
example = lib.literalExpression ''
27+
[
28+
{
29+
help = "print hello";
30+
name = "hello";
31+
command = "echo hello";
32+
}
33+
{
34+
package = "nixfmt";
35+
category = "formatter";
36+
}
37+
]
38+
'';
39+
};
40+
41+
options.commandGroups = lib.mkOption {
42+
type = commandsNestedType;
43+
default = { };
44+
description = ''
45+
Add commands to the environment.
46+
'';
2347
example = lib.literalExpression ''
2448
{
2549
packages = [
@@ -37,7 +61,7 @@ in
3761
}
3862
];
3963
utilites = [
40-
[ "GitHub utility" "gitAndTools.hub" ]
64+
[ "GitHub utility" "hub" ]
4165
[ "golang linter" "golangci-lint" ]
4266
];
4367
}
@@ -48,13 +72,18 @@ in
4872
{
4973
help = "prints this menu";
5074
name = devshellMenuCommandName;
51-
command = commandsToMenu config.devshell.menu config.commands;
75+
command = commandsToMenu config.devshell.menu config.devshell.commands;
5276
}
5377
];
5478

79+
config.devshell.commands =
80+
normalizeCommandsFlat config.commands ++ normalizeCommandsNested config.commandGroups;
81+
5582
# Add the commands to the devshell packages. Either as wrapper scripts, or
5683
# the whole package.
57-
config.devshell.packages = lib.filter (x: x != null) (map commandToPackage config.commands);
84+
config.devshell.packages = lib.filter (x: x != null) (
85+
map commandToPackage config.devshell.commands
86+
);
5887

5988
# config.devshell.motd = "$(motd)";
6089
}

modules/devshell.nix

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@ let
1919
# environment.
2020
strOrPackage = import ../nix/strOrPackage.nix { inherit lib pkgs; };
2121

22-
inherit (import ../nix/commands/lib.nix { inherit pkgs options; }) devshellMenuCommandName;
22+
inherit (import ../nix/commands/lib.nix { inherit pkgs options; })
23+
devshellMenuCommandName
24+
commandsFlatType
25+
;
2326

2427
# Use this to define a flake app for the environment.
2528
mkFlakeApp = bin: {
@@ -319,6 +322,15 @@ in
319322
'';
320323
};
321324

325+
commands = mkOption {
326+
type = commandsFlatType;
327+
internal = true;
328+
default = [ ];
329+
description = ''
330+
Merged normalized `commands` and `commandGroups`.
331+
'';
332+
};
333+
322334
packages = mkOption {
323335
type = types.listOf strOrPackage;
324336
default = [ ];

modules/modules-docs.nix

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,6 @@ let
122122
inherit (import ../nix/commands/lib.nix { inherit pkgs options; })
123123
mkLocSuffix
124124
nestedOptionsType
125-
flatOptionsType
126125
;
127126

128127
# TODO: display values like TOML instead.

nix/commands/commandsType.nix

Lines changed: 58 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -3,30 +3,36 @@
33
pkgs ? import ../nixpkgs.nix { inherit system; },
44
options ? { },
55
}:
6-
with pkgs.lib;
7-
with builtins;
86
let
7+
inherit (builtins)
8+
concatStringsSep
9+
hasAttr
10+
head
11+
isAttrs
12+
isList
13+
isString
14+
;
15+
16+
inherit (pkgs.lib)
17+
attrByPath
18+
collect
19+
flatten
20+
isDerivation
21+
last
22+
mapAttrsRecursiveCond
23+
mapAttrsToList
24+
parseDrvName
25+
pipe
26+
;
27+
28+
inherit (pkgs.lib.options) unknownModule;
29+
930
inherit (import ./types.nix { inherit pkgs options; })
1031
commandsFlatType
1132
commandsNestedType
1233
resolveKey
1334
strOrPackage
1435
;
15-
in
16-
rec {
17-
mergeDefs =
18-
loc: defs:
19-
let
20-
t1 = commandsFlatType;
21-
t2 = commandsNestedType;
22-
defsFlat = t1.merge loc (map (d: d // { value = if isList d.value then d.value else [ ]; }) defs);
23-
defsNested = t2.merge loc (
24-
map (d: d // { value = if !(isList d.value) then d.value else { }; }) defs
25-
);
26-
in
27-
{
28-
inherit defsFlat defsNested;
29-
};
3036

3137
extractHelp = arg: if isList arg then head arg else null;
3238

@@ -55,15 +61,13 @@ rec {
5561
else
5662
alternative;
5763

58-
normalizeCommandsFlat_ =
64+
mergeCommandsFlat =
5965
{
60-
file ? unknownModule,
66+
arg,
6167
loc ? [ ],
62-
arg ? [ ],
68+
file ? unknownModule,
6369
}:
6470
pipe arg [
65-
(value: (mergeDefs loc [ { inherit file value; } ]).defsFlat)
66-
(map (config: flattenNonAttrsOrElse config config))
6771
flatten
6872
(map (value: {
6973
inherit file;
@@ -72,6 +76,10 @@ rec {
7276
(commandsFlatType.merge loc)
7377
];
7478

79+
normalizeCommandsFlat' = map (config: flattenNonAttrsOrElse config config);
80+
81+
normalizeCommandsFlat = arg: mergeCommandsFlat { arg = normalizeCommandsFlat' arg; };
82+
7583
highlyUnlikelyAttrName = "adjd-laso-msle-copq-pcod";
7684

7785
collectLeaves =
@@ -89,15 +97,21 @@ rec {
8997
(map (x: x.${highlyUnlikelyAttrName}))
9098
];
9199

92-
normalizeCommandsNested_ =
93-
{
94-
file ? unknownModule,
95-
loc ? [ ],
96-
arg ? { },
97-
}:
100+
normalizeCommandsNested' =
101+
arg:
98102
pipe arg [
99103
# typecheck and augment configs with missing attributes (if a config is an attrset)
100-
(value: (mergeDefs loc [ { inherit file value; } ]).defsNested)
104+
(
105+
x:
106+
commandsNestedType.merge
107+
[ ]
108+
[
109+
{
110+
file = unknownModule;
111+
value = x;
112+
}
113+
]
114+
)
101115
(mapAttrsToList (
102116
category:
103117
map (
@@ -166,44 +180,21 @@ rec {
166180
)
167181
)
168182
))
169-
flatten
170-
(map (value: {
171-
inherit file;
172-
value = [ value ];
173-
}))
174-
(commandsFlatType.merge loc)
175183
];
176184

177-
normalizeCommandsNested = arg: normalizeCommandsNested_ { inherit arg; };
178-
179-
commandsType =
180-
let
181-
t1 = commandsFlatType;
182-
t2 = commandsNestedType;
183-
either = types.either t1 t2;
184-
in
185-
either
186-
// rec {
187-
name = "commandsType";
188-
description = "(${t1.description}) or (${t2.description})";
189-
merge =
190-
loc: defs:
191-
let
192-
inherit (mergeDefs loc defs) defsFlat defsNested;
193-
defsFlatNormalized = normalizeCommandsFlat_ {
194-
arg = defsFlat;
195-
inherit loc;
196-
};
197-
defsNestedNormalized = normalizeCommandsNested_ {
198-
arg = defsNested;
199-
inherit loc;
200-
};
201-
defsMerged = defsFlatNormalized ++ defsNestedNormalized;
202-
in
203-
defsMerged;
204-
getSubOptions = prefix: {
205-
"${t1.name}" = t1.getSubOptions prefix;
206-
"${t2.name}" = t2.getSubOptions prefix;
207-
};
208-
};
185+
normalizeCommandsNested = arg: mergeCommandsFlat { arg = normalizeCommandsNested' arg; };
186+
in
187+
{
188+
inherit
189+
extractHelp
190+
resolveName
191+
flattenNonAttrsOrElse
192+
highlyUnlikelyAttrName
193+
collectLeaves
194+
mergeCommandsFlat
195+
normalizeCommandsFlat'
196+
normalizeCommandsFlat
197+
normalizeCommandsNested'
198+
normalizeCommandsNested
199+
;
209200
}

nix/commands/devshell.nix

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,8 +122,6 @@ rec {
122122
...
123123
}:
124124
let
125-
len = maxCommandLength - (lib.stringLength name);
126-
127125
nameWidth = toString maxCommandLength;
128126
helpWidth = toString (config.devshell.menu.width - (maxCommandLength + 5));
129127
helpHeight = toString 100;

nix/commands/flatOptions.nix

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,16 +20,13 @@ in
2020

2121
name = mkOption {
2222
type = types.nullOr (
23-
types.str
24-
// (
25-
let
26-
regex = "[^$\r\n]+";
27-
in
28-
{
29-
description = "string matching ${regex}";
30-
check = x: lib.isString x && match regex x != null;
31-
}
32-
)
23+
let
24+
regex = "[^$\r\n]+";
25+
in
26+
lib.types.addCheck types.str (x: lib.isString x && match regex x != null)
27+
// {
28+
description = "string matching ${regex}";
29+
}
3330
);
3431
default = null;
3532
description = ''

0 commit comments

Comments
 (0)