Page Menu
Home
DevCentral
Search
Configure Global Search
Log In
Files
F12359761
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
17 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/composer.json b/composer.json
index d7263af..57d349e 100644
--- a/composer.json
+++ b/composer.json
@@ -1,72 +1,75 @@
{
"name": "keruald/keruald",
"type": "library",
"description": "Modular libraries to build frameworks and applications",
"keywords": [
"framework",
"keruald"
],
"license": "BSD-2-Clause",
"homepage": "https://keruald.nasqueron.org",
"authors": [
{
"name": "Sébastien Santoro",
"email": "dereckson@espace-win.org"
},
{
"name": "Keruald contributors"
}
],
"provide": {
"psr/simple-cache-implementation": "1.0|2.0|3.0"
},
"require": {
"psr/simple-cache": "^1.0|^2.0|^3.0",
"ext-intl": "*"
},
"require-dev": {
"ext-mbstring": "*",
"ext-mysqli": "*",
"ext-pdo": "*",
"ext-xmlwriter": "*",
"nasqueron/codestyle": "^0.1.2",
"phan/phan": "^5.3.1",
"phpunit/phpunit": "^10.2",
"symfony/yaml": "^6.0.3",
"squizlabs/php_codesniffer": "^4.0.0"
},
"suggest": {
"ext-memcached": "*",
"ext-redis": "*"
},
"replace": {
"keruald/cache": "0.1.0",
"keruald/commands": "0.0.1",
"keruald/database": "0.6.0",
"keruald/github": "0.2.1",
"keruald/omnitools": "0.16.0",
- "keruald/report": "0.1.0"
+ "keruald/report": "0.1.0",
+ "keruald/yaml": "0.1.0"
},
"autoload": {
"psr-4": {
"Keruald\\Cache\\": "cache/src/",
"Keruald\\Cache\\Tests\\": "cache/tests/",
"Keruald\\Commands\\": "commands/src/",
"Keruald\\Commands\\Tests\\": "commands/tests/",
"Keruald\\Database\\": "database/src/",
"Keruald\\Database\\Tests\\": "database/tests/",
"Keruald\\GitHub\\": "github/src/",
"Keruald\\GitHub\\Tests\\": "github/tests/",
"Keruald\\OmniTools\\": "omnitools/src/",
"Keruald\\OmniTools\\Tests\\": "omnitools/tests/",
"Keruald\\Reporting\\": "report/src/",
- "Keruald\\Reporting\\Tests\\": "report/tests/"
+ "Keruald\\Reporting\\Tests\\": "report/tests/",
+ "Keruald\\Yaml\\": "yaml/src/",
+ "Keruald\\Yaml\\Tests\\": "yaml/tests/"
}
},
"scripts": {
"lint-src": "find */src -type f -name '*.php' | xargs -n1 php -l",
"lint-tests": "find */tests -type f -name '*.php' | xargs -n1 php -l",
"test": "vendor/bin/phpunit"
},
"minimum-stability": "dev"
}
diff --git a/metadata.yml b/metadata.yml
index 96602b1..e8eff33 100644
--- a/metadata.yml
+++ b/metadata.yml
@@ -1,38 +1,40 @@
# -------------------------------------------------------------
# Metadata for Keruald packages
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Project: Keruald
# Description: Configuration for utilities
# License: Trivial work, not eligible to copyright.
#
# If eligible, this data is made available under
# the Public Domain Dedication and License v1.0
# whose full text can be found at:
# http://opendatacommons.org/licenses/pddl/1.0/
# -------------------------------------------------------------
# -------------------------------------------------------------
# Packages
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Each package matches the following artifacts:
#
# — a subdirectory here
# — a main repository on DevCentral
# — a mirror repository on GitHub in keruald/ organization
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
packages:
- cache
- commands
- database
- github
- omnitools
- report
+ - yaml
packages_namespaces:
cache: Keruald\Cache
commands: Keruald\Commands
database: Keruald\Database
github: Keruald\GitHub
omnitools: Keruald\OmniTools
report: Keruald\Reporting
+ yaml: Keruald\Yaml
diff --git a/phpcs.xml b/phpcs.xml
index d89230c..6b8f384 100644
--- a/phpcs.xml
+++ b/phpcs.xml
@@ -1,58 +1,61 @@
<?xml version="1.0"?>
<!--
=============================================================
PHP_CodeSniffer configuration
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Project: Keruald
License: Trivial work, not eligible to copyright
Source file: _templates/phpcs.xml.in
=============================================================
<auto-generated>
This file is automatically generated from a template.
Changes to this file may cause incorrect behavior
and will be lost if the state is redeployed.
</auto-generated>
-->
<ruleset name="Nasqueron">
<rule ref="vendor/nasqueron/codestyle/CodeSniffer/ruleset.xml" />
<!--
OmniTools exception
Allow dprint_r() and dieprint_r() legacy debug function names
-->
<rule ref="Generic.NamingConventions.CamelCapsFunctionName.NotCamelCaps">
<exclude-pattern>*/_register_to_global_space.php</exclude-pattern>
</rule>
<!--
Database exception
Allow unused parameters
-->
<rule ref="Generic.CodeAnalysis.UnusedFunctionParameter">
<exclude-pattern>database/src/*</exclude-pattern>
</rule>
<file>cache/src</file>
<file>cache/tests</file>
<file>commands/src</file>
<file>commands/tests</file>
<file>database/src</file>
<file>database/tests</file>
<file>github/src</file>
<file>github/tests</file>
<file>omnitools/src</file>
<file>omnitools/tests</file>
<file>report/src</file>
<file>report/tests</file>
+ <file>yaml/src</file>
+ <file>yaml/tests</file>
+
</ruleset>
diff --git a/phpunit.xml b/phpunit.xml
index e545b4e..5fc519b 100644
--- a/phpunit.xml
+++ b/phpunit.xml
@@ -1,65 +1,69 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
=============================================================
PHPUnit configuration
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Project: Keruald
License: Trivial work, not eligible to copyright
Source file: _templates/phpunit.xml.in
=============================================================
<auto-generated>
This file is automatically generated from a template.
Changes to this file may cause incorrect behavior
and will be lost if the state is redeployed.
</auto-generated>
-->
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.3/phpunit.xsd"
displayDetailsOnTestsThatTriggerDeprecations="true"
displayDetailsOnTestsThatTriggerErrors="true"
displayDetailsOnTestsThatTriggerWarnings="true"
displayDetailsOnTestsThatTriggerNotices="true"
bootstrap="vendor/autoload.php"
cacheDirectory=".phpunit.cache"
stopOnFailure="false">
<php>
<ini name="display_errors" value="On" />
<ini name="display_startup_errors" value="On" />
<ini name="error_reporting" value="On" />
</php>
<testsuites>
<testsuite name="Unit tests for keruald/cache">
<directory suffix="Test.php">./cache/tests</directory>
</testsuite>
<testsuite name="Unit tests for keruald/commands">
<directory suffix="Test.php">./commands/tests</directory>
</testsuite>
<testsuite name="Unit tests for keruald/database">
<directory suffix="Test.php">./database/tests</directory>
</testsuite>
<testsuite name="Unit tests for keruald/github">
<directory suffix="Test.php">./github/tests</directory>
</testsuite>
<testsuite name="Unit tests for keruald/omnitools">
<directory suffix="Test.php">./omnitools/tests</directory>
</testsuite>
<testsuite name="Unit tests for keruald/report">
<directory suffix="Test.php">./report/tests</directory>
</testsuite>
+ <testsuite name="Unit tests for keruald/yaml">
+ <directory suffix="Test.php">./yaml/tests</directory>
+ </testsuite>
</testsuites>
<source>
<include>
<directory suffix=".php">cache/src/</directory>
<directory suffix=".php">commands/src/</directory>
<directory suffix=".php">database/src/</directory>
<directory suffix=".php">github/src/</directory>
<directory suffix=".php">omnitools/src/</directory>
<directory suffix=".php">report/src/</directory>
+ <directory suffix=".php">yaml/src/</directory>
</include>
</source>
</phpunit>
diff --git a/yaml/composer.json b/yaml/composer.json
new file mode 100644
index 0000000..61bb0f2
--- /dev/null
+++ b/yaml/composer.json
@@ -0,0 +1,41 @@
+{
+ "name": "keruald/yaml",
+ "description": "YAML parser",
+ "license": "BSD-2-Clause",
+ "repositories": [
+ {
+ "type": "vcs",
+ "url": "https://github.com/keruald/yaml"
+ }
+ ],
+ "authors": [
+ {
+ "name": "Sébastien Santoro",
+ "email": "dereckson@espace-win.org"
+ }
+ ],
+ "keywords": [
+ "keruald",
+ "YAML"
+ ],
+ "support": {
+ "irc": "irc://irc.libera.chat/nasqueron",
+ "issues": "https://devcentral.nasqueron.org"
+ },
+ "require": {
+ "keruald/omnitools": "^0.16.0",
+ "php": ">=8.3.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "12.*"
+ },
+ "autoload": {
+ "psr-4": {
+ "Keruald\\Yaml\\": "src/",
+ "Keruald\\Yaml\\Tests\\": "tests/"
+ }
+ },
+ "scripts": {
+ "test": "phpunit tests"
+ }
+}
diff --git a/yaml/src/Parser.php b/yaml/src/Parser.php
new file mode 100644
index 0000000..c3ccb65
--- /dev/null
+++ b/yaml/src/Parser.php
@@ -0,0 +1,86 @@
+<?php
+
+namespace Keruald\Yaml;
+
+use Symfony\Component\Yaml\Tag\TaggedValue;
+use Symfony\Component\Yaml\Yaml;
+
+use Keruald\Yaml\Tags\Tag;
+
+use InvalidArgumentException;
+
+class Parser {
+
+ /**
+ * @var array<string, Tag>
+ */
+ private array $tags = [];
+
+ ///
+ /// Configure
+ ///
+
+ public function withTagClass (string $type) : self {
+ $tag = new $type();
+
+ return $this->withTag($tag);
+ }
+
+ public function withTag (Tag $tag) : self {
+ $tag->register($this->tags);
+
+ return $this;
+ }
+
+ ///
+ /// Parse
+ ///
+
+ /**
+ * @throws InvalidArgumentException if a tag is not defined at parser level
+ */
+ public function parse (string $expression) : mixed {
+ $flags = Yaml::PARSE_CUSTOM_TAGS;
+ $parsed = Yaml::parse($expression, $flags);
+
+ return $this->resolve($parsed);
+ }
+
+ /**
+ * @throws InvalidArgumentException if the file is not found
+ * @throws InvalidArgumentException if a tag is not defined at parser level
+ */
+ public function parseFile (string $filename) : mixed {
+ if (!file_exists($filename)) {
+ throw new InvalidArgumentException("File not found: $filename");
+ }
+
+ $flags = Yaml::PARSE_CUSTOM_TAGS;
+ $parsed = Yaml::parseFile($filename, $flags);
+
+ return $this->resolve($parsed);
+ }
+
+ private function resolve (mixed $data) {
+ if ($data instanceof TaggedValue) {
+ $tag = $data->getTag();
+
+ if (!array_key_exists($tag, $this->tags)) {
+ throw new InvalidArgumentException("Tag not found: $tag");
+ }
+
+ $tagHandler = $this->tags[$tag];
+
+ return $tagHandler->handle($data->getValue());
+ }
+
+ if (is_array($data)) {
+ foreach ($data as $key => $value) {
+ $data[$key] = $this->resolve($value);
+ }
+ }
+
+ return $data;
+ }
+
+}
diff --git a/yaml/src/Tags/EnvTag.php b/yaml/src/Tags/EnvTag.php
new file mode 100644
index 0000000..1955067
--- /dev/null
+++ b/yaml/src/Tags/EnvTag.php
@@ -0,0 +1,29 @@
+<?php
+
+namespace Keruald\Yaml\Tags;
+
+use Keruald\OmniTools\OS\Environment;
+
+/**
+ * Represents an environment variable
+ */
+class EnvTag extends Tag {
+
+ public function getPrimaryTag () : string {
+ return "tag:keruald.nasqueron.org,2025:env";
+ }
+
+ public function getPrivateTag () : string {
+ return "env";
+ }
+
+ /**
+ * @throws \InvalidArgumentException when the variable does not exist.
+ */
+ public function handle (mixed $data) : string {
+ $key = (string)$data;
+
+ return Environment::get($key);
+ }
+
+}
diff --git a/yaml/src/Tags/Tag.php b/yaml/src/Tags/Tag.php
new file mode 100644
index 0000000..99e7493
--- /dev/null
+++ b/yaml/src/Tags/Tag.php
@@ -0,0 +1,18 @@
+<?php
+
+namespace Keruald\Yaml\Tags;
+
+abstract class Tag {
+
+ public abstract function getPrimaryTag () : string;
+
+ public abstract function getPrivateTag () : string;
+
+ public abstract function handle (mixed $data) : mixed;
+
+ public function register (&$tags) : void {
+ $tags[$this->getPrimaryTag()] = $this;
+ $tags[$this->getPrivateTag()] = $this;
+ }
+
+}
diff --git a/yaml/tests/ParserTest.php b/yaml/tests/ParserTest.php
new file mode 100644
index 0000000..06f2002
--- /dev/null
+++ b/yaml/tests/ParserTest.php
@@ -0,0 +1,47 @@
+<?php
+
+namespace Keruald\Yaml\Tests;
+
+use Keruald\Yaml\Parser;
+
+use PHPUnit\Framework\TestCase;
+
+use InvalidArgumentException;
+
+class ParserTest extends TestCase {
+
+ private Parser $parser;
+
+ protected function setUp () : void {
+ $this->parser = new Parser;
+ }
+
+ public function testParse () {
+ $this->assertEquals(666, $this->parser->parse("666"));
+ $this->assertEquals("", $this->parser->parse(""));
+ }
+
+ public function testParseUnknownTag () {
+ $this->expectException(InvalidArgumentException::class);
+ $this->expectExceptionMessage("Tag not found: foo");
+
+ $this->parser->parse("!foo 4");
+ }
+
+ public function testParseFile () {
+ $expected = [
+ "example" => [
+ "foo" => "bar",
+ "skills" => [
+ "quux",
+ "baz",
+ ],
+ ],
+ ];
+
+ $actual = $this->parser->parseFile(__DIR__ . "/data/example.yaml");
+
+ $this->assertEquals($expected, $actual);
+ }
+
+}
diff --git a/yaml/tests/Tags/EnvTagTest.php b/yaml/tests/Tags/EnvTagTest.php
new file mode 100644
index 0000000..52d51d9
--- /dev/null
+++ b/yaml/tests/Tags/EnvTagTest.php
@@ -0,0 +1,63 @@
+<?php
+
+namespace Keruald\Yaml\Tests\Tags;
+
+use Keruald\Yaml\Parser;
+use Keruald\Yaml\Tags\EnvTag;
+use PHPUnit\Framework\TestCase;
+
+class EnvTagTest extends TestCase {
+
+ private EnvTag $tag;
+
+ protected function setUp () : void {
+ $this->tag = new EnvTag();
+
+ $_ENV["ORBEON_DB_HOST"] = "localhost";
+ $_ENV["ORBEON_DB_PORT"] = "5432";
+
+ $_SERVER["ORBEON_DB_NAME"] = "orbeon_db";
+ }
+
+ public function testHandle () {
+ $this->assertEquals("localhost", $this->tag->handle("ORBEON_DB_HOST"));
+ }
+
+ public function testHandleWithServerVariable () {
+ $this->assertEquals("orbeon_db", $this->tag->handle("ORBEON_DB_NAME"));
+ }
+
+ public function testHandleWithMissingVariable () {
+ $this->assertEquals("5432", $this->tag->handle("ORBEON_DB_PORT"));
+ }
+
+ ///
+ /// Integration
+ ///
+
+ public function testFullParse () {
+ $yamlContent = <<<YAML
+database:
+ host: !env ORBEON_DB_HOST
+ port: !env ORBEON_DB_PORT
+ name: !env ORBEON_DB_NAME
+ pool_size: 10
+YAML;
+
+ $expected = [
+ "database" => [
+ "host" => "localhost",
+ "port" => "5432",
+ "name" => "orbeon_db",
+ "pool_size" => 10,
+ ],
+ ];
+
+ $parser = new Parser();
+ $parser->withTagClass(EnvTag::class);
+ $actual = $parser->parse($yamlContent);
+
+ $this->assertEquals($expected, $actual);
+ }
+
+}
diff --git a/yaml/tests/Tags/TagTest.php b/yaml/tests/Tags/TagTest.php
new file mode 100644
index 0000000..7e614e4
--- /dev/null
+++ b/yaml/tests/Tags/TagTest.php
@@ -0,0 +1,36 @@
+<?php
+
+namespace Keruald\Yaml\Tests\Tags;
+
+use Keruald\Yaml\Tags\Tag;
+use PHPUnit\Framework\TestCase;
+
+class TagTest extends TestCase {
+
+ public static function provideTag () : Tag {
+ return new class () extends Tag {
+ public function getPrimaryTag () : string {
+ return "tag:example.com,2000:test";
+ }
+
+ public function getPrivateTag () : string {
+ return "test";
+ }
+
+ public function handle (mixed $data) : string {
+ return "";
+ }
+ };
+ }
+
+ public function testRegister () {
+ $handlers = [];
+
+ $tag = self::provideTag();
+ $tag->register($handlers);
+
+ $this->assertArrayHasKey("tag:example.com,2000:test", $handlers);
+ $this->assertArrayHasKey("test", $handlers);
+ }
+
+}
diff --git a/yaml/tests/data/example.yaml b/yaml/tests/data/example.yaml
new file mode 100644
index 0000000..f8d8bbb
--- /dev/null
+++ b/yaml/tests/data/example.yaml
@@ -0,0 +1,5 @@
+example:
+ foo: bar
+ skills:
+ - quux
+ - baz
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Fri, Oct 31, 02:18 (21 h, 54 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
3116761
Default Alt Text
(17 KB)
Attached To
Mode
rKERUALD Keruald libraries development repository
Attached
Detach File
Event Timeline
Log In to Comment