about summary refs log tree commit diff
path: root/nixpkgs/pkgs/build-support
diff options
context:
space:
mode:
authorAlyssa Ross <hi@alyssa.is>2023-09-16 08:50:56 +0000
committerAlyssa Ross <hi@alyssa.is>2023-09-16 08:50:56 +0000
commitc51a27c0e7727fcd2be7d2d7d275f365ab1235be (patch)
treec6f917179329e0cad02bf8b818569fe6e905ab13 /nixpkgs/pkgs/build-support
parent9d1daa60832979d5d361dfdac136fb9e5a1af2c5 (diff)
parentace5093e36ab1e95cb9463863491bee90d5a4183 (diff)
downloadnixlib-c51a27c0e7727fcd2be7d2d7d275f365ab1235be.tar
nixlib-c51a27c0e7727fcd2be7d2d7d275f365ab1235be.tar.gz
nixlib-c51a27c0e7727fcd2be7d2d7d275f365ab1235be.tar.bz2
nixlib-c51a27c0e7727fcd2be7d2d7d275f365ab1235be.tar.lz
nixlib-c51a27c0e7727fcd2be7d2d7d275f365ab1235be.tar.xz
nixlib-c51a27c0e7727fcd2be7d2d7d275f365ab1235be.tar.zst
nixlib-c51a27c0e7727fcd2be7d2d7d275f365ab1235be.zip
Merge branch 'nixos-unstable' of https://github.com/NixOS/nixpkgs
Diffstat (limited to 'nixpkgs/pkgs/build-support')
-rw-r--r--nixpkgs/pkgs/build-support/fetchdebianpatch/default.nix6
-rw-r--r--nixpkgs/pkgs/build-support/make-darwin-bundle/write-darwin-bundle.nix30
-rw-r--r--nixpkgs/pkgs/build-support/php/build-composer-project.nix71
-rw-r--r--nixpkgs/pkgs/build-support/php/build-composer-repository.nix87
-rw-r--r--nixpkgs/pkgs/build-support/php/build-pecl.nix (renamed from nixpkgs/pkgs/build-support/build-pecl.nix)0
-rw-r--r--nixpkgs/pkgs/build-support/php/hooks/composer-install-hook.sh113
-rw-r--r--nixpkgs/pkgs/build-support/php/hooks/composer-repository-hook.sh69
-rw-r--r--nixpkgs/pkgs/build-support/php/hooks/default.nix22
-rw-r--r--nixpkgs/pkgs/build-support/php/pkgs/composer-local-repo-plugin.nix112
-rw-r--r--nixpkgs/pkgs/build-support/php/pkgs/composer-phar.nix48
-rw-r--r--nixpkgs/pkgs/build-support/setup-hooks/desktop-to-darwin-bundle.sh4
11 files changed, 546 insertions, 16 deletions
diff --git a/nixpkgs/pkgs/build-support/fetchdebianpatch/default.nix b/nixpkgs/pkgs/build-support/fetchdebianpatch/default.nix
index c058b416d381..8d8076bd59d6 100644
--- a/nixpkgs/pkgs/build-support/fetchdebianpatch/default.nix
+++ b/nixpkgs/pkgs/build-support/fetchdebianpatch/default.nix
@@ -1,8 +1,8 @@
 { lib, fetchpatch }:
 
 lib.makeOverridable (
-  { pname, version, debianRevision ? null, patch, hash,
-    area ? "main", name ? "${patch}.patch" }:
+  { pname, version, debianRevision ? null, area ? "main",
+    patch, name ? patch, hash }:
   let
     inherit (lib.strings) hasPrefix substring;
     prefix =
@@ -14,6 +14,6 @@ lib.makeOverridable (
     inherit name hash;
     url =
       "https://sources.debian.org/data/${area}/${prefix}/"
-      + "${pname}/${versionString}/debian/patches/${patch}.patch";
+      + "${pname}/${versionString}/debian/patches/${patch}";
   }
 )
diff --git a/nixpkgs/pkgs/build-support/make-darwin-bundle/write-darwin-bundle.nix b/nixpkgs/pkgs/build-support/make-darwin-bundle/write-darwin-bundle.nix
index fde977c3636b..752cbbde2a31 100644
--- a/nixpkgs/pkgs/build-support/make-darwin-bundle/write-darwin-bundle.nix
+++ b/nixpkgs/pkgs/build-support/make-darwin-bundle/write-darwin-bundle.nix
@@ -1,4 +1,4 @@
-{ writeScriptBin, lib, ... }:
+{ writeScriptBin, lib, makeBinaryWrapper }:
 
 let
   pListText = lib.generators.toPlist { } {
@@ -17,23 +17,31 @@ in writeScriptBin "write-darwin-bundle" ''
 
     readonly prefix=$1
     readonly name=$2
-    readonly exec=$3
+    # TODO: support executables with spaces in their names
+    readonly execName=''${3%% *} # Before the first space
+    [[ $3 =~ " " ]] && readonly execArgs=''${3#* } # Everything after the first space
     readonly icon=$4.icns
     readonly squircle=''${5:-1}
     readonly plist=$prefix/Applications/$name.app/Contents/Info.plist
+    readonly binary=$prefix/bin/$execName
+    readonly bundleExecutable=$prefix/Applications/$name.app/Contents/MacOS/$name
 
     cat > "$plist" <<EOF
 ${pListText}
 EOF
 
-  if [[ $squircle == 0 || $squircle == "false" ]]; then
-    sed  '/CFBundleIconFiles/,\|</array>|d' -i "$plist"
-  fi
+    if [[ $squircle == 0 || $squircle == "false" ]]; then
+      sed  '/CFBundleIconFiles/,\|</array>|d' -i "$plist"
+    fi
 
-    cat > "$prefix/Applications/$name.app/Contents/MacOS/$name" <<EOF
-#!/bin/bash
-exec $prefix/bin/$exec
-EOF
-
-    chmod +x "$prefix/Applications/$name.app/Contents/MacOS/$name"
+    if [[ -n "$execArgs" ]]; then
+      (
+        source ${makeBinaryWrapper}/nix-support/setup-hook
+        # WORKAROUND: makeBinaryWrapper fails when -u is set
+        set +u
+        makeBinaryWrapper "$binary" "$bundleExecutable" --add-flags "$execArgs"
+      )
+    else
+      ln -s "$binary" "$bundleExecutable"
+    fi
 ''
diff --git a/nixpkgs/pkgs/build-support/php/build-composer-project.nix b/nixpkgs/pkgs/build-support/php/build-composer-project.nix
new file mode 100644
index 000000000000..6aecf4345773
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/php/build-composer-project.nix
@@ -0,0 +1,71 @@
+{ callPackage, stdenvNoCC, lib, writeTextDir, php, makeBinaryWrapper, fetchFromGitHub, fetchurl }:
+
+let
+  buildComposerProjectOverride = finalAttrs: previousAttrs:
+
+    let
+      phpDrv = finalAttrs.php or php;
+      composer = finalAttrs.composer or phpDrv.packages.composer;
+      composer-local-repo-plugin = callPackage ./pkgs/composer-local-repo-plugin.nix { };
+    in
+    {
+      composerLock = previousAttrs.composerLock or null;
+      composerNoDev = previousAttrs.composerNoDev or true;
+      composerNoPlugins = previousAttrs.composerNoPlugins or true;
+      composerNoScripts = previousAttrs.composerNoScripts or true;
+
+      nativeBuildInputs = (previousAttrs.nativeBuildInputs or [ ]) ++ [
+        composer
+        composer-local-repo-plugin
+        phpDrv.composerHooks.composerInstallHook
+      ];
+
+      buildInputs = (previousAttrs.buildInputs or [ ]) ++ [
+        phpDrv
+      ];
+
+      patches = previousAttrs.patches or [ ];
+      strictDeps = previousAttrs.strictDeps or true;
+
+      # Should we keep these empty phases?
+      configurePhase = previousAttrs.configurePhase or ''
+        runHook preConfigure
+
+        runHook postConfigure
+      '';
+
+      buildPhase = previousAttrs.buildPhase or ''
+        runHook preBuild
+
+        runHook postBuild
+      '';
+
+      doCheck = previousAttrs.doCheck or true;
+      checkPhase = previousAttrs.checkPhase or ''
+        runHook preCheck
+
+        runHook postCheck
+      '';
+
+      installPhase = previousAttrs.installPhase or ''
+        runHook preInstall
+
+        runHook postInstall
+      '';
+
+      composerRepository = phpDrv.mkComposerRepository {
+        inherit composer composer-local-repo-plugin;
+        inherit (finalAttrs) patches pname src vendorHash version;
+
+        composerLock = previousAttrs.composerLock or null;
+        composerNoDev = previousAttrs.composerNoDev or true;
+        composerNoPlugins = previousAttrs.composerNoPlugins or true;
+        composerNoScripts = previousAttrs.composerNoScripts or true;
+      };
+
+      meta = previousAttrs.meta or { } // {
+        platforms = lib.platforms.all;
+      };
+    };
+in
+args: (stdenvNoCC.mkDerivation args).overrideAttrs buildComposerProjectOverride
diff --git a/nixpkgs/pkgs/build-support/php/build-composer-repository.nix b/nixpkgs/pkgs/build-support/php/build-composer-repository.nix
new file mode 100644
index 000000000000..30b0b48de751
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/php/build-composer-repository.nix
@@ -0,0 +1,87 @@
+{ callPackage, stdenvNoCC, lib, writeTextDir, fetchFromGitHub, php }:
+
+let
+  mkComposerRepositoryOverride =
+    /*
+      We cannot destruct finalAttrs since the attrset below is used to construct it
+      and Nix currently does not support lazy attribute names.
+      {
+      php ? null,
+      composer ? null,
+      composerLock ? "composer.lock",
+      src,
+      vendorHash,
+      ...
+      }@finalAttrs:
+    */
+    finalAttrs: previousAttrs:
+
+    let
+      phpDrv = finalAttrs.php or php;
+      composer = finalAttrs.composer or phpDrv.packages.composer;
+      composer-local-repo-plugin = callPackage ./pkgs/composer-local-repo-plugin.nix { };
+    in
+    assert (lib.assertMsg (previousAttrs ? src) "mkComposerRepository expects src argument.");
+    assert (lib.assertMsg (previousAttrs ? vendorHash) "mkComposerRepository expects vendorHash argument.");
+    assert (lib.assertMsg (previousAttrs ? version) "mkComposerRepository expects version argument.");
+    assert (lib.assertMsg (previousAttrs ? pname) "mkComposerRepository expects pname argument.");
+    assert (lib.assertMsg (previousAttrs ? composerNoDev) "mkComposerRepository expects composerNoDev argument.");
+    assert (lib.assertMsg (previousAttrs ? composerNoPlugins) "mkComposerRepository expects composerNoPlugins argument.");
+    assert (lib.assertMsg (previousAttrs ? composerNoScripts) "mkComposerRepository expects composerNoScripts argument.");
+    {
+      composerNoDev = previousAttrs.composerNoDev or true;
+      composerNoPlugins = previousAttrs.composerNoPlugins or true;
+      composerNoScripts = previousAttrs.composerNoScripts or true;
+
+      name = "${previousAttrs.pname}-${previousAttrs.version}-composer-repository";
+
+      # See https://github.com/NixOS/nix/issues/6660
+      dontPatchShebangs = previousAttrs.dontPatchShebangs or true;
+
+      nativeBuildInputs = (previousAttrs.nativeBuildInputs or [ ]) ++ [
+        composer
+        composer-local-repo-plugin
+        phpDrv.composerHooks.composerRepositoryHook
+      ];
+
+      buildInputs = previousAttrs.buildInputs or [ ];
+
+      strictDeps = previousAttrs.strictDeps or true;
+
+      # Should we keep these empty phases?
+      configurePhase = previousAttrs.configurePhase or ''
+        runHook preConfigure
+
+        runHook postConfigure
+      '';
+
+      buildPhase = previousAttrs.buildPhase or ''
+        runHook preBuild
+
+        runHook postBuild
+      '';
+
+      doCheck = previousAttrs.doCheck or true;
+      checkPhase = previousAttrs.checkPhase or ''
+        runHook preCheck
+
+        runHook postCheck
+      '';
+
+      installPhase = previousAttrs.installPhase or ''
+        runHook preInstall
+
+        runHook postInstall
+      '';
+
+      COMPOSER_CACHE_DIR = "/dev/null";
+      COMPOSER_MIRROR_PATH_REPOS = "1";
+      COMPOSER_HTACCESS_PROTECT = "0";
+      COMPOSER_DISABLE_NETWORK = "0";
+
+      outputHashMode = "recursive";
+      outputHashAlgo = if (finalAttrs ? vendorHash && finalAttrs.vendorHash != "") then null else "sha256";
+      outputHash = finalAttrs.vendorHash or "";
+    };
+in
+args: (stdenvNoCC.mkDerivation args).overrideAttrs mkComposerRepositoryOverride
diff --git a/nixpkgs/pkgs/build-support/build-pecl.nix b/nixpkgs/pkgs/build-support/php/build-pecl.nix
index 389447e066fa..389447e066fa 100644
--- a/nixpkgs/pkgs/build-support/build-pecl.nix
+++ b/nixpkgs/pkgs/build-support/php/build-pecl.nix
diff --git a/nixpkgs/pkgs/build-support/php/hooks/composer-install-hook.sh b/nixpkgs/pkgs/build-support/php/hooks/composer-install-hook.sh
new file mode 100644
index 000000000000..bb6cb47e861b
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/php/hooks/composer-install-hook.sh
@@ -0,0 +1,113 @@
+declare composerRepository
+declare version
+declare composerNoDev
+declare composerNoPlugins
+declare composerNoScripts
+
+preConfigureHooks+=(composerInstallConfigureHook)
+preBuildHooks+=(composerInstallBuildHook)
+preCheckHooks+=(composerInstallCheckHook)
+preInstallHooks+=(composerInstallInstallHook)
+
+composerInstallConfigureHook() {
+    echo "Executing composerInstallConfigureHook"
+
+    if [[ ! -e "${composerRepository}" ]]; then
+        echo "No local composer repository found."
+        exit 1
+    fi
+
+    if [[ -e "$composerLock" ]]; then
+        cp "$composerLock" composer.lock
+    fi
+
+    if [[ ! -f "composer.lock" ]]; then
+        echo "No composer.lock file found, consider adding one to your repository to ensure reproducible builds."
+
+        if [[ -f "${composerRepository}/composer.lock" ]]; then
+            cp ${composerRepository}/composer.lock composer.lock
+        fi
+
+        echo "Using an autogenerated composer.lock file."
+    fi
+
+    chmod +w composer.json composer.lock
+
+    echo "Finished composerInstallConfigureHook"
+}
+
+composerInstallBuildHook() {
+    echo "Executing composerInstallBuildHook"
+
+    # Since this file cannot be generated in the composer-repository-hook.sh
+    # because the file contains hardcoded nix store paths, we generate it here.
+    composer-local-repo-plugin --no-ansi build-local-repo -p "${composerRepository}" > packages.json
+
+    # Remove all the repositories of type "composer"
+    # from the composer.json file.
+    jq -r -c 'del(try .repositories[] | select(.type == "composer"))' composer.json | sponge composer.json
+
+    # Configure composer to disable packagist and avoid using the network.
+    composer config repo.packagist false
+    # Configure composer to use the local repository.
+    composer config repo.composer composer file://"$PWD"/packages.json
+
+    # Since the composer.json file has been modified in the previous step, the
+    # composer.lock file needs to be updated.
+    COMPOSER_DISABLE_NETWORK=1 \
+    COMPOSER_ROOT_VERSION="${version}" \
+    composer \
+      --lock \
+      --no-ansi \
+      --no-install \
+      --no-interaction \
+      ${composerNoDev:+--no-dev} \
+      ${composerNoPlugins:+--no-plugins} \
+      ${composerNoScripts:+--no-scripts} \
+      update
+
+    echo "Finished composerInstallBuildHook"
+}
+
+composerInstallCheckHook() {
+    echo "Executing composerInstallCheckHook"
+
+    composer validate --no-ansi --no-interaction
+
+    echo "Finished composerInstallCheckHook"
+}
+
+composerInstallInstallHook() {
+    echo "Executing composerInstallInstallHook"
+
+    # Finally, run `composer install` to install the dependencies and generate
+    # the autoloader.
+    # The COMPOSER_ROOT_VERSION environment variable is needed only for
+    # vimeo/psalm.
+    COMPOSER_CACHE_DIR=/dev/null \
+    COMPOSER_DISABLE_NETWORK=1 \
+    COMPOSER_ROOT_VERSION="${version}" \
+    COMPOSER_MIRROR_PATH_REPOS="1" \
+    composer \
+      --no-ansi \
+      --no-interaction \
+      ${composerNoDev:+--no-dev} \
+      ${composerNoPlugins:+--no-plugins} \
+      ${composerNoScripts:+--no-scripts} \
+      install
+
+    # Remove packages.json, we don't need it in the store.
+    rm packages.json
+
+    # Copy the relevant files only in the store.
+    mkdir -p "$out"/share/php/"${pname}"
+    cp -r . "$out"/share/php/"${pname}"/
+
+    # Create symlinks for the binaries.
+    jq -r -c 'try .bin[]' composer.json | while read -r bin; do
+        mkdir -p "$out"/share/php/"${pname}" "$out"/bin
+        makeWrapper "$out"/share/php/"${pname}"/"$bin" "$out"/bin/"$(basename "$bin")"
+    done
+
+    echo "Finished composerInstallInstallHook"
+}
diff --git a/nixpkgs/pkgs/build-support/php/hooks/composer-repository-hook.sh b/nixpkgs/pkgs/build-support/php/hooks/composer-repository-hook.sh
new file mode 100644
index 000000000000..057acf1fcc30
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/php/hooks/composer-repository-hook.sh
@@ -0,0 +1,69 @@
+declare composerLock
+declare version
+declare composerNoDev
+declare composerNoPlugins
+declare composerNoScripts
+
+preConfigureHooks+=(composerRepositoryConfigureHook)
+preBuildHooks+=(composerRepositoryBuildHook)
+preCheckHooks+=(composerRepositoryCheckHook)
+preInstallHooks+=(composerRepositoryInstallHook)
+
+composerRepositoryConfigureHook() {
+    echo "Executing composerRepositoryConfigureHook"
+
+    if [[ -e "$composerLock" ]]; then
+        cp $composerLock composer.lock
+    fi
+
+    if [[ ! -f "composer.lock" ]]; then
+        echo "No composer.lock file found, consider adding one to your repository to ensure reproducible builds."
+        composer \
+            --no-ansi \
+            --no-install \
+            --no-interaction \
+            ${composerNoDev:+--no-dev} \
+            ${composerNoPlugins:+--no-plugins} \
+            ${composerNoScripts:+--no-scripts} \
+            update
+        echo "Using an autogenerated composer.lock file."
+    fi
+
+    echo "Finished composerRepositoryConfigureHook"
+}
+
+composerRepositoryBuildHook() {
+    echo "Executing composerRepositoryBuildHook"
+
+    mkdir -p repository
+
+    # Build the local composer repository
+    # The command 'build-local-repo' is provided by the Composer plugin
+    # nix-community/composer-local-repo-plugin.
+    COMPOSER_CACHE_DIR=/dev/null \
+    composer-local-repo-plugin --no-ansi build-local-repo ${composerNoDev:+--no-dev} -r repository
+
+    echo "Finished composerRepositoryBuildHook"
+}
+
+composerRepositoryCheckHook() {
+    echo "Executing composerRepositoryCheckHook"
+
+    composer validate --no-ansi --no-interaction
+
+    echo "Finished composerRepositoryCheckHook"
+}
+
+composerRepositoryInstallHook() {
+    echo "Executing composerRepositoryInstallHook"
+
+    mkdir -p $out
+
+    cp -ar repository/. $out/
+
+    # Copy the composer.lock files to the output directory, in case it has been
+    # autogenerated.
+    cp composer.lock $out/
+
+    echo "Finished composerRepositoryInstallHook"
+}
diff --git a/nixpkgs/pkgs/build-support/php/hooks/default.nix b/nixpkgs/pkgs/build-support/php/hooks/default.nix
new file mode 100644
index 000000000000..e7de98647c39
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/php/hooks/default.nix
@@ -0,0 +1,22 @@
+{ makeSetupHook
+, jq
+, moreutils
+, makeBinaryWrapper
+, php
+}:
+
+{
+  composerRepositoryHook = makeSetupHook
+    {
+      name = "composer-repository-hook.sh";
+      propagatedBuildInputs = [ jq moreutils php ];
+      substitutions = { };
+    } ./composer-repository-hook.sh;
+
+  composerInstallHook = makeSetupHook
+    {
+      name = "composer-install-hook.sh";
+      propagatedBuildInputs = [ jq makeBinaryWrapper moreutils php ];
+      substitutions = { };
+    } ./composer-install-hook.sh;
+}
diff --git a/nixpkgs/pkgs/build-support/php/pkgs/composer-local-repo-plugin.nix b/nixpkgs/pkgs/build-support/php/pkgs/composer-local-repo-plugin.nix
new file mode 100644
index 000000000000..67edbf1f44f9
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/php/pkgs/composer-local-repo-plugin.nix
@@ -0,0 +1,112 @@
+{ callPackage, stdenvNoCC, lib, fetchFromGitHub, makeBinaryWrapper }:
+
+let
+  composer = callPackage ./composer-phar.nix { };
+
+  composerKeys = stdenvNoCC.mkDerivation (finalComposerKeysAttrs: {
+    pname = "composer-keys";
+    version = "fa5a62092f33e094073fbda23bbfc7188df3cbc5";
+
+    src = fetchFromGitHub {
+      owner = "composer";
+      repo = "composer.github.io";
+      rev = "${finalComposerKeysAttrs.version}";
+      hash = "sha256-3Sfn71LDG1jHwuEIU8iEnV3k6D6QTX7KVIKVaNSuCVE=";
+    };
+
+    installPhase = ''
+      runHook preInstall
+
+      mkdir -p $out
+      install releases.pub $out/keys.tags.pub
+      install snapshots.pub $out/keys.dev.pub
+
+      runHook postInstall
+    '';
+  });
+in
+stdenvNoCC.mkDerivation (finalAttrs: {
+  pname = "composer-local-repo-plugin";
+  version = "1.0.0";
+
+  src = fetchFromGitHub {
+    owner = "nix-community";
+    repo = "composer-local-repo-plugin";
+    rev = finalAttrs.version;
+    hash = "sha256-sjWV4JXK8YJ5XLASMPipKlk9u57352wIDV2PPFIP+sk=";
+  };
+
+  COMPOSER_CACHE_DIR = "/dev/null";
+  COMPOSER_MIRROR_PATH_REPOS = "1";
+  COMPOSER_HTACCESS_PROTECT = "0";
+  COMPOSER_DISABLE_NETWORK = "1";
+
+  nativeBuildInputs = [
+    makeBinaryWrapper
+  ];
+
+  buildInputs = [
+    composer
+  ];
+
+  configurePhase = ''
+    runHook preConfigure
+
+    export COMPOSER_HOME=${placeholder "out"}
+
+    runHook postConfigure
+  '';
+
+  buildPhase = ''
+    runHook preBuild
+
+    # Configure composer globally
+    composer global init --quiet --no-interaction --no-ansi \
+      --name="nixos/composer" \
+      --homepage "https://nixos.org/" \
+      --description "Composer with nix-community/composer-local-repo-plugin" \
+      --license "MIT"
+
+    composer global config --quiet minimum-stability dev
+    composer global config --quiet prefer-stable true
+    composer global config --quiet autoloader-suffix "nixPredictableAutoloaderSuffix"
+    composer global config --quiet apcu-autoloader false
+    composer global config --quiet allow-plugins.nix-community/composer-local-repo-plugin true
+    composer global config --quiet repo.packagist false
+    composer global config --quiet repo.plugin path $src
+
+    # Install the local repository plugin
+    composer global require --quiet --no-ansi --no-interaction nix-community/composer-local-repo-plugin
+
+    runHook postBuild
+  '';
+
+  checkPhase = ''
+    runHook preCheck
+
+    composer global validate --no-ansi
+    composer global show --no-ansi nix-community/composer-local-repo-plugin
+
+    runHook postCheck
+  '';
+
+  installPhase = ''
+    runHook preInstall
+
+    mkdir -p $out
+    cp -ar ${composerKeys}/* $out/
+
+    makeWrapper ${composer}/bin/composer $out/bin/composer-local-repo-plugin \
+      --prefix COMPOSER_HOME : $out
+
+    runHook postInstall
+  '';
+
+  meta = {
+    description = "Composer local repo plugin for Composer";
+    homepage = "https://github.com/nix-community/composer-local-repo-plugin";
+    license = lib.licenses.mit;
+    maintainers = with lib.maintainers; [ drupol ];
+    platforms = lib.platforms.all;
+  };
+})
diff --git a/nixpkgs/pkgs/build-support/php/pkgs/composer-phar.nix b/nixpkgs/pkgs/build-support/php/pkgs/composer-phar.nix
new file mode 100644
index 000000000000..41cba03f4f5d
--- /dev/null
+++ b/nixpkgs/pkgs/build-support/php/pkgs/composer-phar.nix
@@ -0,0 +1,48 @@
+{
+  _7zz
+  , cacert
+  , curl
+  , fetchurl
+  , git
+  , lib
+  , makeBinaryWrapper
+  , php
+  , stdenvNoCC
+  , unzip
+  , xz
+}:
+
+stdenvNoCC.mkDerivation (finalAttrs: {
+  pname = "composer-phar";
+  version = "2.6.2";
+
+  src = fetchurl {
+    url = "https://github.com/composer/composer/releases/download/${finalAttrs.version}/composer.phar";
+    hash = "sha256-iMhNSlP88cJ9Z2Lh1da3DVfG3J0uIxT9Cdv4a/YeGu8=";
+  };
+
+  dontUnpack = true;
+
+  nativeBuildInputs = [ makeBinaryWrapper ];
+
+  installPhase = ''
+    runHook preInstall
+
+    mkdir -p $out/bin
+    install -D $src $out/libexec/composer/composer.phar
+    makeWrapper ${php}/bin/php $out/bin/composer \
+      --add-flags "$out/libexec/composer/composer.phar" \
+      --prefix PATH : ${lib.makeBinPath [ _7zz cacert curl git unzip xz ]}
+
+    runHook postInstall
+  '';
+
+  meta = {
+    changelog = "https://github.com/composer/composer/releases/tag/${finalAttrs.version}";
+    description = "Dependency Manager for PHP, shipped from the PHAR file";
+    homepage = "https://getcomposer.org/";
+    license = lib.licenses.mit;
+    maintainers = with lib.maintainers; [ drupol ];
+    platforms = lib.platforms.all;
+  };
+})
diff --git a/nixpkgs/pkgs/build-support/setup-hooks/desktop-to-darwin-bundle.sh b/nixpkgs/pkgs/build-support/setup-hooks/desktop-to-darwin-bundle.sh
index e4e7fba84770..5b38f4376070 100644
--- a/nixpkgs/pkgs/build-support/setup-hooks/desktop-to-darwin-bundle.sh
+++ b/nixpkgs/pkgs/build-support/setup-hooks/desktop-to-darwin-bundle.sh
@@ -204,8 +204,8 @@ processExecFieldCodes() {
   local -r execNoKC="${execNoK/\%c/$(getDesktopParam "${file}" "Name")}"
   local -r icon=$(getDesktopParam "${file}" "Icon")
   local -r execNoKCI="${execNoKC/\%i/${icon:+--icon }${icon}}"
-  local -r execNoKCIfu="${execNoKCI/\%[fu]/\$1}"
-  local -r exec="${execNoKCIfu/\%[FU]/\$@}"
+  local -r execNoKCIfu="${execNoKCI/ \%[fu]/}"
+  local -r exec="${execNoKCIfu/ \%[FU]/}"
   if [[ "$exec" != "$execRaw" ]]; then
     echo 1>&2 "desktopToDarwinBundle: Application bundles do not understand desktop entry field codes. Changed '$execRaw' to '$exec'."
   fi