]> git.immae.eu Git - perso/Immae/Config/Nix.git/blame - flakes/mypackages/pkgs/composer-env/default.nix
Squash changes containing private information
[perso/Immae/Config/Nix.git] / flakes / mypackages / pkgs / composer-env / default.nix
CommitLineData
d78128ec
IB
1# This file originates from composer2nix
2
1a64deeb 3{ stdenv, lib, writeTextFile, fetchurl, php, unzip, composer ? php.packages.composer }:
d78128ec
IB
4
5let
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);
242in
1a64deeb 243{ inherit composer buildZipPackage buildPackage; }