Skip to content

Commit 4add071

Browse files
committed
Add basic ability to pie install non-interactively
1 parent 8288fd6 commit 4add071

2 files changed

Lines changed: 69 additions & 26 deletions

File tree

src/Command/CommandHelper.php

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,15 @@
5151
/** @internal This is not public API for PIE, so should not be depended upon unless you accept the risk of BC breaks */
5252
final class CommandHelper
5353
{
54-
public const ARG_REQUESTED_PACKAGE_AND_VERSION = 'requested-package-and-version';
55-
public const OPTION_WITH_PHP_CONFIG = 'with-php-config';
56-
public const OPTION_WITH_PHP_PATH = 'with-php-path';
57-
public const OPTION_WITH_PHPIZE_PATH = 'with-phpize-path';
58-
public const OPTION_WORKING_DIRECTORY = 'working-dir';
59-
private const OPTION_MAKE_PARALLEL_JOBS = 'make-parallel-jobs';
60-
private const OPTION_SKIP_ENABLE_EXTENSION = 'skip-enable-extension';
61-
private const OPTION_FORCE = 'force';
54+
public const ARG_REQUESTED_PACKAGE_AND_VERSION = 'requested-package-and-version';
55+
public const OPTION_WITH_PHP_CONFIG = 'with-php-config';
56+
public const OPTION_WITH_PHP_PATH = 'with-php-path';
57+
public const OPTION_WITH_PHPIZE_PATH = 'with-phpize-path';
58+
public const OPTION_WORKING_DIRECTORY = 'working-dir';
59+
public const OPTION_ALLOW_NON_INTERACTIVE_PROJECT_INSTALL = 'allow-non-interactive-project-install';
60+
private const OPTION_MAKE_PARALLEL_JOBS = 'make-parallel-jobs';
61+
private const OPTION_SKIP_ENABLE_EXTENSION = 'skip-enable-extension';
62+
private const OPTION_FORCE = 'force';
6263

6364
/** @psalm-suppress UnusedConstructor */
6465
private function __construct()
@@ -125,6 +126,13 @@ public static function configureDownloadBuildInstallOptions(Command $command, bo
125126

126127
self::configurePhpConfigOptions($command);
127128

129+
$command->addOption(
130+
self::OPTION_ALLOW_NON_INTERACTIVE_PROJECT_INSTALL,
131+
null,
132+
InputOption::VALUE_NONE,
133+
'When installing a PHP project, allow non-interactive project installations. Only used in certain contexts.',
134+
);
135+
128136
/**
129137
* Allows additional options for the `./configure` command to be passed here.
130138
* Note, this means you probably need to call {@see self::validateInput()} to validate the input manually...

src/Command/InstallExtensionsForProjectCommand.php

Lines changed: 53 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,15 @@
1717
use Php\Pie\Installing\InstallForPhpProject\FindMatchingPackages;
1818
use Php\Pie\Installing\InstallForPhpProject\InstallPiePackageFromPath;
1919
use Php\Pie\Installing\InstallForPhpProject\InstallSelectedPackage;
20+
use Php\Pie\Platform;
2021
use Php\Pie\Platform\InstalledPiePackages;
2122
use Php\Pie\Util\Emoji;
2223
use Psr\Container\ContainerInterface;
2324
use Symfony\Component\Console\Attribute\AsCommand;
2425
use Symfony\Component\Console\Command\Command;
2526
use Symfony\Component\Console\Helper\QuestionHelper;
2627
use Symfony\Component\Console\Input\InputInterface;
28+
use Symfony\Component\Console\Input\InputOption;
2729
use Symfony\Component\Console\Output\ConsoleOutputInterface;
2830
use Symfony\Component\Console\Output\NullOutput;
2931
use Symfony\Component\Console\Output\OutputInterface;
@@ -123,6 +125,17 @@ public function execute(InputInterface $input, OutputInterface $output): int
123125
return $exit;
124126
}
125127

128+
$allowNonInteractive = $input->hasOption(CommandHelper::OPTION_ALLOW_NON_INTERACTIVE_PROJECT_INSTALL) && $input->getOption(CommandHelper::OPTION_ALLOW_NON_INTERACTIVE_PROJECT_INSTALL);
129+
if (! Platform::isInteractive() && ! $allowNonInteractive) {
130+
$output->writeln(sprintf(
131+
'<warning>Aborting! You are not running in interactive mode, and --%s was not specified.</warning>',
132+
CommandHelper::OPTION_ALLOW_NON_INTERACTIVE_PROJECT_INSTALL,
133+
));
134+
// @todo more details
135+
136+
return Command::FAILURE;
137+
}
138+
126139
$targetPlatform = CommandHelper::determineTargetPlatformFromInputs($input, $output);
127140

128141
$output->writeln(sprintf(
@@ -221,27 +234,45 @@ function (Link $link) use ($pieComposer, $phpEnabledExtensions, $installedPiePac
221234
return;
222235
}
223236

224-
$choiceQuestion = new ChoiceQuestion(
225-
"\nThe following packages may be suitable, which would you like to install: ",
226-
array_merge(
227-
['None'],
228-
array_map(
229-
static function (array $match): string {
230-
return sprintf('%s: %s', $match['name'], $match['description'] ?? 'no description available');
231-
},
232-
$matches,
237+
if (! Platform::isInteractive() && count($matches) > 1) {
238+
$anyErrorsHappened = true;
239+
240+
// @todo Figure out if there is a way to improve this, safely
241+
$output->writeln(sprintf(
242+
"<warning>Multiple packages were found for %s:</warning>\n %s\n\n<warning>This means you cannot `pie install` this project interactively for now.</warning>",
243+
$extension->nameWithExtPrefix(),
244+
implode("\n ", array_column($matches, 'name')),
245+
));
246+
247+
return;
248+
}
249+
250+
if (Platform::isInteractive()) {
251+
$choiceQuestion = new ChoiceQuestion(
252+
"\nThe following packages may be suitable, which would you like to install: ",
253+
array_merge(
254+
['None'],
255+
array_map(
256+
static function (array $match): string {
257+
return sprintf('%s: %s', $match['name'], $match['description'] ?? 'no description available');
258+
},
259+
$matches,
260+
),
233261
),
234-
),
235-
0,
236-
);
262+
0,
263+
);
237264

238-
$selectedPackageAnswer = (string) $helper->ask($input, $output, $choiceQuestion);
265+
$selectedPackageAnswer = (string) $helper->ask($input, $output, $choiceQuestion);
239266

240-
if ($selectedPackageAnswer === 'None') {
241-
$output->writeln('Okay I won\'t install anything for ' . $extension->name());
242-
$anyErrorsHappened = true;
267+
if ($selectedPackageAnswer === 'None') {
268+
$output->writeln('Okay I won\'t install anything for ' . $extension->name());
269+
$anyErrorsHappened = true;
243270

244-
return;
271+
return;
272+
}
273+
$selectedPackageName = substr($selectedPackageAnswer, 0, (int) strpos($selectedPackageAnswer, ':'));
274+
} else {
275+
$selectedPackageName = $matches[0]['name'];
245276
}
246277

247278
$requestInstallConstraint = '';
@@ -250,8 +281,12 @@ static function (array $match): string {
250281
}
251282

252283
try {
284+
$output->writeln(
285+
sprintf('Invoking pie install of %s%s', $selectedPackageName, $requestInstallConstraint),
286+
OutputInterface::VERBOSITY_VERBOSE,
287+
);
253288
$this->installSelectedPackage->withPieCli(
254-
substr($selectedPackageAnswer, 0, (int) strpos($selectedPackageAnswer, ':')) . $requestInstallConstraint,
289+
$selectedPackageName . $requestInstallConstraint,
255290
$input,
256291
$output,
257292
);

0 commit comments

Comments
 (0)