Skip to content

Commit 2b573c6

Browse files
authored
Merge pull request #425 from asgrim/fix-configure-options-causing-package-not-found
Fix configure options causing package not found
2 parents 6df445e + 9bac9f8 commit 2b573c6

File tree

7 files changed

+144
-43
lines changed

7 files changed

+144
-43
lines changed

.github/workflows/continuous-integration.yml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,9 @@ jobs:
9898
libbz2-dev \
9999
libzip-dev
100100
- name: "Set php-src download URL"
101-
if: ${{ !startsWith(matrix.php-versions, '8.5') }}
102101
run: |
103102
DIST_URL=`curl -fsSL "https://www.php.net/releases/index.php?json&max=1&version=${{ matrix.php-versions }}" | jq -r '.[].source[]|select(.filename|endswith(".gz")).filename'`
104103
echo "php_src_download_url=https://www.php.net/distributions/$DIST_URL" >> $GITHUB_ENV
105-
- name: "Set php-src download URL (8.5 pre-release)"
106-
if: ${{ startsWith(matrix.php-versions, '8.5') }}
107-
run: |
108-
RC_URL=`curl -fsSL "https://www.php.net/release-candidates.php?format=json" | jq -r '.releases[]|select(.version|startswith("${{ matrix.php-versions }}")).files.gz.path'`
109-
echo "php_src_download_url=$RC_URL" >> $GITHUB_ENV
110104
- name: "Install PHP ${{ matrix.php-versions }}"
111105
run: |
112106
mkdir -p /tmp/php

features/build-extensions.feature

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Feature: Extensions can be built with PIE
2+
3+
# pie build <ext>
4+
Example: An extension can be built
5+
When I run a command to build an extension
6+
Then the extension should have been built
7+
8+
# pie build <ext>
9+
Example: An extension can be built with warnings at PHP startup
10+
Given I have an invalid extension installed
11+
When I run a command to build an extension
12+
Then the extension should have been built
13+
14+
# pie build <ext> --with-some-options=foo
15+
Example: An extension can be built with configure options
16+
When I run a command to build an extension with configure options
17+
Then the extension should have been built with options
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Feature: Extensions can be downloaded with PIE
2+
3+
# pie download <ext>
4+
Example: The latest version of an extension can be downloaded
5+
When I run a command to download the latest version of an extension
6+
Then the latest version should have been downloaded
7+
8+
# pie download <ext>:<version>
9+
Scenario Outline: A version matching the requested constraint can be downloaded
10+
When I run a command to download version "<constraint>" of an extension
11+
Then version "<version>" should have been downloaded
12+
13+
Examples:
14+
| constraint | version |
15+
| 2.0.5 | 2.0.5 |
16+
| ^2.0 | 2.0.5 |
17+
18+
# pie download <ext>:dev-main
19+
@non-windows
20+
Example: An in-development version can be downloaded on non-Windows systems
21+
When I run a command to download version "dev-main" of an extension
22+
Then version "dev-main" should have been downloaded

features/install-extensions.feature

Lines changed: 0 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,5 @@
11
Feature: Extensions can be installed with PIE
22

3-
# pie download <ext>
4-
Example: The latest version of an extension can be downloaded
5-
When I run a command to download the latest version of an extension
6-
Then the latest version should have been downloaded
7-
8-
# pie download <ext>:<version>
9-
Scenario Outline: A version matching the requested constraint can be downloaded
10-
When I run a command to download version "<constraint>" of an extension
11-
Then version "<version>" should have been downloaded
12-
13-
Examples:
14-
| constraint | version |
15-
| 2.0.5 | 2.0.5 |
16-
| ^2.0 | 2.0.5 |
17-
18-
# pie download <ext>:dev-main
19-
@non-windows
20-
Example: An in-development version can be downloaded on non-Windows systems
21-
When I run a command to download version "dev-main" of an extension
22-
Then version "dev-main" should have been downloaded
23-
24-
# pie build <ext>
25-
Example: An extension can be built
26-
When I run a command to build an extension
27-
Then the extension should have been built
28-
29-
Example: An extension can be built with warnings at PHP startup
30-
Given I have an invalid extension installed
31-
When I run a command to build an extension
32-
Then the extension should have been built
33-
34-
# pie build <ext> --with-some-options=foo
35-
Example: An extension can be built with configure options
36-
When I run a command to build an extension with configure options
37-
Then the extension should have been built with options
38-
393
# pie install <ext> --skip-enable-extension
404
Example: An extension can be installed without enabling
415
When I run a command to install an extension without enabling it

src/Command/ArgvInput.php

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Php\Pie\Command;
6+
7+
use Throwable;
8+
9+
class ArgvInput extends \Symfony\Component\Console\Input\ArgvInput
10+
{
11+
private Throwable|null $exceptionThrown = null;
12+
13+
/**
14+
* Wrap parent token parsing to collect and ignore exceptions during
15+
* parsing. This ensures that errors we meet mid-way through parsing don't
16+
* short-circuit processing the rest of the arguments. Without this, whilst
17+
* the following example works:
18+
*
19+
* pie build asgrim/example-pie-extension --with-hello-name=sup
20+
*
21+
* This does not:
22+
*
23+
* pie build --with-hello-name=sup asgrim/example-pie-extension
24+
*
25+
* This is because when Symfony tries to parse the `--with-hello-name`, it
26+
* hasn't loaded in the configure options for the package yet, and so
27+
* throws an exception and does not process the package name argument.
28+
*
29+
* Note, however, there is still a limitation, as this will not work:
30+
*
31+
* pie build --with-hello-name sup asgrim/example-pie-extension
32+
*/
33+
protected function parse(): void
34+
{
35+
$this->exceptionThrown = null;
36+
37+
parent::parse();
38+
39+
if ($this->exceptionThrown !== null) {
40+
throw $this->exceptionThrown;
41+
}
42+
}
43+
44+
protected function parseToken(string $token, bool $parseOptions): bool
45+
{
46+
try {
47+
return parent::parseToken($token, $parseOptions);
48+
} catch (Throwable $caught) {
49+
$this->exceptionThrown = $caught;
50+
51+
// Ignore the error intentionally
52+
return $parseOptions;
53+
}
54+
}
55+
}

src/Container.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
use Php\Pie\Building\Build;
1414
use Php\Pie\Building\UnixBuild;
1515
use Php\Pie\Building\WindowsBuild;
16+
use Php\Pie\Command\ArgvInput;
1617
use Php\Pie\Command\BuildCommand;
1718
use Php\Pie\Command\DownloadCommand;
1819
use Php\Pie\Command\InfoCommand;
@@ -43,7 +44,6 @@
4344
use Symfony\Component\Console\Event\ConsoleCommandEvent;
4445
use Symfony\Component\Console\Formatter\OutputFormatter;
4546
use Symfony\Component\Console\Helper\QuestionHelper;
46-
use Symfony\Component\Console\Input\ArgvInput;
4747
use Symfony\Component\Console\Input\InputInterface;
4848
use Symfony\Component\Console\Output\ConsoleOutput;
4949
use Symfony\Component\Console\Output\OutputInterface;
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Php\PieUnitTest\Command;
6+
7+
use Php\Pie\Command\ArgvInput;
8+
use PHPUnit\Framework\Attributes\CoversClass;
9+
use PHPUnit\Framework\Attributes\DataProvider;
10+
use PHPUnit\Framework\TestCase;
11+
use Symfony\Component\Console\Input\InputArgument;
12+
use Symfony\Component\Console\Input\InputDefinition;
13+
use Throwable;
14+
15+
#[CoversClass(ArgvInput::class)]
16+
final class ArgvInputTest extends TestCase
17+
{
18+
/** @return array<string, list<list<string>>> */
19+
public static function argvWithInvalidInputProvider(): array
20+
{
21+
return [
22+
'simple-option' => [['myapp', '--invalid-option', 'myvalue']],
23+
'value-option' => [['myapp', '--invalid-option=foo', 'myvalue']],
24+
'short-option' => [['myapp', '-i', 'myvalue']],
25+
// explicitly not supported for now; we can't tell which is the argument here
26+
// 'split-option' => [['myapp', '--invalid-option', 'foo', 'myvalue']],
27+
];
28+
}
29+
30+
/** @param list<string> $argv */
31+
#[DataProvider('argvWithInvalidInputProvider')]
32+
public function testInvalidOptionsDoNotCauseArgumentsToBeMissed(array $argv): void
33+
{
34+
$definition = new InputDefinition();
35+
$definition->addArgument(new InputArgument('myarg', InputArgument::OPTIONAL));
36+
37+
$argvInput = new ArgvInput($argv);
38+
try {
39+
$argvInput->bind($definition);
40+
self::fail('Expected an exception to be thrown because `--invalid-option` is not defined');
41+
} catch (Throwable) {
42+
// An exception is expected here, because `--invalid-option` was not defined
43+
self::addToAssertionCount(1);
44+
}
45+
46+
// But, crucially, we should have captured the following argument
47+
self::assertSame('myvalue', $argvInput->getArgument('myarg'));
48+
}
49+
}

0 commit comments

Comments
 (0)