Skip to content

Commit

Permalink
Start to generate some code from CLDR
Browse files Browse the repository at this point in the history
  • Loading branch information
olvlvl committed Oct 7, 2023
1 parent 7eedc1b commit 5d3f416
Show file tree
Hide file tree
Showing 20 changed files with 4,608 additions and 427 deletions.
2 changes: 1 addition & 1 deletion MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ None

### Other Changes

None
- Some code is now generated from CLDR data, such as `Units` getters and methods.



Expand Down
21 changes: 21 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,24 @@ test-container-82:
.PHONY: lint
lint:
@XDEBUG_MODE=off vendor/bin/phpstan

#
# Generate
#

GENERATE=./generator/generate

.PHONY=generate
generate: \
lib/LocaleId.php \
lib/Units/SequenceCompanion.php \
lib/Units/UnitsCompanion.php

lib/LocaleId.php:
$(GENERATE) locale-id >$@

lib/Units/SequenceCompanion.php:
$(GENERATE) sequence-companion >$@

lib/Units/UnitsCompanion.php:
$(GENERATE) units-companion >$@
2 changes: 1 addition & 1 deletion docs/General.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ units. [Many units are available](https://www.unicode.org/reports/tr35/tr35-66/t
```php
<?php

/* @var $cldr \ICanBoogie\CLDR\Repository */
/* @var ICanBoogie\CLDR\Repository $cldr */

$units = $cldr->locales['en']->units;

Expand Down
5 changes: 5 additions & 0 deletions generator/.editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
[*]
indent_style = space

[*.json]
indent_size = 2
1 change: 1 addition & 0 deletions generator/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
composer.lock
28 changes: 28 additions & 0 deletions generator/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
ARG PHP_VERSION=8.1
FROM php:${PHP_VERSION}-cli-buster

RUN apt-get update && \
apt-get install -y autoconf pkg-config && \
pecl channel-update pecl.php.net && \
pecl install xdebug && \
docker-php-ext-enable opcache xdebug

RUN echo '\
xdebug.client_host=host.docker.internal\n\
xdebug.mode=develop\n\
xdebug.start_with_request=yes\n\
' >> /usr/local/etc/php/conf.d/docker-php-ext-xdebug.ini

RUN echo '\
display_errors=On\n\
error_reporting=E_ALL\n\
date.timezone=UTC\n\
' >> /usr/local/etc/php/conf.d/php.ini

ENV COMPOSER_ALLOW_SUPERUSER 1

RUN apt-get update && \
apt-get install unzip && \
curl -s https://raw.githubusercontent.com/composer/getcomposer.org/76a7060ccb93902cd7576b67264ad91c8a2700e2/web/installer | php -- --quiet && \
mv composer.phar /usr/local/bin/composer && \
echo 'export PATH="$HOME/.composer/vendor/bin:$PATH"\n' >> /root/.bashrc
31 changes: 31 additions & 0 deletions generator/composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "icanboogie/cldr-generator",
"description": "Generates CLDR classes",
"type": "project",
"license": "BSD-3-Clause",
"authors": [
{
"name": "Olivier Laviale",
"email": "olivier.laviale@gmail.com",
"homepage": "https://olvlvl.com/",
"role": "Developer"
}
],
"config": {
"sort-packages": true
},
"minimum-stability": "dev",
"prefer-stable": true,
"require": {
"php": ">=8.1",
"icanboogie/accessor": "^6.0",
"symfony/console": "^6.3",
"symfony/dependency-injection": "^6.3"
},
"autoload": {
"psr-4": {
"ICanBoogie\\CLDR\\": "../lib",
"ICanBoogie\\CLDR\\Generator\\": "src"
}
}
}
15 changes: 15 additions & 0 deletions generator/docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
version: "3.2"
services:
app81:
build:
context: .
dockerfile: Dockerfile
args:
PHP_VERSION: '8.1'
environment:
PHP_IDE_CONFIG: 'serverName=icanboogie-cldr-generator'
volumes:
- .:/app:delegated
- ~/.composer:/root/.composer:delegated
working_dir: /app
23 changes: 23 additions & 0 deletions generator/generate
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#!/usr/bin/env php
<?php

namespace ICanBoogie\CLDR\Generator;

use Symfony\Component\Console\Application;
use Symfony\Component\Console\CommandLoader\ContainerCommandLoader;

chdir(__DIR__);

require_once 'vendor/autoload.php';

const CACHE = __DIR__ . "/cache";

$container = ContainerProvider::provide_container();

/** @var ContainerCommandLoader $command_loader */

$command_loader = $container->get('console.command_loader');

$console = new Application();
$console->setCommandLoader($command_loader);
$console->run();
53 changes: 53 additions & 0 deletions generator/src/Command/LocaleIdCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?php

namespace ICanBoogie\CLDR\Generator\Command;

use ICanBoogie\CLDR\Repository;
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('locale-id', "Generates LocaleId.php")]
final class LocaleIdCommand extends Command
{
private const TEMPLATE = <<<PHP
<?php
/** DO NOT EDIT - THE FILE HAS BEEN GENERATED WITH locale-id */
namespace ICanBoogie\CLDR;
enum LocaleId: string
{
#CASES#
}
PHP;

public function __construct(
private readonly Repository $repository
) {
parent::__construct();
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$available_locales = $this->repository->available_locales;
$cases = [];

foreach ($available_locales as $locale) {
$case = strtr($locale, [ '-' => '_' ]);

$cases[] = <<<PHP
case $case = "$locale";
PHP;
}

$cases = implode("\n", $cases);

echo strtr(self::TEMPLATE, [ '#CASES#' => $cases ]);

return self::SUCCESS;
}
}
73 changes: 73 additions & 0 deletions generator/src/Command/SequenceCompanionCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
<?php

namespace ICanBoogie\CLDR\Generator\Command;

use ICanBoogie\CLDR\Repository;
use ICanBoogie\CLDR\Units\NumberWithUnit;
use ICanBoogie\CLDR\Units\Unit;
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('sequence-companion', "Generates Units/SequenceCompanion.php")]
final class SequenceCompanionCommand extends Command
{
private const TEMPLATE = <<<PHP
<?php
/** DO NOT EDIT - THE FILE HAS BEEN GENERATED WITH sequence-companion */
namespace ICanBoogie\CLDR\Units;
/**
* @internal
*/
trait SequenceCompanion
{
#METHODS#
}
PHP;

public function __construct(
private readonly Repository $repository
) {
parent::__construct();
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$units = $this->repository->locales['en-001']['units']['long'];
$methods = [];

foreach ($units as $name => $unit) {
if (empty($unit['unitPattern-count-one'])) {
continue;
}

$normalized = strtr($name, [ '-' => '_' ]);

$methods[] = <<<PHP
/**
* @param float|int|numeric-string \$number
*
* @return \$this
*/
public function $normalized(float|int|string \$number): self
{
\$this->sequence["$name"] = \$number;
return \$this;
}
PHP;
}

echo strtr(self::TEMPLATE, [
'#METHODS#' => implode("\n", $methods),
]);

return self::SUCCESS;
}
}
78 changes: 78 additions & 0 deletions generator/src/Command/UnitsCompanionCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

namespace ICanBoogie\CLDR\Generator\Command;

use ICanBoogie\CLDR\Repository;
use ICanBoogie\CLDR\Units\NumberWithUnit;
use ICanBoogie\CLDR\Units\Unit;
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('units-companion', "Generates Units/UnitsCompanion.php")]
final class UnitsCompanionCommand extends Command
{
private const TEMPLATE = <<<PHP
<?php
/** DO NOT EDIT - THE FILE HAS BEEN GENERATED WITH units-companion */
namespace ICanBoogie\CLDR\Units;
/**
* @internal
*
#PROPERTIES#
*
*/
trait UnitsCompanion
{
#METHODS#
}
PHP;

public function __construct(
private readonly Repository $repository
) {
parent::__construct();
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$units = $this->repository->locales['en-001']['units']['long'];
$properties = [];
$methods = [];

foreach ($units as $name => $unit) {
if (empty($unit['unitPattern-count-one'])) {
continue;
}

$normalized = strtr($name, [ '-' => '_' ]);

$properties[] = <<<TXT
* @property-read Unit \$$normalized
TXT;

$methods[] = <<<PHP
/**
* @param float|int|numeric-string \$number
*/
public function $normalized(float|int|string \$number): NumberWithUnit
{
return new NumberWithUnit(\$number, "$name", \$this);
}
PHP;
}

echo strtr(self::TEMPLATE, [
'#PROPERTIES#' => implode("\n", $properties),
'#METHODS#' => implode("\n", $methods),
]);

return self::SUCCESS;
}
}
Loading

0 comments on commit 5d3f416

Please sign in to comment.