Skip to content

Commit 3090b26

Browse files
committed
feat(wrapperModules.direnv): init
style(wrapperModues.direnv): apply nix fmt fix(wrapperModules.direnv): add maintainers feat: use key direnv: add checks refactor tests rework tests use a single drv for tests rework: use nix functions as assertions This way we have a way to join assertions using '&&' and can group assertions. If any assertion fails it will print the error message of the given assertin as well as the name of the test make all tests assertion-based rename functions add documentation add mise integration fix maintainers add env.CONFIG_DIRENV remove "key"-transform hack construcFiles sanitizes the key by default now integrate tests with tlib remove duplicate maintainer entry fix(direnv): avoid IFD when generating TOML
1 parent b1308b5 commit 3090b26

2 files changed

Lines changed: 269 additions & 0 deletions

File tree

wrapperModules/d/direnv/check.nix

Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
{
2+
pkgs,
3+
self,
4+
tlib,
5+
}:
6+
7+
let
8+
inherit (tlib)
9+
fileContains
10+
isDirectory
11+
isFile
12+
notIsFile
13+
test
14+
;
15+
16+
lib = pkgs.lib;
17+
18+
getDotdir =
19+
wrapper:
20+
let
21+
cfg = (wrapper.eval { }).config;
22+
dotdir = "${wrapper}/${cfg.configDirname}";
23+
in
24+
dotdir;
25+
in
26+
test { wrapper = "direnv"; } {
27+
28+
"direnv wrapper should be created" =
29+
let
30+
wrapper = self.wrappers.direnv.wrap {
31+
inherit pkgs;
32+
nix-direnv.enable = true;
33+
};
34+
in
35+
''
36+
"${wrapper}/bin/direnv" --version | grep -q "${wrapper.version}"
37+
'';
38+
39+
"if nix-direnv is enabled then lib/nix-direnv.sh should exists" =
40+
let
41+
wrapper = self.wrappers.direnv.wrap {
42+
inherit pkgs;
43+
nix-direnv.enable = true;
44+
};
45+
in
46+
[
47+
(isDirectory (getDotdir wrapper))
48+
(isFile "${getDotdir wrapper}/lib/nix-direnv.sh")
49+
];
50+
51+
"if nix-direnv is disabled then lib/nix-direnv.sh should not exist" =
52+
let
53+
wrapper = self.wrappers.direnv.wrap {
54+
inherit pkgs;
55+
nix-direnv.enable = false;
56+
};
57+
in
58+
[
59+
(isDirectory (getDotdir wrapper))
60+
(notIsFile "${getDotdir wrapper}/lib/nix-direnv.sh")
61+
];
62+
63+
"if mise is enabled then lib/mise.sh should exists" =
64+
let
65+
wrapper = self.wrappers.direnv.wrap {
66+
inherit pkgs;
67+
mise.enable = true;
68+
};
69+
in
70+
[
71+
(isDirectory (getDotdir wrapper))
72+
(isFile "${getDotdir wrapper}/lib/mise.sh")
73+
];
74+
75+
"if mise is disabled then lib/mise.sh should not exist" =
76+
let
77+
wrapper = self.wrappers.direnv.wrap {
78+
inherit pkgs;
79+
mise.enable = false;
80+
};
81+
in
82+
[
83+
(isDirectory (getDotdir wrapper))
84+
(notIsFile "${getDotdir wrapper}/lib/mise.sh")
85+
];
86+
87+
"if a lib-script is set then it should be generated" =
88+
let
89+
libScriptFile = "${getDotdir wrapper}/lib/foo.sh";
90+
libScriptContent = "echo foo";
91+
wrapper = self.wrappers.direnv.wrap {
92+
inherit pkgs;
93+
lib."foo.sh" = libScriptContent;
94+
};
95+
in
96+
[
97+
(isDirectory (getDotdir wrapper))
98+
(isFile libScriptFile)
99+
(fileContains libScriptFile libScriptContent)
100+
];
101+
102+
"if silent mode is enabled then log settings should be set" =
103+
let
104+
direnvTomlFile = "${getDotdir wrapper}/direnv.toml";
105+
wrapper = self.wrappers.direnv.wrap {
106+
inherit pkgs;
107+
silent = true;
108+
};
109+
in
110+
[
111+
(isDirectory (getDotdir wrapper))
112+
(isFile direnvTomlFile)
113+
(fileContains direnvTomlFile "log_format")
114+
(fileContains direnvTomlFile "log_filter")
115+
116+
];
117+
118+
"if extraConfig is working" =
119+
let
120+
direnvTomlFile = "${getDotdir wrapper}/direnv.toml";
121+
wrapper = self.wrappers.direnv.wrap {
122+
inherit pkgs;
123+
extraConfig = {
124+
fooSection.fooKey = "fooValue";
125+
};
126+
};
127+
in
128+
[
129+
(isDirectory (getDotdir wrapper))
130+
(isFile direnvTomlFile)
131+
(fileContains direnvTomlFile "\\[fooSection\\]")
132+
(fileContains direnvTomlFile "fooKey.*fooValue")
133+
];
134+
135+
"if direnvrc is working" =
136+
let
137+
direnvrcFile = "${getDotdir wrapper}/direnvrc";
138+
direnvrcContent = "echo foo";
139+
140+
wrapper = self.wrappers.direnv.wrap {
141+
inherit pkgs;
142+
direnvrc = direnvrcContent;
143+
};
144+
in
145+
[
146+
(isDirectory (getDotdir wrapper))
147+
(isFile direnvrcFile)
148+
(fileContains direnvrcFile direnvrcContent)
149+
];
150+
}

wrapperModules/d/direnv/module.nix

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
{
2+
config,
3+
lib,
4+
wlib,
5+
pkgs,
6+
...
7+
}:
8+
let
9+
tomlFmt = pkgs.formats.toml { };
10+
direnvDotdir = "${config.wrapper.${config.outputName}}/${config.configDirname}";
11+
in
12+
{
13+
imports = [ wlib.modules.default ];
14+
options = {
15+
configDirname = lib.mkOption {
16+
type = lib.types.str;
17+
default = "${config.binName}-dot-dir";
18+
description = "Name of the directory which is created as the dotdir in the wrapper output";
19+
};
20+
silent = lib.mkEnableOption "silent mode, that is, disabling direnv logging";
21+
direnvrc = lib.mkOption {
22+
type = lib.types.lines;
23+
description = "Content of `$DIRENV_CONFIG/direnv`";
24+
default = "";
25+
};
26+
nix-direnv = {
27+
enable = lib.mkEnableOption "nix-direnv integration";
28+
package = lib.mkPackageOption pkgs "nix-direnv" { };
29+
};
30+
mise = {
31+
enable = lib.mkEnableOption "mise integration";
32+
package = lib.mkPackageOption pkgs "mise" { };
33+
};
34+
lib = lib.mkOption {
35+
type = with lib.types; attrsOf lines;
36+
description = ''
37+
Configuration of [extension files](https://direnv.net/#the-stdlib)
38+
that will be created at `$DIRENV_CONFIG/lib/*.sh`
39+
'';
40+
example = {
41+
"my-lib-script.sh" = "echo 'content of my-lib-script.sh'";
42+
};
43+
default = { };
44+
};
45+
extraConfig = lib.mkOption {
46+
inherit (tomlFmt) type;
47+
default = { };
48+
description = ''
49+
Configuration of direnv.toml.
50+
See <https://direnv.net/man/direnv.toml.1.html>
51+
'';
52+
};
53+
};
54+
config = {
55+
package = lib.mkDefault pkgs.direnv;
56+
env = {
57+
# We currently do not inject `DIRENV_CONFIG` for the reasons outlined in
58+
# meta.description.pre.
59+
60+
# **IMPORTANT** Using `placeholder "out"` here seems to cause issues if this wrapper is
61+
# built inside a subWrapperModule (for example within the zshWrapper) as it refers
62+
# to the build zsh output in that context. The passthru variants seems to solve this issue.
63+
DIRENV_CONFIG = "${placeholder "out"}/${config.configDirname}";
64+
};
65+
passthru.DIRENV_CONFIG = direnvDotdir;
66+
lib = {
67+
"nix-direnv.sh" = lib.mkIf config.nix-direnv.enable ''
68+
source ${config.nix-direnv.package}/share/nix-direnv/direnvrc
69+
'';
70+
"mise.sh" = lib.mkIf config.mise.enable ''
71+
eval "$(${lib.getExe config.mise.package} direnv activate)"
72+
'';
73+
};
74+
extraConfig = {
75+
global = lib.mkIf (config.silent) {
76+
log_format = "-";
77+
log_filter = "^$";
78+
};
79+
};
80+
constructFiles = {
81+
direnvToml = {
82+
content = builtins.toJSON config.extraConfig;
83+
relPath = "${config.configDirname}/direnv.toml";
84+
builder = ''mkdir -p "$(dirname "$2")" && ${pkgs.remarshal}/bin/json2toml "$1" "$2"'';
85+
};
86+
direnvRc = {
87+
content = config.direnvrc;
88+
relPath = "${config.configDirname}/direnvrc";
89+
};
90+
}
91+
// lib.mapAttrs (name: value: {
92+
content = value;
93+
relPath = "${config.configDirname}/lib/${name}";
94+
}) config.lib;
95+
meta.maintainers = [ wlib.maintainers.zenoli ];
96+
meta.description.pre = ''
97+
**IMPORTANT** In order to use this wrapper, `DIRENV_CONFIG` needs to be explicitly
98+
set in your shells environment:
99+
100+
```shell
101+
DIRENV_CONFIG="''${direnvWrapper.passthru.DIRENV_CONFIG}"
102+
```
103+
104+
This is because right now, direnv will use the original `direnv` binary in its shell hook
105+
and not the wrapper script. So injecting `DIRENV_CONFIG` currently has no effect.
106+
107+
If the PR below will ever be merged, this issue can be fixed by setting:
108+
109+
```nix
110+
env.DIRENV_EXE_PATH = "''${placeholder "out"}/bin/direnv";
111+
```
112+
113+
This would make the direnv hook use the wrapper instead of the original binary and
114+
injecting `DIRENV_CONFIG` into the wrapper would start to take effect.
115+
116+
https://github.com/direnv/direnv/pull/1564
117+
'';
118+
};
119+
}

0 commit comments

Comments
 (0)