mirror of
https://github.com/shivammathur/setup-php.git
synced 2026-09-25 03:15:25 +07:00
Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| d20463ddb1 |
@@ -0,0 +1,124 @@
|
|||||||
|
import {extensionPacks} from '../src/extensions';
|
||||||
|
import {execFileSync} from 'node:child_process';
|
||||||
|
import * as fs from 'node:fs';
|
||||||
|
import * as os from 'node:os';
|
||||||
|
import * as path from 'node:path';
|
||||||
|
|
||||||
|
describe('Optional macOS extension archives', () => {
|
||||||
|
it('installs packs concurrently and preserves successful packs when another fails', () => {
|
||||||
|
const directory = fs.mkdtempSync(
|
||||||
|
path.join(os.tmpdir(), 'setup-php-packs-')
|
||||||
|
);
|
||||||
|
const cache = path.join(directory, 'cache');
|
||||||
|
fs.mkdirSync(cache);
|
||||||
|
try {
|
||||||
|
for (const name of ['imagick', 'mongodb', 'memcached']) {
|
||||||
|
fs.writeFileSync(path.join(cache, name + '.json'), '{}');
|
||||||
|
}
|
||||||
|
fs.writeFileSync(
|
||||||
|
path.join(cache, 'install-extensions.cjs'),
|
||||||
|
`const fs=require('node:fs'), path=require('node:path');
|
||||||
|
const [,directory,name]=process.argv.slice(2);
|
||||||
|
fs.writeFileSync(path.join(directory,name+'.started'),'yes');
|
||||||
|
setTimeout(()=>process.exit(2),1500);
|
||||||
|
setInterval(()=>{
|
||||||
|
if (fs.readdirSync(directory).filter(file=>file.endsWith('.started')).length!==3) return;
|
||||||
|
fs.writeFileSync(path.join(directory,name+'.env'),'SASL_PATH=/cache/'+name+'\\n');
|
||||||
|
console.log('completed '+name);
|
||||||
|
process.exit(name==='mongodb'?1:0);
|
||||||
|
},10);
|
||||||
|
`
|
||||||
|
);
|
||||||
|
const output = execFileSync(
|
||||||
|
'bash',
|
||||||
|
[
|
||||||
|
'-c',
|
||||||
|
'. "$CACHE_SCRIPT"; add_env() { printf "env %s %s\\n" "$1" "$2"; }; enable_extensions() { printf "enable batch %s\\n" "$*"; }; enable_extension() { printf "enable module %s\\n" "$1"; }; php() { echo refreshed; }; (exit 0) & extension_cache_pid=$!; finish_extension_cache_downloads; test "$extension_cache_memcached_dependencies" = "igbinary msgpack"; test "$(cat /tmp/php${version}_extensions)" = refreshed; rm /tmp/php${version}_extensions'
|
||||||
|
],
|
||||||
|
{
|
||||||
|
encoding: 'utf8',
|
||||||
|
env: {
|
||||||
|
...process.env,
|
||||||
|
CACHE_SCRIPT: path.resolve(
|
||||||
|
'src/scripts/extensions/darwin_cache.sh'
|
||||||
|
),
|
||||||
|
SETUP_PHP_NODE: process.execPath,
|
||||||
|
SETUP_PHP_EXTENSION_PACKS: 'imagick mongodb memcached',
|
||||||
|
extension_cache_dir: cache,
|
||||||
|
version: 'cache-test-' + path.basename(directory),
|
||||||
|
verbose: ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
expect(output).toContain('completed imagick');
|
||||||
|
expect(output).toContain('completed memcached');
|
||||||
|
expect(output).toContain('mongodb cache unavailable');
|
||||||
|
expect(output).toContain('env SASL_PATH /cache/imagick');
|
||||||
|
expect(output).not.toContain('env SASL_PATH /cache/mongodb');
|
||||||
|
expect(output).toContain('enable batch imagick igbinary msgpack');
|
||||||
|
expect(output).toContain('enable module memcached');
|
||||||
|
expect(output).not.toContain('enable batch mongodb');
|
||||||
|
expect(output.indexOf('enable batch')).toBeLessThan(
|
||||||
|
output.indexOf('enable module memcached')
|
||||||
|
);
|
||||||
|
expect(fs.existsSync(cache)).toBe(false);
|
||||||
|
} finally {
|
||||||
|
fs.rmSync(directory, {recursive: true, force: true});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
it('selects each requested pack once', async () => {
|
||||||
|
expect(
|
||||||
|
await extensionPacks(
|
||||||
|
'imagick, mongodb, memcached, imagick, redis',
|
||||||
|
'8.4',
|
||||||
|
'darwin'
|
||||||
|
)
|
||||||
|
).toEqual(['imagick', 'mongodb', 'memcached']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it.each(['', 'redis, yaml', ':imagick', 'imagick, :imagick'])(
|
||||||
|
'does not download unused or disabled packs: %s',
|
||||||
|
async input => {
|
||||||
|
expect(await extensionPacks(input, '8.4', 'darwin')).toEqual([]);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it.each(['imagick-3.8.1', 'mongodb-beta', 'memcached-github.com/a/b@main'])(
|
||||||
|
'preserves explicit version/source installation: %s',
|
||||||
|
async input => {
|
||||||
|
expect(await extensionPacks(input, '8.4', 'darwin')).toEqual([]);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
it('selects optional packs for PHP 5.6 through 8.7', async () => {
|
||||||
|
for (const version of [
|
||||||
|
'5.6',
|
||||||
|
'7.0',
|
||||||
|
'7.1',
|
||||||
|
'7.2',
|
||||||
|
'7.3',
|
||||||
|
'7.4',
|
||||||
|
'8.0',
|
||||||
|
'8.1',
|
||||||
|
'8.2',
|
||||||
|
'8.3',
|
||||||
|
'8.4',
|
||||||
|
'8.5',
|
||||||
|
'8.6',
|
||||||
|
'8.7'
|
||||||
|
]) {
|
||||||
|
expect(
|
||||||
|
await extensionPacks('imagick, mongodb, memcached', version, 'darwin')
|
||||||
|
).toEqual(['imagick', 'mongodb', 'memcached']);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
it('keeps unsupported PHP and other platforms on their existing paths', async () => {
|
||||||
|
for (const version of ['5.4', '5.5', '7.5', '8.8', '9.0']) {
|
||||||
|
expect(await extensionPacks('imagick', version, 'darwin')).toEqual([]);
|
||||||
|
}
|
||||||
|
for (const os of ['linux', 'win32']) {
|
||||||
|
expect(await extensionPacks('imagick', '8.4', os)).toEqual([]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -1,5 +1,18 @@
|
|||||||
import * as utils from './utils';
|
import * as utils from './utils';
|
||||||
|
|
||||||
|
/** Select only unversioned, requested macOS extension caches. */
|
||||||
|
export async function extensionPacks(
|
||||||
|
extension_csv: string,
|
||||||
|
version: string,
|
||||||
|
os: string
|
||||||
|
): Promise<string[]> {
|
||||||
|
if (os !== 'darwin' || !/^(5\.6|7\.[0-4]|8\.[0-7])$/.test(version)) return [];
|
||||||
|
const requested = await utils.extensionArray(extension_csv);
|
||||||
|
return ['imagick', 'mongodb', 'memcached'].filter(
|
||||||
|
name => requested.includes(name) && !requested.includes(':' + name)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Install and enable extensions for darwin
|
* Install and enable extensions for darwin
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -31,6 +31,13 @@ export async function getScript(os: string): Promise<string> {
|
|||||||
const ini_file: string = await utils.parseIniFile(
|
const ini_file: string = await utils.parseIniFile(
|
||||||
await utils.getInput('ini-file', false)
|
await utils.getInput('ini-file', false)
|
||||||
);
|
);
|
||||||
|
const packs = await extensions.extensionPacks(extension_csv, version, os);
|
||||||
|
if (packs.length) {
|
||||||
|
process.env['SETUP_PHP_EXTENSION_PACKS'] = packs.join(' ');
|
||||||
|
process.env['SETUP_PHP_NODE'] = process.execPath;
|
||||||
|
} else {
|
||||||
|
delete process.env['SETUP_PHP_EXTENSION_PACKS'];
|
||||||
|
}
|
||||||
let script = await utils.joins('.', script_path, `'${version}'`, ini_file);
|
let script = await utils.joins('.', script_path, `'${version}'`, ini_file);
|
||||||
if (extension_csv) {
|
if (extension_csv) {
|
||||||
script += await extensions.addExtension(extension_csv, version, os);
|
script += await extensions.addExtension(extension_csv, version, os);
|
||||||
|
|||||||
@@ -77,6 +77,9 @@ add_brew_extension() {
|
|||||||
prefix=$2
|
prefix=$2
|
||||||
expected_version=${3:-}
|
expected_version=${3:-}
|
||||||
extension="$(get_extension_from_formula "$formula")"
|
extension="$(get_extension_from_formula "$formula")"
|
||||||
|
if [ "$extension" = memcached ] && [ -n "${extension_cache_memcached_dependencies:-}" ]; then
|
||||||
|
enable_extension_cache_dependencies "$extension"
|
||||||
|
fi
|
||||||
enable_extension "$extension" "$prefix"
|
enable_extension "$extension" "$prefix"
|
||||||
if check_extension "$extension" && { [ -z "$expected_version" ] || check_extension_version "$extension" "$expected_version"; }; then
|
if check_extension "$extension" && { [ -z "$expected_version" ] || check_extension_version "$extension" "$expected_version"; }; then
|
||||||
add_log "${tick:?}" "$extension" "Enabled"
|
add_log "${tick:?}" "$extension" "Enabled"
|
||||||
@@ -337,4 +340,10 @@ export HOMEBREW_NO_INSTALL_FROM_API=1
|
|||||||
configure_brew
|
configure_brew
|
||||||
read_env
|
read_env
|
||||||
self_hosted_setup
|
self_hosted_setup
|
||||||
|
if [ -n "${SETUP_PHP_EXTENSION_PACKS:-}" ]; then
|
||||||
|
# shellcheck source=.
|
||||||
|
. "$scripts/extensions/darwin_cache.sh"
|
||||||
|
start_extension_cache_downloads
|
||||||
|
fi
|
||||||
setup_php
|
setup_php
|
||||||
|
if [ -n "${SETUP_PHP_EXTENSION_PACKS:-}" ]; then finish_extension_cache_downloads; fi
|
||||||
|
|||||||
@@ -0,0 +1,87 @@
|
|||||||
|
# Optional macOS extension archives. Downloads overlap PHP installation; the
|
||||||
|
# PHP-only path never sources this file or contacts the extension cache.
|
||||||
|
start_extension_cache_downloads() {
|
||||||
|
extension_cache_dir=$(mktemp -d "${RUNNER_TEMP:-/tmp}/setup-php-extensions.XXXXXX") || return 0
|
||||||
|
(
|
||||||
|
cache_installer="$extension_cache_dir/install-extensions.cjs"
|
||||||
|
cache_primary="https://github.com/shivammathur/php-darwin/releases/download/extensions"
|
||||||
|
cache_mirror="https://artifacts.php-darwin.setup-php.com/extensions"
|
||||||
|
curl -fsSL --retry 0 --connect-timeout 3 --max-time 3 --max-filesize 2000000 \
|
||||||
|
"$cache_primary/install-extensions.cjs" -o "$cache_installer" ||
|
||||||
|
curl -fsSL --retry 0 --connect-timeout 3 --max-time 10 --max-filesize 2000000 \
|
||||||
|
"$cache_mirror/install-extensions.cjs" -o "$cache_installer" || exit 0
|
||||||
|
IFS=' ' read -r -a cache_extensions <<< "$SETUP_PHP_EXTENSION_PACKS"
|
||||||
|
"$SETUP_PHP_NODE" "$cache_installer" prefetch "$extension_cache_dir" \
|
||||||
|
"$version" "$debug" "$ts" "$(uname -m)" "${cache_extensions[@]}"
|
||||||
|
) > "$extension_cache_dir/download.log" 2>&1 &
|
||||||
|
extension_cache_pid=$!
|
||||||
|
}
|
||||||
|
|
||||||
|
finish_extension_cache_downloads() {
|
||||||
|
[ -n "${extension_cache_pid:-}" ] || return 0
|
||||||
|
wait "$extension_cache_pid" || true
|
||||||
|
extension_cache_pid=
|
||||||
|
if [[ "${verbose:-${VERBOSE:-}}" =~ ^(true|v{1,3})$ ]]; then
|
||||||
|
cat "$extension_cache_dir/download.log"
|
||||||
|
fi
|
||||||
|
if [ ! -s "$extension_cache_dir/install-extensions.cjs" ]; then
|
||||||
|
rm -rf "$extension_cache_dir"
|
||||||
|
extension_cache_dir=
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
local extension variable value index
|
||||||
|
local cache_install_names=() cache_install_pids=() cache_enable_names=()
|
||||||
|
for extension in $SETUP_PHP_EXTENSION_PACKS; do
|
||||||
|
[ -s "$extension_cache_dir/$extension.json" ] || continue
|
||||||
|
# Packs own separate directories and module names. Extract and validate them
|
||||||
|
# concurrently, then import their environments only after each one succeeds.
|
||||||
|
"$SETUP_PHP_NODE" "$extension_cache_dir/install-extensions.cjs" install "$extension_cache_dir" "$extension" \
|
||||||
|
> "$extension_cache_dir/$extension.install.log" 2>&1 &
|
||||||
|
cache_install_names+=("$extension")
|
||||||
|
cache_install_pids+=("$!")
|
||||||
|
done
|
||||||
|
for index in "${!cache_install_pids[@]}"; do
|
||||||
|
extension=${cache_install_names[$index]}
|
||||||
|
if wait "${cache_install_pids[$index]}"; then
|
||||||
|
cat "$extension_cache_dir/$extension.install.log"
|
||||||
|
while IFS='=' read -r variable value; do
|
||||||
|
case "$variable" in
|
||||||
|
MAGICK_CONFIGURE_PATH|MAGICK_CODER_MODULE_PATH|MAGICK_FILTER_MODULE_PATH|SASL_PATH)
|
||||||
|
add_env "$variable" "$value"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done < "$extension_cache_dir/$extension.env"
|
||||||
|
# Store the dependency names in shell variables; the download directory
|
||||||
|
# can be removed before the action enables its requested extensions.
|
||||||
|
if [ "$extension" = memcached ]; then
|
||||||
|
extension_cache_memcached_dependencies='igbinary msgpack'
|
||||||
|
cache_enable_names+=(igbinary msgpack)
|
||||||
|
else
|
||||||
|
cache_enable_names+=("$extension")
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
cat "$extension_cache_dir/$extension.install.log"
|
||||||
|
printf 'setup-php: %s cache unavailable for this PHP; using the existing installer\n' "$extension"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
rm -rf "$extension_cache_dir"
|
||||||
|
extension_cache_dir=
|
||||||
|
# Use the normal enabling rules, but overlap independent modules and refresh
|
||||||
|
# the loaded-module list once so later extension checks do not repeat php -m.
|
||||||
|
if [ "${#cache_enable_names[@]}" -gt 0 ]; then
|
||||||
|
enable_extensions "${cache_enable_names[@]}"
|
||||||
|
if [ -n "${extension_cache_memcached_dependencies:-}" ]; then
|
||||||
|
enable_extension memcached extension
|
||||||
|
fi
|
||||||
|
php -m > "/tmp/php${version}_extensions"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
enable_extension_cache_dependencies() {
|
||||||
|
if [ "$1" = memcached ] && [ -n "${extension_cache_memcached_dependencies:-}" ]; then
|
||||||
|
local dependency
|
||||||
|
for dependency in $extension_cache_memcached_dependencies; do
|
||||||
|
enable_extension "$dependency" extension
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user