Task: #53687 Support instance-specific cfg write targets and add coverage V2 #4

Merged
norb merged 11 commits from 53687/task-support-instance-specific-cfg-write-target-v2 into master 2026-03-30 15:09:21 +00:00
Member

cfg behavior (functional summary)

cfg separates two concepts:
--pkgPath (-p): where extension/package default files are read from (<prefix>.default.conf.php).
--appPath (-a): where local/override configuration is written (config/...).

So -p does not define the write target; it defines the defaults source.

  1. Global configuration (existing)
cfg -p public/extensions/myCEESV/ write myCEESV 'auth:projectId="218523..."'
  • Reads defaults from: public/extensions/myCEESV/config/myCEESV.default.conf.php
  • Writes to global local config: ./config/myCEESV.conf.php (if -a is not provided, cwd is used)
  1. Global configuration in an instance subdirectory (new)
cfg -p public/extensions/myCEESV/ write myCEESV 'auth:projectId="218523..."' --siteDir=owner_xyz
  • Reads defaults from: public/extensions/myCEESV/config/myCEESV.default.conf.php
  • Writes to: ./config/owner_xyz/myCEESV.conf.php
  • --siteDir accepts both owner_xyz and config/owner_xyz (both normalize to the same target)
  1. Configuration inside the extension tree (existing)
cfg -p public/extensions/myCEESV/ -a public/extensions/myCEESV/ write myCEESV 'auth:projectId="218523226823721217"'
  • Reads defaults from: public/extensions/myCEESV/config/myCEESV.default.conf.php
  • Writes to: public/extensions/myCEESV/config/myCEESV.conf.php

Technical note
A bug was fixed in Settings::load() so cfg no longer fails when the extension default config does not define mode; it now applies an automatic fallback and does not require -m.

Please test cfg with instance-specific targets:

From an instance root (cd <path2instance>), run:

cfg -p public/extensions/myCEESV/ write myCEESV 'auth:projectId="218523..."' --siteDir=owner_xyz
cfg -p public/extensions/myCEESV/ write myCEESV 'auth:clientId="service-xxxx-qual@myceesv.ch"' --siteDir=owner_xyz
cfg -p public/extensions/myCEESV/ show myCEESV --siteDir=owner_xyz

Expected:

  • Writes go to config/owner_xyz/myCEESV.conf.php (directory created if missing)
  • Local file config/myCEESV.conf.php is untouched when --siteDir is used
  • Repeated writes merge values and create .bak when overwriting existing instance config
  • Without --siteDir, behavior stays unchanged (writes to local config)
### cfg behavior (functional summary) cfg separates two concepts: • `--pkgPath` (`-p`): where extension/package default files are read from (`<prefix>.default.conf.php`). • `--appPath `(`-a`): where local/override configuration is written (`config/...`). So `-p` does not define the write target; it defines the defaults source. 1) Global configuration (existing) ```shell cfg -p public/extensions/myCEESV/ write myCEESV 'auth:projectId="218523..."' ``` - Reads defaults from: `public/extensions/myCEESV/config/myCEESV.default.conf.php` - Writes to global local config: .`/config/myCEESV.conf.php` (if -a is not provided, cwd is used) 2) Global configuration in an instance subdirectory (new) ```shell cfg -p public/extensions/myCEESV/ write myCEESV 'auth:projectId="218523..."' --siteDir=owner_xyz ``` - Reads defaults from: public/extensions/myCEESV/config/myCEESV.default.conf.php - Writes to: `./config/owner_xyz/myCEESV.conf.php` - `--siteDir` accepts both owner_xyz and config/owner_xyz (both normalize to the same target) 3) Configuration inside the extension tree (existing) ```shell cfg -p public/extensions/myCEESV/ -a public/extensions/myCEESV/ write myCEESV 'auth:projectId="218523226823721217"' ``` - Reads defaults from: `public/extensions/myCEESV/config/myCEESV.default.conf.php` - Writes to: `public/extensions/myCEESV/config/myCEESV.conf.php` **Technical note** A bug was fixed in Settings::load() so cfg no longer fails when the extension default config does not define mode; it now applies an automatic fallback and does not require -m. ### Please test cfg with instance-specific targets: From an instance root (`cd <path2instance>`), run: ``` cfg -p public/extensions/myCEESV/ write myCEESV 'auth:projectId="218523..."' --siteDir=owner_xyz cfg -p public/extensions/myCEESV/ write myCEESV 'auth:clientId="service-xxxx-qual@myceesv.ch"' --siteDir=owner_xyz cfg -p public/extensions/myCEESV/ show myCEESV --siteDir=owner_xyz ``` **Expected:** - Writes go to `config/owner_xyz/myCEESV.conf.php` (directory created if missing) - Local file `config/myCEESV.conf.php` is untouched when `--siteDir` is used - Repeated writes merge values and create `.bak` when overwriting existing instance config - Without `--siteDir`, behavior stays unchanged (writes to local config)
alejandro.sosa changed title from 53687/task-support-instance-specific-cfg-write-target-v2 to Task: #53687 Support instance-specific cfg write targets and add coverage V2 2026-03-26 09:17:57 +00:00
- Changed site targeting from --site, --directory-name, --directoryName to --siteDir
- Added write -i <json> for multi-setting input
- Added support for inline JSON string values in write
- Updated help/examples to generic placeholders
- Extended tests for new arguments and validations (all passing)
norb requested changes 2026-03-26 10:29:41 +00:00
Dismissed
bin/cfg Outdated
@ -238,27 +369,37 @@ case 'show':
case 'write':
$path = ($settings['key'] !== '') ? explode(':', $settings['key']) : [];
var_dump($path);
Owner

perhaps we could have a verbose mode?

perhaps we could have a verbose mode?
Author
Member

@norb wrote in #4 (comment):

perhaps we could have a verbose mode?

Hi Norber, for this round I kept the verbose implementation minimal on purpose. The current CLI helper library is not fully compatible with PHP 8 in the verbosity path (especially around incrementing flags), so going further right now would either require patching vendor code or introducing larger structural changes. I agree we should improve this longer term; a good replacement would be Symfony Console (https://symfony.com/doc/current/components/console.html), which I know well and that already provides robust argument parsing, verbosity levels, and many related features. For this version, I think it is safer to keep it simple and stable, and handle a full CLI migration in a dedicated follow-up.

@norb wrote in https://code.verua.online/rabe/Util-Settings/pulls/4#issuecomment-3735: > perhaps we could have a verbose mode? Hi Norber, for this round I kept the verbose implementation minimal on purpose. The current CLI helper library is not fully compatible with PHP 8 in the verbosity path (especially around incrementing flags), so going further right now would either require patching vendor code or introducing larger structural changes. I agree we should improve this longer term; a good replacement would be Symfony Console (https://symfony.com/doc/current/components/console.html), which I know well and that already provides robust argument parsing, verbosity levels, and many related features. For this version, I think it is safer to keep it simple and stable, and handle a full CLI migration in a dedicated follow-up.
norb marked this conversation as resolved
bin/cfg Outdated
@ -23,3 +23,3 @@
}
$version = '0.3';
// Pre-parse site options so they can be passed after positional args.
Owner

I don't really like this .. seems over complicating the code. It is just for beging able to have different order of arguments?

not that important to me .. and probably better put inside the input helper library or replace it altogether .. IIRC the one used is not maintained anymore

I don't really like this .. seems over complicating the code. It is just for beging able to have different order of arguments? not that important to me .. and probably better put inside the input helper library or replace it altogether .. IIRC the one used is not maintained anymore
Author
Member

@norb wrote in #4 (comment):

I don't really like this .. seems over complicating the code. It is just for beging able to have different order of arguments?

not that important to me .. and probably better put inside the input helper library or replace it altogether .. IIRC the one used is not maintained anymore

You're right. After reviewing it again with the alias cleanup in place, I realized we can keep this much simpler. The pre-parse block was added as a defensive workaround while multiple option variants were still in play, but with --siteDir now unified and a couple of small follow-up fixes, the standard parser flow is sufficient. I removed that extra layer to keep the code cleaner and easier to maintain.

@norb wrote in https://code.verua.online/rabe/Util-Settings/pulls/4#issuecomment-3732: > I don't really like this .. seems over complicating the code. It is just for beging able to have different order of arguments? > > not that important to me .. and probably better put inside the input helper library or replace it altogether .. IIRC the one used is not maintained anymore You're right. After reviewing it again with the alias cleanup in place, I realized we can keep this much simpler. The pre-parse block was added as a defensive workaround while multiple option variants were still in play, but with --siteDir now unified and a couple of small follow-up fixes, the standard parser flow is sufficient. I removed that extra layer to keep the code cleaner and easier to maintain.
alejandro.sosa marked this conversation as resolved
bin/cfg Outdated
@ -60,6 +115,16 @@ $collection = (new Input\InputCollection())
->description('Path where the config/ directory of the package conf files is located, defaults to the working dir')
) // }}}
->add( Input\InputTypeFactory::build('LongOption')->name('site')->short('s') // {{{
Owner

as agreed in chat, again to keep the code simple, use --siteDir without alias

same argument, if we think we will need arguments, implement in used lib or use different lib

as agreed in chat, again to keep the code simple, use --siteDir without alias same argument, if we think we will need arguments, implement in used lib or use different lib
Author
Member

@norb wrote in #4 (comment):

as agreed in chat, again to keep the code simple, use --siteDir without alias

same argument, if we think we will need arguments, implement in used lib or use different lib

👍🏼 Done, agreed. I removed aliases and kept only --siteDir to keep the CLI simple

@norb wrote in https://code.verua.online/rabe/Util-Settings/pulls/4#issuecomment-3733: > as agreed in chat, again to keep the code simple, use --siteDir without alias > > same argument, if we think we will need arguments, implement in used lib or use different lib 👍🏼 Done, agreed. I removed aliases and kept only --siteDir to keep the CLI simple
alejandro.sosa marked this conversation as resolved
bin/cfg Outdated
@ -198,0 +277,4 @@
$siteFlag = 0x01;
// Only one site selector may be provided to avoid ambiguous targets.
$providedSiteOptions = [];
foreach ($preparsedSiteOptions as $option) {
Owner

our coding style would always put the opening curly bracket on a newline. I retain it specially important if the following codeblock is longer than a couple of lines

our coding style would always put the opening curly bracket on a newline. I retain it specially important if the following codeblock is longer than a couple of lines
alejandro.sosa marked this conversation as resolved
norb requested changes 2026-03-30 09:43:43 +00:00
Dismissed
bin/cfg Outdated
@ -23,3 +23,3 @@
}
$version = '0.3';
function readJsonInputFile(string $path): array
Owner

can you do this as validators? e.g.

->validator(new Input\Validator(

can you do this as validators? e.g. https://code.verua.online/rabe/helpers-cli-input/src/commit/c6fe64321ef06633c89bc055252f22d6ff676d52/example/example.php#L35
alejandro.sosa marked this conversation as resolved
bin/cfg Outdated
@ -200,0 +275,4 @@
$site = null;
$siteFlag = 0x01;
$siteInput = $argv->find('siteDir');
if ($siteInput !== null && $siteInput !== false)
Owner

probably most of this should be done in the validator as well

probably most of this should be done in the validator as well
alejandro.sosa marked this conversation as resolved
bin/cfg Outdated
@ -240,0 +366,4 @@
// Write needs exactly one payload source:
// either SETTING (key=value) or --in (JSON file).
// This avoids ambiguous input precedence and empty writes.
if ($inputFile && $settings['key'] !== '')
Owner

probably this one too?

probably this one too?
alejandro.sosa marked this conversation as resolved
norb approved these changes 2026-03-30 15:08:57 +00:00
norb merged commit 18860c799d into master 2026-03-30 15:09:21 +00:00
norb deleted branch 53687/task-support-instance-specific-cfg-write-target-v2 2026-03-30 15:09:21 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
rabe/Util-Settings!4
No description provided.