Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
21 changes: 21 additions & 0 deletions .docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
FROM php:8.4-cli

ARG UID=1000
ARG GID=1000

RUN apt-get update && \
apt-get install -y git default-jre-headless

WORKDIR /var/www

ADD https://api.github.com/repos/php/phd/git/refs/heads/master version-phd.json
ADD https://api.github.com/repos/php/docbook-cs/git/refs/heads/main version-docbook-cs.json

RUN echo 'memory_limit = 512M' >> /usr/local/etc/php/conf.d/local.ini

RUN chown $UID:$GID /var/www

USER $UID:$GID

RUN git clone --depth 1 https://github.com/php/phd.git && \
git clone --depth 1 https://github.com/php/docbook-cs.git
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Files generated by the configure script
.manual.xml
.manual.*.xml
.revcheck.json
version.xml
sources.xml
Expand All @@ -9,3 +10,6 @@ fileModHistory.php

# A plece for all temporary or generated files (idempotent build)
temp/

# Docker dev build stamp
.docker/built
44 changes: 44 additions & 0 deletions docbookcs.dev.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Fallback docbook-cs configuration for translations that do not ship their
own docbookcs.xml. @LANG@ is replaced with the target language.
-->
<docbookcs xmlns="https://php.github.io/docbook-cs/config"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://php.github.io/docbook-cs/config
https://php.github.io/docbook-cs/config.xsd">

<project>
<directory alias="doc-@LANG@">@LANG@</directory>
<directory>doc-base</directory>
</project>

<sniffs>
<sniff class="DocbookCS\Sniff\SimparaSniff" />
<sniff class="DocbookCS\Sniff\ExceptionNameSniff" />
<sniff class="DocbookCS\Sniff\AttributeOrderSniff" />
<sniff class="DocbookCS\Sniff\MixedIndentationSniff" />
<sniff class="DocbookCS\Sniff\TrailingWhitespaceSniff" />
</sniffs>

<paths>
<path>.</path>
</paths>

<entities>
<file>extensions.ent</file>
<file>language-defs.ent</file>
<file>language-snippets.ent</file>
<directory>entities/</directory>
<directory>../doc-base/entities/</directory>
<file>../doc-base/temp/manual.ent</file>
<file>../doc-base/temp/entities.ent</file>
<file>../doc-base/temp/file-entities.ent</file>
<directory>../doc-base/temp/file-entities</directory>
</entities>

<exclude>
<pattern>output/*</pattern>
</exclude>

</docbookcs>
2 changes: 1 addition & 1 deletion docs/local-setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,4 @@ revert the changes with commands below and open an issue on
git config --unset core.autocrlf
git reset
git status
```
```
17 changes: 17 additions & 0 deletions phpdoc.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#!/usr/bin/env php
<?php

/**
* Dev build tool for the PHP manual, usable for every language
* Run "php phpdoc.php help" for usage
*/

declare(strict_types=1);

spl_autoload_register(static function (string $class): void {
if (str_starts_with($class, 'PhpDoc\\Dev\\')) {
require __DIR__ . '/scripts/dev/' . str_replace('\\', '/', substr($class, 11)) . '.php';
}
});

exit((new PhpDoc\Dev\Application(__DIR__))->run(array_slice($argv, 1)));
173 changes: 173 additions & 0 deletions scripts/dev/Application.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<?php

declare(strict_types=1);

namespace PhpDoc\Dev;

use PhpDoc\Dev\Command\BuildCommand;
use PhpDoc\Dev\Command\ConfigureCommand;
use PhpDoc\Dev\Command\HelpCommand;
use PhpDoc\Dev\Command\LintCommand;
use PhpDoc\Dev\Command\PullCommand;
use PhpDoc\Dev\Command\RenderCommand;
use PhpDoc\Dev\Command\ServeCommand;
use PhpDoc\Dev\Command\ShellCommand;
use PhpDoc\Dev\Command\WebDocServeCommand;
use PhpDoc\Dev\Environment\DockerEnvironment;
use PhpDoc\Dev\Environment\LocalEnvironment;

final class Application
{
public function __construct(private readonly string $basedir)
{
}

/**
* @param list<string> $args Command line arguments, without argv[0].
*/
public function run(array $args): int
{
$options = new Options();
$command = $this->parse($args, $options);

if ($command === null) {
return 1;
}

if ($command === 'help') {
return (new HelpCommand())->execute($options);
}

$subcommand = null;

if ($command === 'docker') {
$subcommand = array_shift($options->args);

if (!in_array($subcommand, ['build', 'shell'], true)) {
fwrite(STDERR, "Usage: php phpdoc.php docker <build|shell> (see: php phpdoc.php help)\n");
return 1;
}

$options->docker = true;
}

if ($command === 'render') {
$subcommand = array_shift($options->args);

if (!in_array($subcommand, ['xhtml', 'php'], true)) {
fwrite(STDERR, "Usage: php phpdoc.php render <xhtml|php> (see: php phpdoc.php help)\n");
return 1;
}

$options->format = $subcommand;
}

// "serve" takes an optional subject: plain serve shows the rendered
// manual, "serve web-doc" runs the doc.php.net site.
if ($command === 'serve' && ($options->args[0] ?? null) === 'web-doc') {
array_shift($options->args);
$subcommand = 'web-doc';
}

if ($command === 'cs') {
$subcommand = array_shift($options->args);

if (!in_array($subcommand, ['lint', 'fix'], true)) {
fwrite(STDERR, "Usage: php phpdoc.php cs <lint|fix> (see: php phpdoc.php help)\n");
return 1;
}
}

$runner = new ProcessRunner();
$dockerAvailable = $runner->runQuiet(['docker', 'version', '--format', '{{.Server.Version}}']) === 0;

if ($options->docker === true && !$dockerAvailable) {
fwrite(STDERR, "error: Docker requested but the docker command is not available.\n");
return 1;
}

$workspace = new Workspace($this->basedir, $runner, $options->assumeYes);
$environment = ($options->docker ?? $dockerAvailable)
? new DockerEnvironment($workspace, $runner)
: new LocalEnvironment($workspace, $runner);

$configure = new ConfigureCommand($workspace, $environment);

switch ($command) {
case 'pull':
return (new PullCommand($workspace, $environment))->execute($options);
case 'configure':
return $configure->execute($options);
case 'render':
return (new RenderCommand($workspace, $environment, $configure))->execute($options);
case 'cs':
return (new LintCommand($workspace, $environment, $configure, fix: $subcommand === 'fix'))
->execute($options);
case 'serve':
return $subcommand === 'web-doc'
? (new WebDocServeCommand($workspace, $environment))->execute($options)
: (new ServeCommand($workspace, $environment))->execute($options);
case 'docker':
return $subcommand === 'build'
? (new BuildCommand($environment))->execute($options)
: (new ShellCommand($environment))->execute($options);
}

fwrite(STDERR, "Unknown command: $command (see: php phpdoc.php help)\n");

return 1;
}

/** @param list<string> $args */
private function parse(array $args, Options $options): ?string
{
$command = null;

foreach ($args as $arg) {
if (preg_match('/^--lang=(.+)$/', $arg, $m)) {
$options->lang = $m[1];
continue;
}

if (preg_match('/^--port=(\d+)$/', $arg, $m)) {
$options->port = (int) $m[1];
continue;
}

if ($arg === '--docker') {
$options->docker = true;
continue;
}

if ($arg === '--no-docker') {
$options->docker = false;
continue;
}

if ($arg === '--yes' || $arg === '-y') {
$options->assumeYes = true;
continue;
}

if ($command === null) {
if ($arg[0] !== '-') {
$command = $arg;
continue;
}

if ($arg === '-h' || $arg === '--help') {
$command = 'help';
continue;
}

$fileName = $_SERVER['SCRIPT_FILENAME'];
fwrite(STDERR, "Unknown option: $arg (see: php $fileName help)\n");
return null;
}

$options->args[] = $arg;
}

return $command ?? 'help';
}
}
20 changes: 20 additions & 0 deletions scripts/dev/Command/BuildCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace PhpDoc\Dev\Command;

use PhpDoc\Dev\Environment\Environment;
use PhpDoc\Dev\Options;

final class BuildCommand implements Command
{
public function __construct(private readonly Environment $environment)
{
}

public function execute(Options $options): int
{
return $this->environment->buildImage();
}
}
12 changes: 12 additions & 0 deletions scripts/dev/Command/Command.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<?php

declare(strict_types=1);

namespace PhpDoc\Dev\Command;

use PhpDoc\Dev\Options;

interface Command
{
public function execute(Options $options): int;
}
38 changes: 38 additions & 0 deletions scripts/dev/Command/ConfigureCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php

declare(strict_types=1);

namespace PhpDoc\Dev\Command;

use PhpDoc\Dev\Environment\Environment;
use PhpDoc\Dev\Options;
use PhpDoc\Dev\Workspace;

final class ConfigureCommand implements Command
{
public function __construct(
private readonly Workspace $workspace,
private readonly Environment $environment,
) {
}

public function execute(Options $options): int
{
$lang = $options->lang;

if (!$this->workspace->ensureLangRepos($lang, $this->environment->canMapDirectoryNames())) {
return 1;
}

$this->workspace->pullSideRepos($lang);

$args = array_merge([
($this->workspace->isBaseLang($lang) ? '--with-base-lang=' : '--with-lang=') . $lang,
'--enable-xml-details',
'--disable-libxml-check',
'--redirect-stderr-to-stdout',
], $options->args);

return $this->environment->configure($lang, $args);
}
}
Loading