为命令行工具提供配置服务。

3.0.0 2024-04-05 00:11 UTC

README

管理命令行工具的配置。

ci scrutinizer codecov license

此组件旨在提供从不同来源管理配置选项所需的所有组件,包括

  • 命令行选项
  • 配置文件
  • 别名文件(特殊配置文件,用于标识特定的目标站点)
  • 默认值(由命令提供)

Symfony Console 用于为命令行工具提供框架,并使用 Symfony 配置组件来加载和合并配置文件。此项目提供将组件粘合在一起以便于使用的包。

如果您目标是能够快速编写可配置的命令行工具,您可能希望考虑使用 Robo 作为框架,因为在此项目中已经完成了设置此组件的工作。尽管如此,Consolidation/Config 可以与任何 Symfony Console 应用程序一起使用。

组件状态

在 Robo、Terminus 和 Drush 中使用。

动机

提供简单的 Config 类,可以在需要的地方注入以提供配置值,并通过自动从配置中初始化输入对象,使配置设置对命令类无效。

配置文件使用

配置文件是简单的层次化 YAML 文件。

提供命令选项

通过在配置文件的 command: 部分(每个命令名下创建一个条目)来定义命令选项。应在 options: 部分内定义命令的选项。例如,为 example 命令中的 --color 选项设置配置值 red

command:
  example:
    options:
      color: red

如果命令名中包含一个 :,则命令名的每个部分都定义了命令选项配置中的另一个层次。例如,为 my:foo 命令的 --name 选项设置配置值 George

command:
  my:
    foo:
      options:
        name: George

此外,命令名层次结构的每一级都可以包含选项。例如,为以 my: 开头的任何命令的 --dir 选项定义配置值

command:
  my:
    options:
      dir: '/base/path'
    foo:
      options:
        name: George
    bar:
      options:
        priority: high

提供全局选项

如果您的 Symfony Console 应用程序定义了全局选项,如下所示(来自 Application 类扩展方法中的方法)

$this->getDefinition()
    ->addOption(
        new InputOption('--simulate', null, InputOption::VALUE_NONE, 'Run in simulated mode (show what would have happened).')
    );

可以在全局选项部分声明全局选项的默认值

options:
  simulate: false

如果这样做,则将在命令行上设置的全球选项值将用于在运行时更改配置项的值。例如,当不使用 --simulate 全局选项时,$config->get('options.simulate') 将返回 false,当使用它时,将返回 true

有关如何启用此设置的说明,请参阅下面的“设置命令选项配置注入”部分。

配置值替换

可以在配置文件中定义将被替换的值。例如

common:
  path: '/shared/path'
command:
  my:
    options:
      dir: '${common.path}'
    foo:
      options:
        name: George

grasmash/yaml-expander 用于提供此功能。

API 使用

利用此项目功能的最简单方法是使用 Robo 作为框架 来创建您的命令行工具。尽管如此,使用 Robo 是可选的,因为此项目可以与任何 Symfony Console 应用程序一起使用。

使用提供的加载器加载配置文件

合并/配置包含一个内置的YAML加载器/处理器。要直接使用它,请使用YamlConfigLoader加载每个配置文件,并使用ConfigProcessor将它们合并在一起。然后,从配置处理器中导出结果,并将其导入到Config对象中。

use Consolidation\Config\Config;
use Consolidation\Config\YamlConfigLoader;
use Consolidation\Config\ConfigProcessor;

$config = new Config();
$loader = new YamlConfigLoader();
$processor = new ConfigProcessor();
$processor->extend($loader->load('defaults.yml'));
$processor->extend($loader->load('myconf.yml'));
$config->import($processor->export());

设置命令选项配置注入

上一节“提供命令选项”中描述的命令选项配置功能是通过配置注入类提供的。您需要做的只是将此对象附加到您的Symfony Console应用程序的事件分发器上,即可使用此功能。

$application = new Symfony\Component\Console\Application($name, $version);
$configInjector = new \Consolidation\Config\Inject\ConfigForCommand($config);
$configInjector->setApplication($application);

$eventDispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher();
$eventDispatcher->addSubscriber($configInjector);
$application->setDispatcher($eventDispatcher);

获取配置值

如果您有一个类似这样的配置文件

a:
  b:
    c: foo

那么您可以通过以下方式获取配置选项c的值

$value = $config->get('a.b.c');

dflydev/dot-access-data被利用来提供此功能。

插值

插值允许将配置值注入到字符串中,使用令牌。这些令牌用作在配置对象中查找的键;生成的配置值将用于替换提供的字符串中的令牌。

例如,使用上面显示的相同配置文件

$result = $config->interpolate('The value is: {{a.b.c}}')

在这个例子中,$result字符串将是

The value is: foo

配置覆盖

您可以选择使用ConfigOverlay类将多个实现ConfigInterface的配置对象合并成一个优先级配置对象。使用配置覆盖不是必需的;如果您的唯一目标是合并多个文件中的配置,您可以遵循上面的示例来扩展具有多个配置文件的处理器,然后将结果导入到单个配置对象中。这将导致较新的配置项覆盖同一键下存储的任何现有值。

配置覆盖可以在不覆盖任何配置值的情况下实现相同的结果。这样做的好处是,可以使用不同的配置覆盖来创建不同集合配置的“视图”。如果希望临时覆盖一些配置值,然后再通过移除覆盖将事物恢复原状,配置覆盖也非常有用。

use Consolidation\Config\Config;
use Consolidation\Config\YamlConfigLoader;
use Consolidation\Config\ConfigProcessor;
use Consolidation\Config\Util\ConfigOverlay;

$config1 = new Config();
$config2 = new Config();
$loader = new YamlConfigLoader();
$processor = new ConfigProcessor();
$processor->extend($loader->load('c1.yml'));
$config1->import($processor->export());
$processor = new ConfigProcessor();
$processor->extend($loader->load('c2.yml'));
$config2->import($processor->export());

$configOverlay = (new ConfigOverlay())
    ->addContext('one', $config1)
    ->addContext('two', $config2);

$value = $configOverlay->get('key');

$configOverlay->removeContext('two');

$value = $configOverlay->get('key');

上面的第一个对$configOverlay->get('key')的调用将返回存在于$config2中的key的值,如果存在的话,否则从$config1中返回。在移除$config2之后的第二次对同一函数的调用,将仅考虑存储在$config1中的配置值。

外部示例

使用Symfony/Config加载配置文件

Symfony Config组件提供定位配置文件、从YAML或XML源加载它们以及验证它们是否与特定定义的方案匹配的功能。也有用于查找配置文件的类。

如果需要这些功能,可以直接将Symfony\Component\Config\Definition\Processor::processConfiguration()的结果提供给Consolidation\Config\Config::import()方法。

使用配置调用setter方法

Robo提供了一种配置文件定义任务setter方法默认值的功能。这是通过ConfigForSetters::apply()方法完成的。

$taskClass = static::configClassIdentifier($taskClass);
$configurationApplier = new \Consolidation\Config\Inject\ConfigForSetters($this->getConfig(), $taskClass, 'task.');
$configurationApplier->apply($task, 'settings');

configClassIdentifier方法将\分隔的类和命名空间名称转换为.分隔的标识符;它由ConfigAwareTrait提供

protected static function configClassIdentifier($classname)
{
    $configIdentifier = strtr($classname, '\\', '.');
    $configIdentifier = preg_replace('#^(.*\.Task\.|\.)#', '', $configIdentifier);

    return $configIdentifier;
}

在其他可能希望使用setter方法注入值的对象中,可以使用类似的模式。

与现有解决方案的比较

Drush具有从多个文件中加载配置值并按优先级顺序叠加结果的过程化机制。配置文件和站点别名中的特定命令选项也可以应用。