]>
Commit | Line | Data |
---|---|---|
d78128ec IB |
1 | # This file originates from composer2nix |
2 | ||
1a64deeb | 3 | { stdenv, lib, writeTextFile, fetchurl, php, unzip, composer ? php.packages.composer }: |
d78128ec IB |
4 | |
5 | let | |
d78128ec IB |
6 | buildZipPackage = { name, src }: |
7 | stdenv.mkDerivation { | |
8 | inherit name src; | |
9 | buildInputs = [ unzip ]; | |
10 | buildCommand = '' | |
11 | unzip $src | |
12 | baseDir=$(find . -type d -mindepth 1 -maxdepth 1) | |
13 | cd $baseDir | |
14 | mkdir -p $out | |
15 | mv * $out | |
16 | ''; | |
17 | }; | |
18 | ||
19 | buildPackage = | |
20 | { name | |
21 | , src | |
22 | , packages ? {} | |
23 | , devPackages ? {} | |
24 | , buildInputs ? [] | |
25 | , symlinkDependencies ? false | |
26 | , executable ? false | |
27 | , removeComposerArtifacts ? false | |
28 | , postInstall ? "" | |
29 | , preInstall ? "" | |
30 | , noDev ? false | |
31 | , unpackPhase ? "true" | |
32 | , buildPhase ? "true" | |
a3d281ea | 33 | , doRemoveVendor ? true |
d78128ec IB |
34 | , ...}@args: |
35 | ||
36 | let | |
37 | reconstructInstalled = writeTextFile { | |
38 | name = "reconstructinstalled.php"; | |
39 | executable = true; | |
40 | text = '' | |
41 | #! ${php}/bin/php | |
42 | <?php | |
43 | if(file_exists($argv[1])) | |
44 | { | |
45 | $composerLockStr = file_get_contents($argv[1]); | |
46 | ||
47 | if($composerLockStr === false) | |
48 | { | |
49 | fwrite(STDERR, "Cannot open composer.lock contents\n"); | |
50 | exit(1); | |
51 | } | |
52 | else | |
53 | { | |
54 | $config = json_decode($composerLockStr, true); | |
55 | ||
56 | if(array_key_exists("packages", $config)) | |
57 | $allPackages = $config["packages"]; | |
58 | else | |
59 | $allPackages = array(); | |
60 | ||
1a64deeb | 61 | ${lib.optionalString (!noDev) '' |
d78128ec IB |
62 | if(array_key_exists("packages-dev", $config)) |
63 | $allPackages = array_merge($allPackages, $config["packages-dev"]); | |
64 | ''} | |
65 | ||
66 | $packagesStr = json_encode($allPackages, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); | |
67 | print($packagesStr); | |
68 | } | |
69 | } | |
70 | else | |
71 | print("[]"); | |
72 | ?> | |
73 | ''; | |
74 | }; | |
75 | ||
76 | constructBin = writeTextFile { | |
77 | name = "constructbin.php"; | |
78 | executable = true; | |
79 | text = '' | |
80 | #! ${php}/bin/php | |
81 | <?php | |
82 | $composerJSONStr = file_get_contents($argv[1]); | |
83 | ||
84 | if($composerJSONStr === false) | |
85 | { | |
86 | fwrite(STDERR, "Cannot open composer.json contents\n"); | |
87 | exit(1); | |
88 | } | |
89 | else | |
90 | { | |
91 | $config = json_decode($composerJSONStr, true); | |
92 | ||
93 | if(array_key_exists("bin-dir", $config)) | |
94 | $binDir = $config["bin-dir"]; | |
95 | else | |
96 | $binDir = "bin"; | |
97 | ||
98 | if(array_key_exists("bin", $config)) | |
99 | { | |
100 | if(!file_exists("vendor/".$binDir)) | |
101 | mkdir("vendor/".$binDir); | |
102 | ||
103 | foreach($config["bin"] as $bin) | |
104 | symlink("../../".$bin, "vendor/".$binDir."/".basename($bin)); | |
105 | } | |
106 | } | |
107 | ?> | |
108 | ''; | |
109 | }; | |
110 | ||
111 | bundleDependencies = dependencies: | |
1a64deeb | 112 | lib.concatMapStrings (dependencyName: |
d78128ec IB |
113 | let |
114 | dependency = dependencies.${dependencyName}; | |
115 | in | |
116 | '' | |
117 | ${if dependency.targetDir == "" then '' | |
118 | vendorDir="$(dirname ${dependencyName})" | |
119 | mkdir -p "$vendorDir" | |
120 | ${if symlinkDependencies then | |
121 | ''ln -s "${dependency.src}" "$vendorDir/$(basename "${dependencyName}")"'' | |
122 | else | |
625e0bfd | 123 | ''cp -a "${dependency.src}" "$vendorDir/$(basename "${dependencyName}")"'' |
85545c3f IB |
124 | }${if dependency.needsModifyRights or false then "\n" + '' |
125 | chmod -R u+rwx "$vendorDir/$(basename "${dependencyName}")" | |
126 | '' else ""} | |
d78128ec IB |
127 | '' else '' |
128 | namespaceDir="${dependencyName}/$(dirname "${dependency.targetDir}")" | |
129 | mkdir -p "$namespaceDir" | |
130 | ${if symlinkDependencies then | |
131 | ''ln -s "${dependency.src}" "$namespaceDir/$(basename "${dependency.targetDir}")"'' | |
132 | else | |
625e0bfd | 133 | ''cp -a "${dependency.src}" "$namespaceDir/$(basename "${dependency.targetDir}")"'' |
85545c3f IB |
134 | }${if dependency.needsModifyRights or false then "\n" + '' |
135 | chmod -R u+rwx "$namespaceDir/$(basename "${dependency.targetDir}")" | |
136 | '' else ""} | |
d78128ec IB |
137 | ''} |
138 | '') (builtins.attrNames dependencies); | |
139 | ||
140 | extraArgs = removeAttrs args [ "name" "packages" "devPackages" "buildInputs" ]; | |
141 | in | |
142 | stdenv.mkDerivation ({ | |
143 | name = "composer-${name}"; | |
144 | buildInputs = [ php composer ] ++ buildInputs; | |
145 | ||
146 | inherit unpackPhase buildPhase; | |
147 | ||
148 | installPhase = '' | |
149 | ${if executable then '' | |
150 | mkdir -p $out/share/php | |
625e0bfd | 151 | cp -a $src $out/share/php/$name |
d78128ec IB |
152 | chmod -R u+w $out/share/php/$name |
153 | cd $out/share/php/$name | |
154 | '' else '' | |
625e0bfd | 155 | cp -a $src $out |
d78128ec IB |
156 | chmod -R u+w $out |
157 | cd $out | |
158 | ''} | |
159 | ||
160 | # Execute pre install hook | |
161 | runHook preInstall | |
162 | ||
163 | # Remove unwanted files | |
164 | rm -f *.nix | |
165 | ||
166 | export HOME=$TMPDIR | |
167 | ||
a3d281ea | 168 | ${if doRemoveVendor then '' |
d78128ec IB |
169 | # Remove the provided vendor folder if it exists |
170 | rm -Rf vendor | |
a3d281ea | 171 | '' else ""} |
d78128ec IB |
172 | # If there is no composer.lock file, compose a dummy file. |
173 | # Otherwise, composer attempts to download the package.json file from | |
174 | # the registry which we do not want. | |
175 | if [ ! -f composer.lock ] | |
176 | then | |
177 | cat > composer.lock <<EOF | |
178 | { | |
179 | "packages": [] | |
180 | } | |
181 | EOF | |
182 | fi | |
183 | ||
184 | # Reconstruct the installed.json file from the lock file | |
185 | mkdir -p vendor/composer | |
186 | ${reconstructInstalled} composer.lock > vendor/composer/installed.json | |
187 | ||
188 | # Copy or symlink the provided dependencies | |
189 | cd vendor | |
190 | ${bundleDependencies packages} | |
1a64deeb | 191 | ${lib.optionalString (!noDev) (bundleDependencies devPackages)} |
d78128ec IB |
192 | cd .. |
193 | ||
194 | # Reconstruct autoload scripts | |
195 | # We use the optimize feature because Nix packages cannot change after they have been built | |
196 | # Using the dynamic loader for a Nix package is useless since there is nothing to dynamically reload. | |
1a64deeb | 197 | composer dump-autoload --optimize ${lib.optionalString noDev "--no-dev"} |
d78128ec IB |
198 | |
199 | # Run the install step as a validation to confirm that everything works out as expected | |
1a64deeb | 200 | composer install --optimize-autoloader ${lib.optionalString noDev "--no-dev"} |
d78128ec | 201 | |
1a64deeb | 202 | ${lib.optionalString executable '' |
d78128ec IB |
203 | # Reconstruct the bin/ folder if we deploy an executable project |
204 | ${constructBin} composer.json | |
205 | ln -s $(pwd)/vendor/bin $out/bin | |
206 | ''} | |
207 | ||
1a64deeb | 208 | ${lib.optionalString (!symlinkDependencies) '' |
d78128ec IB |
209 | # Patch the shebangs if possible |
210 | if [ -d $(pwd)/vendor/bin ] | |
211 | then | |
212 | # Look for all executables in bin/ | |
213 | for i in $(pwd)/vendor/bin/* | |
214 | do | |
215 | # Look for their location | |
216 | realFile=$(readlink -f "$i") | |
217 | ||
218 | # Restore write permissions | |
219 | chmod u+wx "$(dirname "$realFile")" | |
220 | chmod u+w "$realFile" | |
221 | ||
222 | # Patch shebang | |
223 | sed -e "s|#!/usr/bin/php|#!${php}/bin/php|" \ | |
224 | -e "s|#!/usr/bin/env php|#!${php}/bin/php|" \ | |
225 | "$realFile" > tmp | |
226 | mv tmp "$realFile" | |
227 | chmod u+x "$realFile" | |
228 | done | |
229 | fi | |
230 | ''} | |
231 | ||
232 | if [ "$removeComposerArtifacts" = "1" ] | |
233 | then | |
234 | # Remove composer stuff | |
235 | rm -f composer.json composer.lock | |
236 | fi | |
237 | ||
238 | # Execute post install hook | |
239 | runHook postInstall | |
240 | ''; | |
241 | } // extraArgs); | |
242 | in | |
1a64deeb | 243 | { inherit composer buildZipPackage buildPackage; } |