about summary refs log tree commit diff
path: root/nixpkgs/pkgs/build-support/php/hooks/composer-install-hook.sh
blob: ab7756aef4f122b1cd68a2658571758e8a9d8f15 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
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
        composer \
            --no-ansi \
            --no-install \
            --no-interaction \
            ${composerNoDev:+--no-dev} \
            ${composerNoPlugins:+--no-plugins} \
            ${composerNoScripts:+--no-scripts} \
            update

        mkdir -p $out
        cp composer.lock $out/

        echo
        echo 'No composer.lock file found, consider adding one to your repository to ensure reproducible builds.'
        echo "In the meantime, a composer.lock file has been generated for you in $out/composer.lock"
        echo
        echo 'To fix the issue:'
        echo "1. Copy the composer.lock file from $out/composer.lock to the project's source:"
        echo "  cp $out/composer.lock <path>"
        echo '2. Add the composerLock attribute, pointing to the copied composer.lock file:'
        echo '  composerLock = ./composer.lock;'
        echo

        exit 1
    fi

    echo "Validating consistency between composer.lock and ${composerRepository}/composer.lock"
    if ! @cmp@ -s "composer.lock" "${composerRepository}/composer.lock"; then
        echo
        echo "ERROR: vendorHash is out of date"
        echo
        echo "composer.lock is not the same in $composerRepository"
        echo
        echo "To fix the issue:"
        echo '1. Set vendorHash to an empty string: `vendorHash = "";`'
        echo '2. Build the derivation and wait for it to fail with a hash mismatch'
        echo '3. Copy the "got: sha256-..." value back into the vendorHash field'
        echo '   You should have: vendorHash = "sha256-XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX=";'
        echo

        exit 1
    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 -m "${composerRepository}" .

    # Remove all the repositories of type "composer" and "vcs"
    # from the composer.json file.
    jq -r -c 'del(try .repositories[] | select(.type == "composer" or .type == "vcs"))' 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_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_ROOT_VERSION="${version}" \
    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"
}