Skip to content

Commit 7fe74bd

Browse files
committed
feat: Let users load extensions from require-dev using nix develop.
1 parent eb88769 commit 7fe74bd

File tree

2 files changed

+111
-59
lines changed

2 files changed

+111
-59
lines changed

Diff for: README.md

+13-4
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,30 @@ Available PHP versions from `5.6` to `8.1`.
2626
The PHP extensions to use are automatically inferred
2727
from the `composer.json` and `composer.lock` files.
2828

29-
To load the `xdebug` and `pcov` extensions, edit `composer.json` as such:
30-
3129
```json
3230
...8<...
3331

3432
"require": {
33+
"ext-intl": "*",
34+
},
35+
"require-dev": {
3536
"ext-xdebug": "*",
3637
"ext-pcov": "*",
3738
}
3839

3940
...>8...
4041
```
42+
Loading extensions from the `require` section of the `composer.json` file
43+
requires the use of the nix `shell` command.
44+
45+
However, if you want to load extensions from `require` and `required-dev`
46+
sections, using the nix `develop` command is required.
47+
48+
Use `nix shell` to load the `ext-intl` extension only or `nix develop` to load
49+
`ext-intl`, `ext-xdebug` and `ext-pcov` extensions.
4150

42-
Do not forget to add the flag `--impure` when loading custom
43-
extensions from `composer.json`.
51+
Do not forget to add the flag `--impure` when you want to load extensions from
52+
`composer.json`.
4453

4554
## Usage
4655

Diff for: flake.nix

+98-55
Original file line numberDiff line numberDiff line change
@@ -77,13 +77,7 @@
7777
];
7878
};
7979

80-
makePhp =
81-
{ php
82-
, withExtensions ? [ ]
83-
, withoutExtensions ? [ ]
84-
, extraConfig ? ""
85-
, flags ? { }
86-
}:
80+
getExtensionFromComposerSection = section:
8781
let
8882
readJsonSectionFromFile = file: section: default:
8983
let
@@ -93,17 +87,28 @@
9387
filecontent.${section} or default;
9488

9589
# Get "require" section to extract extensions later
96-
require = readJsonSectionFromFile "composer.json" "require" { };
90+
require = readJsonSectionFromFile "composer.json" section { };
9791
# Copy keys into values
9892
composerRequiresKeys = map (p: lib.attrsets.mapAttrs' (k: v: lib.nameValuePair k k) p) [ require ];
9993
# Convert sets into lists
10094
composerRequiresMap = map (package: (map (key: builtins.getAttr key package) (builtins.attrNames package))) composerRequiresKeys;
95+
in
10196
# Convert the set into a list, filter out values not starting with "ext-", get rid of the first 4 characters from the name
102-
userExtensions = map (x: builtins.substring 4 (builtins.stringLength x) x) (builtins.filter (x: (builtins.substring 0 4 x) == "ext-") (lib.flatten composerRequiresMap));
97+
map (x: builtins.substring 4 (builtins.stringLength x) x) (builtins.filter (x: (builtins.substring 0 4 x) == "ext-") (lib.flatten composerRequiresMap));
10398

104-
phpIniFile = "${builtins.getEnv "PWD"}/.user.ini";
99+
requiredExts = getExtensionFromComposerSection "require";
100+
requiredDevExts = getExtensionFromComposerSection "require-dev";
105101

106-
extensions = builtins.filter (x: !builtins.elem x withoutExtensions) (lib.unique (withExtensions ++ userExtensions));
102+
makePhp =
103+
{ php
104+
, withExtensions ? [ ]
105+
, withoutExtensions ? [ ]
106+
, extraConfig ? ""
107+
, flags ? { }
108+
}:
109+
let
110+
phpIniFile = "${builtins.getEnv "PWD"}/.user.ini";
111+
extensions = builtins.filter (x: !builtins.elem x withoutExtensions) (lib.unique withExtensions);
107112
in
108113
((php.override flags).buildEnv {
109114
extraConfig = extraConfig + "\n" + (if builtins.pathExists "${phpIniFile}" then builtins.readFile "${phpIniFile}" else "");
@@ -112,49 +117,49 @@
112117

113118
phpDerivations = rec
114119
{
115-
default = derivations.php81;
120+
default = phpDerivations.php81;
116121

117-
php56 = makePhp {
122+
php56 = {
118123
php = phps.php56;
119-
withExtensions = defaultExtensions;
124+
withExtensions = defaultExtensions ++ requiredExts;
120125
withoutExtensions = [ "sodium" "pcov" ];
121126
};
122127

123-
php70 = makePhp {
128+
php70 = {
124129
php = phps.php70;
125-
withExtensions = defaultExtensions;
130+
withExtensions = defaultExtensions ++ requiredExts;
126131
withoutExtensions = [ "sodium" ];
127132
};
128133

129-
php71 = makePhp {
134+
php71 = {
130135
php = phps.php71;
131-
withExtensions = defaultExtensions;
136+
withExtensions = defaultExtensions ++ requiredExts;
132137
withoutExtensions = [ "sodium" ];
133138
};
134139

135-
php72 = makePhp {
140+
php72 = {
136141
php = phps.php72;
137-
withExtensions = defaultExtensions;
142+
withExtensions = defaultExtensions ++ requiredExts;
138143
};
139144

140-
php73 = makePhp {
145+
php73 = {
141146
php = phps.php73;
142-
withExtensions = defaultExtensions;
147+
withExtensions = defaultExtensions ++ requiredExts;
143148
};
144149

145-
php74 = makePhp {
150+
php74 = {
146151
php = phps.php74;
147-
withExtensions = defaultExtensions;
152+
withExtensions = defaultExtensions ++ requiredExts;
148153
};
149154

150-
php80 = makePhp {
155+
php80 = {
151156
php = phps.php80;
152-
withExtensions = defaultExtensions;
157+
withExtensions = defaultExtensions ++ requiredExts;
153158
};
154159

155-
php81 = makePhp {
160+
php81 = {
156161
php = phps.php81;
157-
withExtensions = defaultExtensions;
162+
withExtensions = defaultExtensions ++ requiredExts;
158163
};
159164
};
160165

@@ -163,44 +168,82 @@
163168
lib.nameValuePair
164169
(name + "-nts")
165170
(
166-
let
171+
php // {
167172
flags = {
168173
apxs2Support = false;
169174
ztsSupport = false;
170175
};
171-
in
172-
(php.override flags)
176+
}
173177
)
174178
) phpDerivations;
175-
176-
# Build PHP environments.
177-
derivations = phpDerivationsWithNts // lib.mapAttrs' (name: php:
178-
let
179-
pname = "env-" + name;
180-
in
181-
lib.nameValuePair
182-
(pname)
183-
(makePhpEnv pname php)
184-
) phpDerivationsWithNts;
185179
in
186180
{
187-
# This is deprecated in Nix 2.7.0
188-
defaultPackage = derivations.default-nts;
189-
190-
# This is deprecated in Nix 2.7.0
191-
devShell = pkgs.mkShellNoCC {
192-
name = derivations.default.name;
193-
buildInputs = [ derivations.default-nts ];
194-
};
195-
196-
packages = derivations;
197-
181+
# In use for "nix shell"
182+
packages = builtins.mapAttrs
183+
(name: phpConfig: pkgs.buildEnv {
184+
inherit name;
185+
paths = [
186+
(makePhp {
187+
php = phpConfig.php;
188+
flags = phpConfig.flags or {};
189+
withExtensions = phpConfig.withExtensions;
190+
withoutExtensions = phpConfig.withoutExtensions or [];
191+
})
192+
];
193+
})
194+
phpDerivationsWithNts //
195+
lib.mapAttrs' (name: phpConfig:
196+
let
197+
pname = "env-" + name;
198+
in
199+
lib.nameValuePair
200+
(pname)
201+
(
202+
makePhpEnv pname (makePhp {
203+
php = phpConfig.php;
204+
flags = phpConfig.flags or {};
205+
withExtensions = phpConfig.withExtensions;
206+
withoutExtensions = phpConfig.withoutExtensions or [];
207+
})
208+
)
209+
) phpDerivationsWithNts;
210+
211+
# In use for "nix develop"
198212
devShells = builtins.mapAttrs
199-
(name: value: pkgs.mkShellNoCC {
213+
(name: phpConfig: pkgs.mkShellNoCC {
200214
inherit name;
201-
buildInputs = [ value ];
215+
buildInputs = [
216+
(makePhp {
217+
php = phpConfig.php;
218+
flags = phpConfig.flags or {};
219+
withExtensions = phpConfig.withExtensions ++ requiredDevExts;
220+
withoutExtensions = phpConfig.withoutExtensions or [];
221+
})
222+
];
202223
})
203-
derivations;
224+
phpDerivationsWithNts //
225+
lib.mapAttrs' (name: phpConfig:
226+
let
227+
phpEnv = makePhpEnv name (makePhp {
228+
php = phpConfig.php;
229+
flags = phpConfig.flags or {};
230+
withExtensions = phpConfig.withExtensions ++ requiredDevExts;
231+
withoutExtensions = phpConfig.withoutExtensions or [];
232+
});
233+
in
234+
let
235+
pname = "env-" + name;
236+
in
237+
lib.nameValuePair
238+
(pname)
239+
(
240+
pkgs.mkShellNoCC {
241+
name = pname;
242+
buildInputs = [ phpEnv ];
243+
}
244+
)
245+
)
246+
phpDerivationsWithNts;
204247
}
205248
);
206249
}

0 commit comments

Comments
 (0)