#!/usr/bin/env php '', 'value' => '']; /* Flags and Argument configuration {{{*/ $collection = (new Input\InputCollection()) ->add( Input\InputTypeFactory::build('LongOption')->name('help')->short('h') // {{{ ->flags(AbstractInputType::FLAG_OPTIONAL) ->description('Display help text') ) // }}} ->add( Input\InputTypeFactory::build('LongOption')->name('in')->short('i') // {{{ ->flags(AbstractInputType::FLAG_OPTIONAL | Input\AbstractInputType::FLAG_VALUE_REQUIRED) ->description('Path to a json data file to to read') ) // }}} ->add( Input\InputTypeFactory::build('LongOption')->name('out')->short('o') // {{{ ->flags(AbstractInputType::FLAG_OPTIONAL | Input\AbstractInputType::FLAG_VALUE_REQUIRED) ->description('Path to a json file to to write to') ) // }}} ->add( Input\InputTypeFactory::build('LongOption')->name('appPath')->short('a') // {{{ ->flags(AbstractInputType::FLAG_OPTIONAL | Input\AbstractInputType::FLAG_VALUE_REQUIRED) ->description('Path where the config/ directory for the conf files is located, defaults to the working dir') ) // }}} ->add( Input\InputTypeFactory::build('LongOption')->name('pkgPath')->short('p') // {{{ ->flags(AbstractInputType::FLAG_OPTIONAL | Input\AbstractInputType::FLAG_VALUE_REQUIRED) ->description('Path where the config/ directory of the package conf files is located, defaults to the working dir') ) // }}} ->add( Input\InputTypeFactory::build('Argument')->name('action') // {{{ ->flags(AbstractInputType::FLAG_REQUIRED) ->description( 'one of:' ."\n\t".'show reads configurations' ."\n\t".'write writes configurations' ) ->validator(new Input\Validator( function (AbstractInputType $input, AbstractInputHandler $context) use ($actions) { $action = $context->find('action'); if ( !in_array($action, $actions) ) { throw new \Exception("'$action' not found"); } return $action; } )) ) // }}} ->add( Input\InputTypeFactory::build('Argument')->name('prefix') // {{{ ->flags(AbstractInputType::FLAG_REQUIRED) ->description( 'the settings prefix' ) /* ->validator(new Input\Validator( function (AbstractInputType $input, AbstractInputHandler $context) use ($actions) { $action = $context->find('action'); if ( !in_array($action, $actions) { throw new \Exception("'$action' not found"); } return $action; } )) */ ) // }}} ->add( Input\InputTypeFactory::build('Argument')->name('setting') // {{{ ->flags(AbstractInputType::FLAG_OPTIONAL) ->description( 'the settings you want to work on. With action "write" you can pass the value to set as JSON after an equal sign.' ) ->validator(new Input\Validator( function (AbstractInputType $input, AbstractInputHandler $context) { $setting = $context->find('setting'); $action = $context->find('action'); $setting = explode('=', $setting); $settings['key'] = $setting[0]; if ($action === 'write') { $value = $setting[1]; if (! (isset($value) || $context->find('data'))) { throw new \Exception('You need a value to write'); } $specialValues = [ 'true', 'false', 'null' ]; if (! (in_array($value, $specialValues) || is_numeric($value) || strpbrk($value, '[{":') !== false )) { $value = "\"$value\""; } try { $settings['value'] = json_decode($value, true, 512, JSON_THROW_ON_ERROR); } catch (\JsonException $ex) { throw new \Exception( sprintf( 'The value does not appear to be a valid JSON string. Returned: %s: %s', $ex->getCode(), $ex->getMessage() )); } } return $settings; } )) ) // }}} ; // }}} /* Parse Input, usage, unkown flags, Help {{{*/ $usage = Cli\manpage( basename(__FILE__), $version, 'read write settings', $collection, Colour::FG_GREEN, Colour::FG_WHITE, [ 'Examples' => 'cfg show VeruA db:host'.PHP_EOL. 'cfg write VeruA \'db:host="newHost"\''.PHP_EOL ] ).PHP_EOL; // Get the supplied input. Passing the collection will make the handler bind values // and validate the input according to our collection try { $argv = Input\InputHandlerFactory::build('Argv', $collection); } catch (\Exception $ex) { echo $usage; if ($argv[1] == '-h' || $argv[1] == '--help' || $argv[1] == 'help') { exit(0); } echo $ex->getMessage().PHP_EOL; exit(1); } // show help if ($argv->find( 'help' ) || $argv->find('action') == 'help') { echo $usage; exit(0); } //}}} $prefix = $argv->find('prefix'); /* echo $argv->find('action').PHP_EOL; echo ($prefix).PHP_EOL; echo $argv->find('setting')['key'].PHP_EOL; echo $argv->find('setting')['value'].PHP_EOL; */ // var_dump($cfg); $appPath = $argv->find('appPath'); if (!$appPath) $appPath = getcwd().'/'; /* $it = new RecursiveDirectoryIterator($appPath); foreach(new RecursiveIteratorIterator($it) as $file) { $configDir = $file->getPath(); if ($file->isDir() && $file->getFilename() == '.' && basename($configDir) == 'config') { echo "found config dir: $configDir\n"; } } */ $cfg = (new Settings())->appPath($appPath)->prefix($prefix); if ($pkgPath = $argv->find('pkgPath')) $cfg->pkgPath($pkgPath); if (is_readable($cfg->buildFileName('default'))) { $cfg->load(); } elseif (is_readable($cfgFile = $cfg->buildFileName())) { $cfg->load(require($cfgFile)); } //var_dump($cfg); $result = $cfg; $settings = $argv->find('setting') ?? $settings; if ($settings['key']) { foreach (explode(':', $settings['key']) as $setting) { try { $result = $result->{$setting}; } catch (\OutOfRangeException $e) { echo $e->getMessage().PHP_EOL; exit(1); } } } else $result = $cfg; if ($result instanceof Settings) $result = $result->toArray(); switch ($argv->find('action')) { case 'show': echo json_encode($result, JSON_PRETTY_PRINT).PHP_EOL; break; case 'write': $path = ($settings['key'] !== '') ? explode(':', $settings['key']) : []; var_dump($path); $setting2write = $settings['value']; while ( ! empty($path)) { $setting2write = [array_pop($path) => $setting2write]; } if (is_readable($file = $cfg->buildFileName())) { $setting2write = array_replace_recursive(require($file), $setting2write); copy($file, "$file.bak"); } $writeCfg = $cfg->create($setting2write); // var_dump($writeCfg->toArray()); try { (new SettingsWriter($writeCfg))->write(); echo "Written modified settings to: $file".PHP_EOL; } catch (\Exception $e) { echo $e->getMessage().PHP_EOL; } break; } /* jEdit buffer local properties {{{ * :folding=explicit:collapseFolds=1: }}}*/