Skip to content

Commit

Permalink
Implement PR feedbacks
Browse files Browse the repository at this point in the history
  • Loading branch information
tigitz committed Feb 12, 2024
1 parent c97239c commit 1f9f557
Show file tree
Hide file tree
Showing 12 changed files with 51 additions and 59 deletions.
8 changes: 4 additions & 4 deletions .github/actions/phar/action.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,19 +18,19 @@ runs:
shell: bash
working-directory: tools/phar

- name: Build Castor PHAR Archive for Linux
- name: Build Castor phar for Linux
run: bin/castor castor:phar:linux
shell: bash

- name: Build Castor PHAR Archive for Darwin
- name: Build Castor phar for Darwin
run: bin/castor castor:phar:darwin
shell: bash

- name: Build Castor PHAR Archive for Windows
- name: Build Castor phar for Windows
run: bin/castor castor:phar:windows
shell: bash

- name: Ensure PHAR is OK
- name: Ensure phar is OK
run: build/castor.linux-amd64.phar --version
shell: bash
working-directory: tools/phar
17 changes: 7 additions & 10 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ jobs:
- php: "8.1"
castor:
bin: 'bin/castor'
method: 'vendor'
method: 'bin/castor'
- php: "8.1"
castor:
bin: 'tools/phar/build/castor.linux-amd64.phar'
Expand All @@ -53,16 +53,14 @@ jobs:
castor:
bin: 'castor'
method: 'binary'
build-options: '--php-extensions=mbstring,phar,posix,tokenizer,pcntl'
php-bin: 'none'
- php: "8.2"
castor:
bin: 'bin/castor'
method: 'vendor'
method: 'bin/castor'
- php: "8.3"
castor:
bin: 'bin/castor'
method: 'vendor'
method: 'bin/castor'

steps:
- name: Checkout
Expand All @@ -81,7 +79,7 @@ jobs:
run: composer install --prefer-dist --no-progress --optimize-autoloader --classmap-authoritative
working-directory: tools/phar

- name: Build Castor PHAR Archive for Linux
- name: Build Castor phar for Linux
run: bin/castor castor:phar:linux
shell: bash
if: matrix.castor.method == 'phar' || matrix.castor.method == 'binary'
Expand All @@ -93,8 +91,8 @@ jobs:
# /tmp/castor-php-static-compiler
# key: php-static-build-cache-${{ hashFiles('src/Console/Command/CompileCommand.php', 'tests/CompileCommandTest.php') }}

- name: Compile Custom Built PHP along Castor PHAR Archive for Linux
run: bin/castor compile tools/phar/build/castor.linux-amd64.phar ${{ matrix.castor.build-options }}
- name: Compile Custom Built PHP along Castor phar for Linux
run: bin/castor compile tools/phar/build/castor.linux-amd64.phar --php-extensions=mbstring,phar,posix,tokenizer,pcntl
shell: bash
if: matrix.castor.method == 'binary'

Expand All @@ -108,10 +106,9 @@ jobs:
run: vendor/bin/simple-phpunit
env:
CASTOR_BIN: ${{ github.workspace }}/${{ matrix.castor.bin }}
PHP_BIN: ${{ matrix.castor.php-bin }}

phar:
name: Ensure PHAR is OK
name: Ensure phar is OK
runs-on: ubuntu-latest

steps:
Expand Down
1 change: 1 addition & 0 deletions bin/generate-tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
'log:with-context',
'parallel:sleep',
'repack',
'compile',
'run:ls',
'run:run-parallel',
];
Expand Down
25 changes: 15 additions & 10 deletions doc/going-further/compile.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
# Compiling your application into a standalone binary

[Putting your Castor application into a PHAR archive](repack.md) can be a good way to easily share and use it in various environments.
[Packing your Castor application as a phar](repack.md) can be a good way to easily
share and use it in various environments.

However, you need to ensure that PHP is installed and configured correctly in all the environments where you want to use your Castor app.
However, you need to ensure that PHP is installed and configured correctly in all
the environments where you want to use your Castor app.
This can be a hassle, especially if you don't have control over the environments.

To make things simpler, Castor's `compile` command can help by creating a customizable PHP binary with a PHAR archive, making one executable file that can be used in any setting.
To make things simpler, Castor's `compile` command can help by creating a
customizable PHP binary with a phar, making one executable file that can be used in any setting.

Just pass your repacked Castor app PHAR as an argument of this command.
Just pass your repacked Castor app phar as an argument of this command.

## Pre-requisites

Follow the [`repack` documentation](repack.md) to output a PHAR archive of your Castor app.
Follow the [`repack` documentation](repack.md) to produce a phar of your
Castor app.

## Running the Compile Command

Expand All @@ -28,19 +32,20 @@ vendor/bin/castor compile my-custom-castor-app.phar

Make sure to take a look at the command description to see all the available options:
```bash
vendor/bin/castor compile -h
``````
vendor/bin/castor compile --help
```

### Behavior

The `compile` command performs several steps:

1. Downloads or uses an existing Static PHP CLI tool to compile PHP and the PHAR archive into a binary.
1. Downloads or uses an existing [Static PHP CLI tool](https://github.com/crazywhalecc/static-php-cli) to compile PHP and the phar into a binary.
2. If required, it automatically installs dependencies and compiles PHP with the specified extensions.
3. Combines the compiled PHP and your PHAR file into a single executable.
3. Combines the compiled PHP and your phar file into a single executable.

## Post-Compilation

Once the compilation is finished, your Castor application is transformed into a standalone binary named `compiled-castor` by default (you can use the `--output=` option to change it).
Once the compilation is finished, your Castor application is transformed into a standalone binary named `castor` by default (you can use the `--output` option to change it).

This binary is now ready to be distributed and run in environments that do not have PHP installed.

Expand Down
4 changes: 2 additions & 2 deletions doc/going-further/repack.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ vendor/bin/castor repack --help
## Going further

Packaging your Castor app as a PHAR archive simplifies distribution but requires PHP setup on target systems.
Packaging your Castor app as a phar simplifies distribution but requires PHP setup on target systems.

[Castor's `compile` command](compile.md) streamlines this by embedding the PHAR in a PHP binary, creating a standalone executable for diverse environments
[Castor's `compile` command](compile.md) streamlines this by embedding the phar in a PHP binary, creating a standalone executable for diverse environments.
2 changes: 1 addition & 1 deletion examples/failure.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#[AsTask(description: 'A failing task not authorized to fail')]
function failure(): void
{
run('i_do_not_exist', path: '/tmp');
run('i_do_not_exist', path: '/tmp', pty: false);
}

#[AsTask(description: 'A failing task authorized to fail')]
Expand Down
38 changes: 17 additions & 21 deletions src/Console/Command/CompileCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
use Castor\PathHelper;
use Castor\PlatformUtil;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Helper\ProgressBar;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
Expand All @@ -31,11 +30,11 @@ protected function configure(): void
{
$this
->setName('compile')
->addArgument('phar-path', InputArgument::REQUIRED, 'Path to PHAR archived compiled along PHP')
->addArgument('phar-path', InputArgument::REQUIRED, 'Path to phar to compile along PHP')
->addOption('output', null, InputOption::VALUE_REQUIRED, 'Compiled standalone binary output filepath', PathHelper::getRoot() . '/castor')
->addOption('os', null, InputOption::VALUE_REQUIRED, 'Target OS for PHP compilation', 'linux', ['linux', 'macos'])
->addOption('arch', null, InputOption::VALUE_REQUIRED, 'Target architecture for PHP compilation', 'x86_64', ['x86_64', 'aarch64'])
->addOption('php-version', null, InputOption::VALUE_REQUIRED, 'PHP version in major.minor format', '8.2')
->addOption('php-version', null, InputOption::VALUE_REQUIRED, 'PHP version in major.minor format', '8.3')
->addOption('php-extensions', null, InputOption::VALUE_REQUIRED, 'PHP extensions required, in a comma-separated format. Defaults are the minimum required to run a basic "Hello World" task in Castor.', 'mbstring,phar,posix,tokenizer')
->addOption('php-rebuild', null, InputOption::VALUE_NONE, 'Ignore cache and force PHP build compilation.')
->setHidden(true)
Expand All @@ -55,7 +54,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}

$io = new SymfonyStyle($input, $output);
$io->section('Compiling PHP and your Castor app PHAR archive into a standalone binary');
$io->section('Compiling PHP and your Castor app phar into a standalone binary');

$spcBinaryPath = PlatformUtil::getCacheDirectory() . '/castor-php-static-compiler/spc';
$spcBinaryDir = \dirname($spcBinaryPath);
Expand Down Expand Up @@ -102,16 +101,16 @@ protected function execute(InputInterface $input, OutputInterface $output): int
return Command::SUCCESS;
}

private function downloadSPC(string $spcSourceUrl, string $spcBinaryDestination, OutputInterface $output): void
private function downloadSPC(string $spcSourceUrl, string $spcBinaryDestination, SymfonyStyle $io): void
{
$response = $this->httpClient->request('GET', $spcSourceUrl);
$contentLength = $response->getHeaders()['content-length'][0] ?? 0;

$outputStream = fopen($spcBinaryDestination, 'w');
$progressBar = new ProgressBar($output, (int) $contentLength);
$progressBar = $io->createProgressBar((int) $contentLength);

if (false === $outputStream) {
throw new \RuntimeException(sprintf('Failed to open file "%s" for writing', $spcBinaryDestination));
throw new \RuntimeException(sprintf('Failed to open file "%s" for writing.', $spcBinaryDestination));
}

foreach ($this->httpClient->stream($response) as $chunk) {
Expand All @@ -128,15 +127,12 @@ private function downloadSPC(string $spcSourceUrl, string $spcBinaryDestination,
private function installPHPBuildTools(string $spcBinaryPath, string $spcBinaryDir, SymfonyStyle $io): void
{
$installSPCDepsProcess = new Process(
command: [
$spcBinaryPath, 'doctor',
'--auto-fix',
],
command: [$spcBinaryPath, 'doctor', '--auto-fix'],
cwd: $spcBinaryDir,
timeout: 5 * 60
timeout: null,
);
$io->text('Running command: ' . $installSPCDepsProcess->getCommandLine());
$installSPCDepsProcess->mustRun(fn ($type, $buffer) => print ($buffer));
$installSPCDepsProcess->mustRun(fn ($type, $buffer) => print $buffer);
}

private function downloadPHPSourceDeps(string $spcBinaryPath, mixed $phpExtensions, mixed $phpVersion, string $spcBinaryDir, SymfonyStyle $io): void
Expand All @@ -148,10 +144,10 @@ private function downloadPHPSourceDeps(string $spcBinaryPath, mixed $phpExtensio
'--with-php=' . $phpVersion,
],
cwd: $spcBinaryDir,
timeout: 5 * 60
timeout: null,
);
$io->text('Running command: ' . $downloadProcess->getCommandLine());
$downloadProcess->mustRun(fn ($type, $buffer) => print ($buffer));
$downloadProcess->mustRun(fn ($type, $buffer) => print $buffer);
}

private function buildPHP(string $spcBinaryPath, mixed $phpExtensions, mixed $arch, string $spcBinaryDir, SymfonyStyle $io): void
Expand All @@ -161,13 +157,12 @@ private function buildPHP(string $spcBinaryPath, mixed $phpExtensions, mixed $ar
$spcBinaryPath, 'build', $phpExtensions,
'--build-micro',
'--arch=' . $arch,
'-r',
],
cwd: $spcBinaryDir,
timeout: 60 * 60
timeout: null,
);
$io->text('Running command: ' . $buildProcess->getCommandLine());
$buildProcess->mustRun(fn ($type, $buffer) => print ($buffer));
$buildProcess->mustRun(fn ($type, $buffer) => print $buffer);
}

private function mergePHPandPHARIntoSingleExecutable(string $spcBinaryPath, string $pharFilePath, string $appBinaryFilePath, string $spcBinaryDir, SymfonyStyle $io): void
Expand All @@ -182,11 +177,12 @@ private function mergePHPandPHARIntoSingleExecutable(string $spcBinaryPath, stri
'micro:combine', $pharFilePath,
'--output=' . $appBinaryFilePath,
],
cwd: $spcBinaryDir
cwd: $spcBinaryDir,
timeout: null,
);

$io->text('Running command: ' . $mergePHPandPHARProcess->getCommandLine());
$mergePHPandPHARProcess->mustRun(fn ($type, $buffer) => print ($buffer));
$mergePHPandPHARProcess->mustRun(fn ($type, $buffer) => print $buffer);
}

private function setupSPC(string $spcBinaryDir, string $spcBinaryPath, SymfonyStyle $io, mixed $os, mixed $arch, OutputInterface $output): void
Expand All @@ -198,7 +194,7 @@ private function setupSPC(string $spcBinaryDir, string $spcBinaryPath, SymfonySt
} else {
$spcSourceUrl = sprintf('https://dl.static-php.dev/static-php-cli/spc-bin/nightly/spc-%s-%s', $os, $arch);
$io->text(sprintf('Downloading the static-php-cli (spc) tool from "%s" to "%s"', $spcSourceUrl, $spcBinaryPath));
$this->downloadSPC($spcSourceUrl, $spcBinaryPath, $output);
$this->downloadSPC($spcSourceUrl, $spcBinaryPath, $io);
$io->newLine(2);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Console/Command/RepackCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class RepackedApplication extends Application
$process = new Process([$box, 'compile', '--config=.box.json']);

try {
$process->mustRun(fn ($type, $buffer) => print ($buffer));
$process->mustRun(fn ($type, $buffer) => print $buffer);
} finally {
unlink('.box.json');
unlink('.main.php');
Expand Down
1 change: 1 addition & 0 deletions tests/Examples/Generated/FailureFailureTest.php.err.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
sh: 1: i_do_not_exist: not found

In failure.php line 12:

Expand Down
1 change: 0 additions & 1 deletion tests/Examples/Generated/FailureFailureTest.php.output.txt
Original file line number Diff line number Diff line change
@@ -1 +0,0 @@
sh: 1: i_do_not_exist: not found
9 changes: 1 addition & 8 deletions tests/TaskTestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ public function runTask(array $args, ?string $cwd = null): Process
$coverage = $this->getTestResultObject()?->getCodeCoverage();

$castorBin = $_SERVER['CASTOR_BIN'] ?? __DIR__ . '/../bin/castor';
$phpBin = !isset($_SERVER['PHP_BIN']) || '' === $_SERVER['PHP_BIN'] ? \PHP_BINARY : $_SERVER['PHP_BIN'];

$extraEnv = [
'ENDPOINT' => $_SERVER['ENDPOINT'],
Expand All @@ -34,14 +33,8 @@ public function runTask(array $args, ?string $cwd = null): Process
];
}

$commandLine = [$castorBin, '--no-ansi', ...$args];

if ('none' !== $phpBin) {
array_unshift($commandLine, $phpBin);
}

$process = new Process(
$commandLine,
[$castorBin, '--no-ansi', ...$args],
cwd: $cwd ?? __DIR__ . '/..',
env: [
'COLUMNS' => 120,
Expand Down
2 changes: 1 addition & 1 deletion tools/php-cs-fixer/composer.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"require": {
"friendsofphp/php-cs-fixer": "3.48.*"
"friendsofphp/php-cs-fixer": "^3.46"
}
}

0 comments on commit 1f9f557

Please sign in to comment.