Browse Source

feat(preset): compare default for all preset

Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
pull/54414/head
Maxence Lange 2 months ago
parent
commit
6eda5583db
  1. 22
      core/Command/Config/Preset.php
  2. 8
      lib/private/AppConfig.php
  3. 66
      lib/private/Config/PresetManager.php

22
core/Command/Config/Preset.php

@ -11,6 +11,7 @@ namespace OC\Core\Command\Config;
use OC\Config\PresetManager;
use OC\Core\Command\Base;
use OCP\Config\Lexicon\Preset as ConfigLexiconPreset;
use Symfony\Component\Console\Helper\Table;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
@ -28,7 +29,8 @@ class Preset extends Base {
$this->setName('config:preset')
->setDescription('Select a config preset')
->addArgument('preset', InputArgument::OPTIONAL, 'Preset to use for all unset config values', '')
->addOption('list', '', InputOption::VALUE_NONE, 'display available preset');
->addOption('list', '', InputOption::VALUE_NONE, 'display available preset')
->addOption('compare', '', InputOption::VALUE_NONE, 'compare preset');
}
protected function execute(InputInterface $input, OutputInterface $output): int {
@ -38,6 +40,24 @@ class Preset extends Base {
return self::SUCCESS;
}
if ($input->getOption('compare')) {
$list = $this->presetManager->retrieveLexiconPreset();
if ($input->getOption('output') === 'plain') {
$table = new Table($output);
$table->setHeaders(['app', 'config key', 'value', ...array_map(static fn (ConfigLexiconPreset $p): string => $p->name, ConfigLexiconPreset::cases())]);
foreach ($list as $appId => $entries) {
foreach ($entries as $item) {
$table->addRow([$appId, $item['entry']['key'], '<comment>' . ($item['value'] ?? '') . '</comment>', ...($item['defaults'] ?? [])]);
}
}
$table->render();
return self::SUCCESS;
}
$this->writeArrayInOutputFormat($input, $output, $list);
return self::SUCCESS;
}
$presetArg = $input->getArgument('preset');
if ($presetArg !== '') {
$preset = $this->getEnum($presetArg, $list);

8
lib/private/AppConfig.php

@ -1791,7 +1791,13 @@ class AppConfig implements IAppConfig {
return $this->configLexiconDetails[$appId];
}
private function getLexiconEntry(string $appId, string $key): ?Entry {
/**
* get Lexicon Entry using appId and config key entry
*
* @return Entry|null NULL if entry does not exist in app's Lexicon
* @internal
*/
public function getLexiconEntry(string $appId, string $key): ?Entry {
return $this->getConfigDetailsFromLexicon($appId)['entries'][$key] ?? null;
}

66
lib/private/Config/PresetManager.php

@ -12,10 +12,15 @@ use OC\App\AppManager;
use OC\Installer;
use OCP\App\AppPathNotFoundException;
use OCP\App\IAppManager;
use OC\AppConfig;
use OCP\App\IAppManager;
use OCP\Config\Lexicon\Preset;
use OCP\Exceptions\AppConfigUnknownKeyException;
use OCP\IAppConfig;
use OCP\IConfig;
use OCP\Server;
use Psr\Log\LoggerInterface;
use OCP\Server;
/**
* tools to manage the Preset feature
@ -57,6 +62,67 @@ class PresetManager {
return $this->configLexiconPreset;
}
/**
* get lexicon config entries affected by Preset and its default values
*
* **Warning** This method MUST be considered resource-needy!
*
* @return array<string, list<array{defaults: array{CLUB: null|string, FAMILY: null|string, LARGE: null|string, MEDIUM: null|string, NONE: null|string, PRIVATE: null|string, SCHOOL: null|string, SHARED: null|string, SMALL: null|string, UNIVERSITY: null|string}, entry: array{definition: string, deprecated: bool, key: string, lazy: bool, note: string, type: 'ARRAY'|'BOOL'|'FLOAT'|'INT'|'MIXED'|'STRING'}, value?: mixed}>>
*/
public function retrieveLexiconPreset(?string $appId = null): array {
if ($appId === null) {
$apps = [];
foreach (['core'] + Server::get(IAppManager::class)->getEnabledApps() as $app) {
$preset = $this->retrieveLexiconPreset($app);
$apps[$app] = $preset[$app];
}
return $apps;
}
/** @var AppConfig|null $appConfig */
$appConfig = Server::get(IAppConfig::class);
$lexicon = $appConfig->getConfigDetailsFromLexicon($appId);
$presets = [];
foreach ($lexicon['entries'] as $entry) {
$defaults = [];
foreach (Preset::cases() as $case) {
// for each case, we need to use a fresh IAppConfig with clear cache
// cloning to avoid conflict while emulating preset
$newConfig = clone $appConfig;
$newConfig->clearCache(); // needed to ignore cache and rebuild default
$newLexicon = $newConfig->getLexiconEntry($appId, $entry->getKey());
$defaults[$case->name] = $newLexicon?->getDefault($case);
}
// compare all value from $defaults, if more than 1 exist we have a preset
$uniqueness = array_unique($defaults);
if (count($uniqueness) < 2) {
continue;
}
$details = [
'entry' => [
'key' => $entry->getKey(),
'type' => $entry->getValueType()->name,
'definition' => $entry->getDefinition(),
'lazy' => $entry->isLazy(),
'deprecated' => $entry->isDeprecated(),
'note' => $entry->getNote(),
],
'defaults' => $defaults
];
try {
$details['value'] = $appConfig->getDetails($appId, $entry->getKey())['value'];
} catch (AppConfigUnknownKeyException) {
}
$presets[] = $details;
}
return [$appId => $presets];
}
/**
* Enable and/or Disable a list of apps based on the currently selected Preset
*/

Loading…
Cancel
Save