Skip to content

Commit

Permalink
Merge pull request #19 from asgrim/build-implementation
Browse files Browse the repository at this point in the history
Build Command implementation
  • Loading branch information
asgrim authored Jul 22, 2024
2 parents c3e710e + 5713757 commit 2dc77ac
Show file tree
Hide file tree
Showing 31 changed files with 1,223 additions and 119 deletions.
2 changes: 2 additions & 0 deletions bin/pie
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ declare(strict_types=1);

namespace Php\Pie;

use Php\Pie\Command\BuildCommand;
use Php\Pie\Command\DownloadCommand;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;
Expand All @@ -21,6 +22,7 @@ $application->setCommandLoader(new ContainerCommandLoader(
$container,
[
'download' => DownloadCommand::class,
'build' => BuildCommand::class,
]
));
$application->run($container->get(InputInterface::class), $container->get(OutputInterface::class));
21 changes: 21 additions & 0 deletions src/Building/Build.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace Php\Pie\Building;

use Php\Pie\Downloading\DownloadedPackage;
use Php\Pie\Platform\TargetPlatform;
use Symfony\Component\Console\Output\OutputInterface;

/** @internal This is not public API for PIE, so should not be depended upon unless you accept the risk of BC breaks */
interface Build
{
/** @param list<non-empty-string> $configureOptions */
public function __invoke(
DownloadedPackage $downloadedPackage,
TargetPlatform $targetPlatform,
array $configureOptions,
OutputInterface $output,
): void;
}
76 changes: 76 additions & 0 deletions src/Building/UnixBuild.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
<?php

declare(strict_types=1);

namespace Php\Pie\Building;

use Php\Pie\Downloading\DownloadedPackage;
use Php\Pie\Platform\TargetPlatform;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Process\Process;

use function count;
use function file_exists;
use function implode;
use function sprintf;

/** @internal This is not public API for PIE, so should not be depended upon unless you accept the risk of BC breaks */
final class UnixBuild implements Build
{
/** {@inheritDoc} */
public function __invoke(
DownloadedPackage $downloadedPackage,
TargetPlatform $targetPlatform,
array $configureOptions,
OutputInterface $output,
): void {
$this->phpize($downloadedPackage);
$output->writeln('<info>phpize complete</info>.');

$phpConfigPath = $targetPlatform->phpBinaryPath->phpConfigPath();
if ($phpConfigPath !== null) {
$configureOptions[] = '--with-php-config=' . $phpConfigPath;
}

$this->configure($downloadedPackage, $configureOptions);
$optionsOutput = count($configureOptions) ? ' with options: ' . implode(' ', $configureOptions) : '.';
$output->writeln('<info>Configure complete</info>' . $optionsOutput);

$this->make($downloadedPackage);

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

if (! file_exists($expectedSoFile)) {
$output->writeln(sprintf(
'Build complete, but expected <comment>%s</comment> does not exist - however, this may be normal if this extension outputs the .so file in a different location.',
$expectedSoFile,
));

return;
}

$output->writeln(sprintf(
'<info>Build complete:</info> %s',
$expectedSoFile,
));
}

private function phpize(DownloadedPackage $downloadedPackage): void
{
(new Process(['phpize'], $downloadedPackage->extractedSourcePath))
->mustRun();
}

/** @param list<non-empty-string> $configureOptions */
private function configure(DownloadedPackage $downloadedPackage, array $configureOptions = []): void
{
(new Process(['./configure', ...$configureOptions], $downloadedPackage->extractedSourcePath))
->mustRun();
}

private function make(DownloadedPackage $downloadedPackage): void
{
(new Process(['make'], $downloadedPackage->extractedSourcePath))
->mustRun();
}
}
23 changes: 23 additions & 0 deletions src/Building/WindowsBuild.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

declare(strict_types=1);

namespace Php\Pie\Building;

use Php\Pie\Downloading\DownloadedPackage;
use Php\Pie\Platform\TargetPlatform;
use Symfony\Component\Console\Output\OutputInterface;

/** @internal This is not public API for PIE, so should not be depended upon unless you accept the risk of BC breaks */
final class WindowsBuild implements Build
{
/** {@inheritDoc} */
public function __invoke(
DownloadedPackage $downloadedPackage,
TargetPlatform $targetPlatform,
array $configureOptions,
OutputInterface $output,
): void {
$output->writeln('<info>Nothing to do on Windows.</info>');
}
}
58 changes: 58 additions & 0 deletions src/Command/BuildCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?php

declare(strict_types=1);

namespace Php\Pie\Command;

use Php\Pie\Building\Build;
use Php\Pie\DependencyResolver\DependencyResolver;
use Php\Pie\Downloading\DownloadAndExtract;
use Symfony\Component\Console\Attribute\AsCommand;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

#[AsCommand(
name: 'build',
description: 'Download and build a PIE-compatible PHP extension, without installing it.',
)]
final class BuildCommand extends Command
{
public function __construct(
private readonly DependencyResolver $dependencyResolver,
private readonly DownloadAndExtract $downloadAndExtract,
private readonly Build $build,
) {
parent::__construct();
}

public function configure(): void
{
parent::configure();

CommandHelper::configureOptions($this);
}

public function execute(InputInterface $input, OutputInterface $output): int
{
$targetPlatform = CommandHelper::determineTargetPlatformFromInputs($input, $output);

$requestedNameAndVersionPair = CommandHelper::requestedNameAndVersionPair($input);

$downloadedPackage = CommandHelper::downloadPackage(
$this->dependencyResolver,
$targetPlatform,
$requestedNameAndVersionPair,
$this->downloadAndExtract,
$output,
);

CommandHelper::bindConfigureOptionsFromPackage($this, $downloadedPackage->package, $input);

$configureOptionsValues = CommandHelper::processConfigureOptionsFromInput($downloadedPackage->package, $input);

($this->build)($downloadedPackage, $targetPlatform, $configureOptionsValues, $output);

return Command::SUCCESS;
}
}
Loading

0 comments on commit 2dc77ac

Please sign in to comment.