Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
d0eb650
Move Composer event listeners into namespace
asgrim Jan 29, 2025
fa79308
Externalise the possible asset names when fetching release assets
asgrim Jan 29, 2025
48cab2f
Update download URL override to support different DownloadUrlMethod v…
asgrim Jan 30, 2025
4915713
Refactor PIE Package VO to improve the API
asgrim Jan 31, 2025
011c511
Add {version} template to download package path
asgrim Feb 3, 2025
7362b27
Add handling for override-download-url-method configuration
asgrim Feb 3, 2025
205d478
Move php-ext schema from pie-design repo
asgrim Feb 3, 2025
1806bb9
CS and SA fixes
asgrim Feb 4, 2025
68b3428
Documentation for override-download-url-method
asgrim Feb 4, 2025
edcc851
Update docs with actual expected build path
asgrim Feb 5, 2025
7e3b16f
Update to remove superfluous override- prefix and pull latest compose…
asgrim Feb 5, 2025
52ca666
Specify Package VO defaults in properties
asgrim Feb 6, 2025
1cb972b
Removed testing package name format
asgrim Feb 6, 2025
e9eb4ff
Add remaining unit tests for download URL override
asgrim Feb 6, 2025
afd8a8c
Fix help for package+version command hint
asgrim Feb 7, 2025
eccc8ac
Split out PIE package installed.json processor
asgrim Feb 7, 2025
3b26156
Do not purge packages so they remain available in pie show even after…
asgrim Feb 7, 2025
b3ade18
Improve BinaryFile with verify methods
asgrim Feb 12, 2025
2121410
Added component to remove INI entries for a package
asgrim Feb 12, 2025
dd22619
Added component to uninstall the installed binary
asgrim Feb 12, 2025
0a4677a
ComposerIntegrationHandler no longer __invoke
asgrim Feb 17, 2025
8762065
Add method to remove a require from pie.json
asgrim Feb 17, 2025
9fac585
Added uninstall to PieOperation enum
asgrim Feb 17, 2025
742d0ca
Added ComposerIntegrationHandler#runUninstall
asgrim Feb 17, 2025
058a5ef
Added Composer uninstall processor for PiePackageInstaller
asgrim Feb 17, 2025
f305935
Use Composer in InstalledPiePackages
asgrim Feb 20, 2025
4b33470
Fix uninstall and complete tests
asgrim Feb 24, 2025
6cda93b
Disable uninstall command for Windows
asgrim Feb 25, 2025
64c05ce
Use sudo to remove the binary if no permissions given
asgrim Feb 25, 2025
e835b5e
Move BinaryFile into new File namespace
asgrim Feb 26, 2025
80f835f
Util to capture and return errors running a function
asgrim Feb 26, 2025
2d7b503
Added Sudo locator
asgrim Feb 26, 2025
dccc695
Added file util to write to a file with sudo
asgrim Feb 26, 2025
cedd3ae
Use sudo to write INI file to remove the INI entry
asgrim Feb 26, 2025
2a3e8a9
Only run SudoFilePutTest if allowed
asgrim Feb 26, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions bin/pie
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ use Php\Pie\Command\RepositoryAddCommand;
use Php\Pie\Command\RepositoryListCommand;
use Php\Pie\Command\RepositoryRemoveCommand;
use Php\Pie\Command\ShowCommand;
use Php\Pie\Command\UninstallCommand;
use Php\Pie\Util\PieVersion;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
Expand All @@ -37,6 +38,7 @@ $application->setCommandLoader(new ContainerCommandLoader(
'repository:list' => RepositoryListCommand::class,
'repository:add' => RepositoryAddCommand::class,
'repository:remove' => RepositoryRemoveCommand::class,
'uninstall' => UninstallCommand::class,
]
));

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
],
"require": {
"php": "8.1.*||8.2.*||8.3.*||8.4.*",
"composer/composer": "^2.8.5",
"composer/composer": "dev-main",
"composer/pcre": "^3.3.2",
"composer/semver": "^3.4.3",
"fidry/cpu-core-counter": "^1.2",
Expand Down
21 changes: 12 additions & 9 deletions composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 20 additions & 0 deletions docs/extension-maintainers.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,26 @@ should specify this path in `build-path`, for example:
}
```

The `build-path` may contain some templated values which are replaced:

* `{version}` to be replaced with the package version. For example a package
with version 1.2.3 with a `build-path` of `myext-{version}` the actual build
path would become `myext-1.2.3`.

#### `download-url-method`

The `download-url-method` directive allows extension maintainers to
change the behaviour of downloading the source package.

* Setting this to `composer-default`, which is the default value if not
specified, will use the default behaviour implemented by Composer, which is
to use the standard ZIP archive from the GitHub API (or other source control
system).
* Using `pre-packaged-source` will locate a source code package in the release
assets list based matching one of the following naming conventions:
* `php_{ExtensionName}-{Version}-src.tgz` (e.g. `php_myext-1.20.1-src.tgz`)
* `php_{ExtensionName}-{Version}-src.zip` (e.g. `php_myext-1.20.1-src.zip`)

### Extension dependencies

Extension authors may define some dependencies in `require`, but practically,
Expand Down
8 changes: 8 additions & 0 deletions features/uninstall-extensions.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Feature: Extensions can be uninstalled with PIE

# See https://github.com/php/pie/issues/190 for why this is non-Windows
@non-windows
Example: An extension can be uninstalled
Given an extension was previously installed
When I run a command to uninstall an extension
Then the extension should not be installed anymore
106 changes: 106 additions & 0 deletions resources/composer-json-php-ext-schema.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://raw.githubusercontent.com/php/pie/main/composer-json-php-ext-schema.json",
"title": "composer.json php-ext schema",
"description": "Schema for the proposed php-ext section in composer.json that the new PECL will use to build packages",
"type": "object",
"properties": {
"php-ext": {
"type": "object",
"description": "Settings for PHP extension packages.",
"properties": {
"extension-name": {
"type": "string",
"description": "If specified, this will be used as the name of the extension, where needed by tooling. If this is not specified, the extension name will be derived from the Composer package name (e.g. `vendor/name` would become `ext-name`). The extension name may be specified with or without the `ext-` prefix, and tools that use this must normalise this appropriately.",
"example": "ext-xdebug"
},
"priority": {
"type": "integer",
"description": "This is used to add a prefix to the INI file, e.g. `90-xdebug.ini` which affects the loading order. The priority is a number in the range 10-99 inclusive, with 10 being the highest priority (i.e. will be processed first), and 99 being the lowest priority (i.e. will be processed last). There are two digits so that the files sort correctly on any platform, whether the sorting is natural or not.",
"minimum": 10,
"maximum": 99,
"example": 80,
"default": 80
},
"support-zts": {
"type": "boolean",
"description": "Does this package support Zend Thread Safety",
"example": false,
"default": true
},
"support-nts": {
"type": "boolean",
"description": "Does this package support non-Thread Safe mode",
"example": false,
"default": true
},
"build-path": {
"type": ["string", "null"],
"description": "If specified, this is the subdirectory that will be used to build the extension instead of the root of the project.",
"example": "my-extension-source",
"default": null
},
"download-url-method": {
"type": "string",
"description": "If specified, this technique will be used to override the URL that PIE uses to download the asset. The default, if not specified, is composer-default.",
"enum": ["composer-default", "pre-packaged-source"],
"example": "composer-default"
},
"os-families": {
"type": "array",
"minItems": 1,
"description": "An array of OS families to mark as compatible with the extension. Specifying this property will mean this package is not installable with PIE on any OS family not listed here. Must not be specified alongside os-families-exclude.",
"items": {
"type": "string",
"enum": ["windows", "bsd", "darwin", "solaris", "linux", "unknown"],
"description": "The name of the OS family to mark as compatible."
}
},
"os-families-exclude": {
"type": "array",
"minItems": 1,
"description": "An array of OS families to mark as incompatible with the extension. Specifying this property will mean this package is installable on any OS family except those listed here. Must not be specified alongside os-families.",
"items": {
"type": "string",
"enum": ["windows", "bsd", "darwin", "solaris", "linux", "unknown"],
"description": "The name of the OS family to exclude."
}
},
"configure-options": {
"type": "array",
"description": "These configure options make up the flags that can be passed to ./configure when installing the extension.",
"items": {
"type": "object",
"required": ["name"],
"properties": {
"name": {
"type": "string",
"description": "The name of the flag, this would typically be prefixed with `--`, for example, the value 'the-flag' would be passed as `./configure --the-flag`.",
"example": "without-xdebug-compression",
"pattern": "^[a-zA-Z0-9][a-zA-Z0-9-_]*$"
},
"needs-value": {
"type": "boolean",
"description": "If this is set to true, the flag needs a value (e.g. --with-somelib=<path>), otherwise it is a flag without a value (e.g. --enable-some-feature).",
"example": false,
"default": false
},
"description": {
"type": "string",
"description": "The description of what the flag does or means.",
"example": "Disable compression through zlib"
}
}
}
}
},
"allOf": [
{
"not": {
"required": ["os-families", "os-families-exclude"]
}
}
]
}
}
}
2 changes: 1 addition & 1 deletion src/Building/Build.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

namespace Php\Pie\Building;

use Php\Pie\BinaryFile;
use Php\Pie\Downloading\DownloadedPackage;
use Php\Pie\File\BinaryFile;
use Php\Pie\Platform\TargetPhp\PhpizePath;
use Php\Pie\Platform\TargetPlatform;
use Symfony\Component\Console\Output\OutputInterface;
Expand Down
4 changes: 2 additions & 2 deletions src/Building/UnixBuild.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

namespace Php\Pie\Building;

use Php\Pie\BinaryFile;
use Php\Pie\Downloading\DownloadedPackage;
use Php\Pie\File\BinaryFile;
use Php\Pie\Platform\TargetPhp\PhpizePath;
use Php\Pie\Platform\TargetPlatform;
use Php\Pie\Util\Process;
Expand Down Expand Up @@ -76,7 +76,7 @@ public function __invoke(

$this->make($targetPlatform, $downloadedPackage, $output, $outputCallback);

$expectedSoFile = $downloadedPackage->extractedSourcePath . '/modules/' . $downloadedPackage->package->extensionName->name() . '.so';
$expectedSoFile = $downloadedPackage->extractedSourcePath . '/modules/' . $downloadedPackage->package->extensionName()->name() . '.so';

if (! file_exists($expectedSoFile)) {
throw ExtensionBinaryNotFound::fromExpectedBinary($expectedSoFile);
Expand Down
2 changes: 1 addition & 1 deletion src/Building/WindowsBuild.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

namespace Php\Pie\Building;

use Php\Pie\BinaryFile;
use Php\Pie\Downloading\DownloadedPackage;
use Php\Pie\File\BinaryFile;
use Php\Pie\Platform\TargetPhp\PhpizePath;
use Php\Pie\Platform\TargetPlatform;
use Php\Pie\Platform\WindowsExtensionAssetName;
Expand Down
4 changes: 2 additions & 2 deletions src/Command/BuildCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ public function execute(InputInterface $input, OutputInterface $output): int
$requestedNameAndVersion,
$forceInstallPackageVersion,
);
$output->writeln(sprintf('<info>Found package:</info> %s which provides <info>%s</info>', $package->prettyNameAndVersion(), $package->extensionName->nameWithExtPrefix()));
$output->writeln(sprintf('<info>Found package:</info> %s which provides <info>%s</info>', $package->prettyNameAndVersion(), $package->extensionName()->nameWithExtPrefix()));

// Now we know what package we have, we can validate the configure options for the command and re-create the
// Composer instance with the populated configure options
Expand All @@ -85,7 +85,7 @@ public function execute(InputInterface $input, OutputInterface $output): int
);

try {
($this->composerIntegrationHandler)(
$this->composerIntegrationHandler->runInstall(
$package,
$composer,
$targetPlatform,
Expand Down
18 changes: 9 additions & 9 deletions src/Command/CommandHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,27 +64,27 @@ public static function configurePhpConfigOptions(Command $command): void
InputOption::VALUE_REQUIRED,
'The path to the `php` binary to use as the target PHP platform on ' . OperatingSystem::Windows->asFriendlyName() . ', e.g. --' . self::OPTION_WITH_PHP_PATH . '=C:\usr\php7.4.33\php.exe',
);
$command->addOption(
self::OPTION_WITH_PHPIZE_PATH,
null,
InputOption::VALUE_REQUIRED,
'The path to the `phpize` binary to use as the target PHP platform, e.g. --' . self::OPTION_WITH_PHPIZE_PATH . '=/usr/bin/phpize7.4',
);
}

public static function configureDownloadBuildInstallOptions(Command $command): void
{
$command->addArgument(
self::ARG_REQUESTED_PACKAGE_AND_VERSION,
InputArgument::REQUIRED,
'The extension name and version constraint to use, in the format {ext-name}{?:{?version-constraint}{?@stability}}, for example `xdebug/xdebug:^3.4@alpha`, `xdebug/xdebug:@alpha`, `xdebug/xdebug:^3.4`, etc.',
'The PIE package name and version constraint to use, in the format {vendor/package}{?:{?version-constraint}{?@stability}}, for example `xdebug/xdebug:^3.4@alpha`, `xdebug/xdebug:@alpha`, `xdebug/xdebug:^3.4`, etc.',
);
$command->addOption(
self::OPTION_MAKE_PARALLEL_JOBS,
'j',
InputOption::VALUE_REQUIRED,
'Override many jobs to run in parallel when running compiling (this is passed to "make -jN" during build). PIE will try to detect this by default.',
);
$command->addOption(
self::OPTION_WITH_PHPIZE_PATH,
null,
InputOption::VALUE_REQUIRED,
'The path to the `phpize` binary to use as the target PHP platform, e.g. --' . self::OPTION_WITH_PHPIZE_PATH . '=/usr/bin/phpize7.4',
);
$command->addOption(
self::OPTION_SKIP_ENABLE_EXTENSION,
null,
Expand Down Expand Up @@ -226,7 +226,7 @@ public static function requestedNameAndVersionPair(InputInterface $input): Reque

public static function bindConfigureOptionsFromPackage(Command $command, Package $package, InputInterface $input): void
{
foreach ($package->configureOptions as $configureOption) {
foreach ($package->configureOptions() as $configureOption) {
$command->addOption(
$configureOption->name,
null,
Expand All @@ -242,7 +242,7 @@ public static function bindConfigureOptionsFromPackage(Command $command, Package
public static function processConfigureOptionsFromInput(Package $package, InputInterface $input): array
{
$configureOptionsValues = [];
foreach ($package->configureOptions as $configureOption) {
foreach ($package->configureOptions() as $configureOption) {
if (! $input->hasOption($configureOption->name)) {
continue;
}
Expand Down
4 changes: 2 additions & 2 deletions src/Command/DownloadCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,10 @@ public function execute(InputInterface $input, OutputInterface $output): int
$requestedNameAndVersion,
$forceInstallPackageVersion,
);
$output->writeln(sprintf('<info>Found package:</info> %s which provides <info>%s</info>', $package->prettyNameAndVersion(), $package->extensionName->nameWithExtPrefix()));
$output->writeln(sprintf('<info>Found package:</info> %s which provides <info>%s</info>', $package->prettyNameAndVersion(), $package->extensionName()->nameWithExtPrefix()));

try {
($this->composerIntegrationHandler)(
$this->composerIntegrationHandler->runInstall(
$package,
$composer,
$targetPlatform,
Expand Down
16 changes: 8 additions & 8 deletions src/Command/InfoCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -64,17 +64,17 @@ public function execute(InputInterface $input, OutputInterface $output): int
$requestedNameAndVersion,
CommandHelper::determineForceInstallingPackageVersion($input),
);
$output->writeln(sprintf('<info>Found package:</info> %s which provides <info>%s</info>', $package->prettyNameAndVersion(), $package->extensionName->nameWithExtPrefix()));
$output->writeln(sprintf('<info>Found package:</info> %s which provides <info>%s</info>', $package->prettyNameAndVersion(), $package->extensionName()->nameWithExtPrefix()));

$output->writeln(sprintf('Extension name: %s', $package->extensionName->name()));
$output->writeln(sprintf('Extension type: %s (%s)', $package->extensionType->value, $package->extensionType->name));
$output->writeln(sprintf('Composer package name: %s', $package->name));
$output->writeln(sprintf('Version: %s', $package->version));
$output->writeln(sprintf('Download URL: %s', $package->downloadUrl ?? '(not specified)'));
$output->writeln(sprintf('Extension name: %s', $package->extensionName()->name()));
$output->writeln(sprintf('Extension type: %s (%s)', $package->extensionType()->value, $package->extensionType()->name));
$output->writeln(sprintf('Composer package name: %s', $package->name()));
$output->writeln(sprintf('Version: %s', $package->version()));
$output->writeln(sprintf('Download URL: %s', $package->downloadUrl() ?? '(not specified)'));

if (count($package->configureOptions)) {
if (count($package->configureOptions())) {
$output->writeln('Configure options:');
foreach ($package->configureOptions as $configureOption) {
foreach ($package->configureOptions() as $configureOption) {
$output->writeln(sprintf(' --%s%s (%s)', $configureOption->name, $configureOption->needsValue ? '=?' : '', $configureOption->description));
}
} else {
Expand Down
Loading