Skip to content

Commit

Permalink
Add support for entry namespaces
Browse files Browse the repository at this point in the history
  • Loading branch information
Piagrammist committed Oct 3, 2024
1 parent 16dc017 commit 0865668
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 43 deletions.
33 changes: 33 additions & 0 deletions src/Ini/Entry.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
final class Entry implements JsonSerializable
{
private ?string $name;
private ?string $namespace = null;
private EntryState $state = EntryState::UNTOUCHED;

private mixed $value = null;
Expand Down Expand Up @@ -47,6 +48,37 @@ public function getName(): ?string
return $this->name;
}

public function setNamespace(string $namespace): self
{
if ($namespace === '') {
throw new \InvalidArgumentException(Lang::get('err_namespace_empty'));
}
if (!validateSnake($namespace)) {
throw new \InvalidArgumentException(Lang::get('err_namespace_snake'));
}
$this->namespace = $namespace;
return $this;
}
public function getNamespace(): ?string
{
return $this->namespace;
}

public function getFullName(): ?string
{
if ($this->namespace === null) {
return $this->name;
}
return "{$this->namespace}.{$this->name}";
}
public function getFullNameRegex(): ?string
{
if ($this->namespace === null) {
return $this->name;
}
return "{$this->namespace}\\.{$this->name}";
}

public function setValue(mixed $value, ValueFormat $format = ValueFormat::NONE): self
{
$this->value = $value;
Expand Down Expand Up @@ -130,6 +162,7 @@ public function jsonSerialize(): array
{
return [
'name' => $this->getName(),
'namespace' => $this->getNamespace(),
'value' => $this->getValue(),
'prev_value' => $this->getPrevValue(),
'state' => $this->getState(),
Expand Down
18 changes: 18 additions & 0 deletions src/Ini/EntryManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
use ReflectionProperty;
use ReflectionAttribute;

use EasyIni\Lang;
use function EasyIni\camelToSnake;

abstract class EntryManager implements JsonSerializable
{
private ?string $namespace = null;

/** Instantiates all props with the `Entry` attribute. */
public function __construct()
{
Expand All @@ -25,10 +28,25 @@ public function __construct()
if (!$entry->getName()) {
$entry->setName(camelToSnake($property->getName()));
}
if ($this->namespace) {
$entry->setNamespace($this->namespace);
}
$this->{$property->name} = $entry;
}
}

/**
* Sets the entries' prefix/namespace.
* ! Must be called before `__construct()`
*/
protected function setNamespace(string $namespace): void
{
if ($namespace === '') {
throw new \InvalidArgumentException(Lang::get('err_namespace_empty'));
}
$this->namespace = $namespace;
}

protected function setEntry(
Entry &$prop,
mixed $value = null,
Expand Down
54 changes: 28 additions & 26 deletions src/Lang.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,33 +5,35 @@
final class Lang
{
private static array $strings = [
'err_class_resolve' => "Could not resolve class '%s'!",
'err_env_mode' => "Invalid environment mode '%s'!",
'err_setup' => 'Cannot setup more than once!',
'err_key_str' => "Invalid string key provided '%s'!",
'err_argc_match' => "Arguments count don't match the %s!",
'err_options_cls' => "Invalid options class provided '%s', expected '%s'!",
'err_bytes' => '%s size must be a positive value in bytes, ' .
'err_class_resolve' => "Could not resolve class '%s'!",
'err_env_mode' => "Invalid environment mode '%s'!",
'err_setup' => 'Cannot setup more than once!',
'err_key_str' => "Invalid string key provided '%s'!",
'err_argc_match' => "Arguments count don't match the %s!",
'err_options_cls' => "Invalid options class provided '%s', expected '%s'!",
'err_bytes' => '%s size must be a positive value in bytes, ' .
"or with standard PHP data size suffixes (K, M or G) e.g. '256M'!",
'err_id_resolve' => "%s '%s' does not exist and will be ignored!",
'err_file_resolve' => "File does not exist at '%s'!",
'err_ini_resolve' => 'Could not resolve the ini path!',
'err_entry_empty' => 'Entry name cannot be empty!',
'err_entry_snake' => 'Entry name must be snake_case!',
'err_jit_flags' => 'JIT flags must be a 4 digit number or one of "%s".',
'err_win_no_ext' => 'Extension handling is only supported on Windows. Skipping...',
'debug_pattern' => "PatternPair{ '%s' => '%s' }",
'debug_entry' => "Entry{ '%s' = %s }",
'ini_read' => "Using '%s' as template.",
'ini_write' => "Writing to '%s'.",
'env_mode' => 'Env mode: %s',
'entry_add' => 'No `%s` entry found, proceeding to add.',
'jit_processed' => 'JIT processed.',
'no_x' => 'No %s provided!',
'count' => 'Got %s %s.',
'no_option' => 'No %s option provided!',
'option_count' => 'Got %s %s option(s).',
'done' => 'Done!',
'err_id_resolve' => "%s '%s' does not exist and will be ignored!",
'err_file_resolve' => "File does not exist at '%s'!",
'err_ini_resolve' => 'Could not resolve the ini path!',
'err_entry_empty' => 'Entry name cannot be empty!',
'err_entry_snake' => 'Entry name must be snake_case!',
'err_namespace_empty' => 'Entry namespace cannot be empty!',
'err_namespace_snake' => 'Entry namespace must be snake_case!',
'err_jit_flags' => 'JIT flags must be a 4 digit number or one of "%s".',
'err_win_no_ext' => 'Extension handling is only supported on Windows. Skipping...',
'debug_pattern' => "PatternPair{ '%s' => '%s' }",
'debug_entry' => "Entry{ '%s' = %s }",
'ini_read' => "Using '%s' as template.",
'ini_write' => "Writing to '%s'.",
'env_mode' => 'Env mode: %s',
'entry_add' => 'No `%s` entry found, proceeding to add.',
'jit_processed' => 'JIT processed.',
'no_x' => 'No %s provided!',
'count' => 'Got %s %s.',
'no_option' => 'No %s option provided!',
'option_count' => 'Got %s %s option(s).',
'done' => 'Done!',
];

public static function get(string $key, string ...$args): string
Expand Down
1 change: 1 addition & 0 deletions src/Options/JitOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ final class JitOptions extends EntryManager

public function __construct()
{
$this->setNamespace('opcache');
parent::__construct();

$this->flags->setValue('tracing');
Expand Down
4 changes: 2 additions & 2 deletions src/PatternPairs.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ final class PatternPairs
private array $lookups = [];
private array $replacements = [];

public function entry(string $key, Entry $entry): self
public function entry(Entry $entry): self
{
$value = $entry->getValue();
// * For the sake of extensions
Expand All @@ -18,7 +18,7 @@ public function entry(string $key, Entry $entry): self
}
foreach ($value as $v) {
$this->basicEntry(
$key,
$entry->getFullNameRegex(),
$v,
$entry->getPrevValue(),
$entry->toComment()
Expand Down
2 changes: 1 addition & 1 deletion src/Processors/AbstractProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public function apply(?EntryManager $options): void
if ($entry->untouched())
continue;

$this->patterns->entry($entry->getName(), $entry);
$this->patterns->entry($entry);
++$i;
}
Logger::debug(Lang::get('option_count', (string)$i, \strtolower(static::$name)));
Expand Down
22 changes: 10 additions & 12 deletions src/Processors/JitProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,34 +44,32 @@ public function apply($options): void
) {
$this->patterns->basicEntry('zend_extension', prevValue: 'opcache', comment: true);
}

foreach (['enable', 'enable_cli'] as $name) {
$entry = $options[$name];
if ($entry->untouched())
continue;

$this->patterns->entry("opcache\\.$name", $entry);
foreach ([$enable, $enableCli] as $entry) {
if (!$entry->untouched()) {
$this->patterns->entry($entry);
}
}

$toAdd = [];
foreach (['jit', 'jit_buffer_size'] as $name) {
/** @var \EasyIni\Ini\Entry $entry */
$entry = $options[$name];
if ($entry->untouched())
continue;

// See if flags/buffer-size entries already exist
if (\str_contains($this->ini, "opcache.$name")) {
$this->patterns->entry("opcache\\.$name", $entry);
if (\str_contains($this->ini, $entry->getFullName())) {
$this->patterns->entry($entry);
} else {
$toAdd[] = comment($entry->toComment()) .
"opcache.$name = {$entry->getValue()}";
Logger::notice(Lang::get('entry_add', "opcache.$name"));
$entry->getFullName() . ' = ' . $entry->getValue();
Logger::notice(Lang::get('entry_add', $entry->getFullName()));
}
}
if (\count($toAdd)) {
$toAdd = \implode('', prefixArray(\PHP_EOL . \PHP_EOL, $toAdd));
$this->patterns->basicEntry(
'opcache\.enable_cli',
$enableCli->getFullNameRegex(),
"\\2$toAdd",
'\d',
$enableCli->toComment()
Expand Down
2 changes: 1 addition & 1 deletion src/functions.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function validateBytes(string|int $bytes): bool

function validateSnake(string $text): bool
{
return (bool)\preg_match('/^(?<word>[a-z][a-z\d]*)(?:[_.](?&word))*$/', $text);
return (bool)\preg_match('/^(?<word>[a-z][a-z\d]*)(?:_(?&word))*$/', $text);
}

function camelToSnake(string $text): string
Expand Down
2 changes: 1 addition & 1 deletion tests/Unit/FunctionsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
['AString', false],
['a__string', false],
['_string', false],
['opcache.jit_buffer_size', true],
['opcache.jit_buffer_size', false],
]);


Expand Down

0 comments on commit 0865668

Please sign in to comment.