Repo for the search and displace core module including the interface to select files and search and displace operations to run on them. https://searchanddisplace.com
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

239 lines
7.4 KiB

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