7fdf11fc92822c4613d102ab168ffbcf70b28fc1
[yaffs-website] / vendor / consolidation / config / README.md
1 # Consolidation\Config
2
3 Manage configuration for a commandline tool.
4
5 [![Travis CI](https://travis-ci.org/consolidation/config.svg?branch=master)](https://travis-ci.org/consolidation/config) 
6 [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/consolidation/config/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/consolidation/config/?branch=master)
7 [![Coverage Status](https://coveralls.io/repos/github/consolidation/config/badge.svg?branch=master)](https://coveralls.io/github/consolidation/config?branch=master)
8 [![License](https://poser.pugx.org/consolidation/config/license)](https://packagist.org/packages/consolidation/config)
9
10 This component is designed to provide the components needed to manage configuration options from different sources, including:
11
12 - Commandline options
13 - Configuration files
14 - Alias files (special configuration files that identify a specific target site)
15 - Default values (provided by command)
16
17 Symfony Console is used to provide the framework for the commandline tool, and the Symfony Configuration component is used to load and merge configuration files.  This project provides the glue that binds the components together in an easy-to-use package.
18
19 If your goal is to be able to quickly write configurable commandline tools, you might want to consider using [Robo as a Framework](https://robo.li/framework), as the work for setting up this component is already done in that project. Consolidation/Config may be used with any Symfony Console application, though.
20
21 ## Component Status
22
23 In use in Robo (1.x), Terminus (1.x) and Drush (9.x).
24
25 ## Motivation
26
27 Provide a simple Config class that can be injected where needed to provide configuration values in non-command classes, and make configuration settings a no-op for command classes by automatically initializing the Input object from configuration as needed.
28
29 ## Configuration File Usage
30
31 Configuration files are simple hierarchical yaml files.
32
33 ### Providing Command Options
34
35 Command options are defined by creating an entry for each command name under the `command:` section of the configuration file. The options for the command should be defined within an `options:` section. For example, to set a configuration value `red` for the option `--color` in the `example` command:
36 ```
37 command:
38   example:
39     options:
40       color: red
41 ```
42 If a command name contains a `:`, then each section of the command name defines another level of heirarchy in the command option configuration. For example, to set a configuration value `George` for the option `--name` of the command `my:foo`:
43 ```
44 command:
45   my:
46     foo:
47       options:
48         name: George
49 ```
50 Furthermore, every level of the command name heirarchy may contain options. For example, to define a configuration value for the option `--dir` for any command that begins with `my:`:
51 ```
52 command:
53   my:
54     options:
55       dir: '/base/path'
56     foo:
57       options:
58         name: George
59     bar:
60       options:
61         priority: high
62 ```
63
64 ### Providing Global Options
65
66 If your Symfony Console application defines global options, like so (from a method in an extension of the Application class):
67 ```
68 $this->getDefinition()
69     ->addOption(
70         new InputOption('--simulate', null, InputOption::VALUE_NONE, 'Run in simulated mode (show what would have happened).')
71     );
72 ```
73 Default values for global options can then be declared in the global options section:
74 ```
75 options:
76   simulate: false
77 ```
78 If this is done, then global option values set on the command line will be used to alter the value of the configuration item at runtime. For example, `$config->get('options.simulate')` will return `false` when the `--simulate` global option is not used, and will return `true` when it is.
79
80 See the section "Set Up Command Option Configuration Injection", below, for instructions on how to enable this setup.
81
82 ### Configuration Value Substitution
83
84 It is possible to define values in a configuration file that will be substituted in wherever used. For example:
85 ```
86 common:
87   path: '/shared/path'
88 command:
89   my:
90     options:
91       dir: '${common.path}'
92     foo:
93       options:
94         name: George
95 ```
96
97 [grasmash/yaml-expander](https://github.com/grasmash/expander) is used to provide this capability.
98
99 ## API Usage
100
101 The easiest way to utilize the capabilities of this project is to use [Robo as a framework](https://robo.li/framework) to create your commandline tools. Using Robo is optional, though, as this project will work with any Symfony Console application.
102
103 ### Load Configuration Files with Provided Loader
104
105 Consolidation/config includes a built-in yaml loader / processor. To use it directly, use a YamlConfigLoader to load each of your configuration files, and a ConfigProcessor to merge them together. Then, export the result from the configuration processor, and import it into a Config object.
106 ```
107 use Consolidation\Config\Config;
108 use Consolidation\Config\YamlConfigLoader;
109 use Consolidation\Config\ConfigProcessor;
110
111 $config = new Config();
112 $loader = new YamlConfigLoader();
113 $processor = new ConfigProcessor();
114 $processor->extend($loader->load('defaults.yml'));
115 $processor->extend($loader->load('myconf.yml'));
116 $config->import($processor->export());
117 ```
118
119 ### Set Up Command Option Configuration Injection
120
121 The command option configuration feature described above in the section `Providing Command Options` is provided via a configuration injection class. All that you need to do to use this feature as attach this object to your Symfony Console application's event dispatcher:
122 ```
123 $application = new Symfony\Component\Console\Application($name, $version);
124 $configInjector = new \Consolidation\Config\Inject\ConfigForCommand($config);
125 $configInjector->setApplication($application);
126
127 $eventDispatcher = new \Symfony\Component\EventDispatcher\EventDispatcher();
128 $eventDispatcher->addSubscriber($configInjector);
129 $application->setDispatcher($eventDispatcher);
130 ```
131
132
133 ### Get Configuration Values
134 If you have a configuration file that looks like this:
135 ```
136 a:
137   b:
138     c: foo
139 ```
140 Then you can fetch the value of the configuration option `c` via: 
141 ```
142 $value = $config->get('a.b.c');
143 ```
144 [dflydev/dot-access-data](https://github.com/dflydev/dot-access-data) is leveraged to provide this capability.
145
146 ### Configuration Overlays
147
148 Optionally, you may use the ConfigOverlay class to combine multiple configuration objects implamenting ConfigInterface into a single, prioritized configuration object. It is not necessary to use a configuration overlay; if your only goal is to merge configuration from multiple files, you may follow the example above to extend a processor with multiple configuration files, and then import the result into a single configuration object. This will cause newer configuration items to overwrite any existing values stored under the same key.
149
150 A configuration overlay can achieve the same end result without overwriting any config values. The advantage of doing this is that different configuration overlays could be used to create separate "views" on different collections of configuration. A configuration overlay is also useful if you wish to temporarily override some configuration values, and then put things back the way they were by removing the overlay.
151 ```
152 use Consolidation\Config\Config;
153 use Consolidation\Config\YamlConfigLoader;
154 use Consolidation\Config\ConfigProcessor;
155 use Consolidation\Config\Util\ConfigOverlay;
156
157 $config1 = new Config();
158 $config2 = new Config();
159 $loader = new YamlConfigLoader();
160 $processor = new ConfigProcessor();
161 $processor->extend($loader->load('c1.yml'));
162 $config1->import($processor->export());
163 $processor = new ConfigProcessor();
164 $processor->extend($loader->load('c2.yml'));
165 $config2->import($processor->export());
166
167 $configOverlay = (new ConfigOverlay())
168     ->addContext('one', $config1)
169     ->addContext('two', $config2);
170
171 $value = $configOverlay->get('key');
172
173 $configOverlay->removeContext('two');
174
175 $value = $configOverlay->get('key');
176 ```
177 The first call to `$configOverlay->get('key')`, above, will return the value from `key` in `$config2`, if it exists, or from `$config1` otherwise. The second call to the same function, after `$config2` is removed, will only consider configuration values stored in `$config1`.
178
179 ## External Examples
180
181 ### Load Configuration Files with Symfony/Config
182
183 The [Symfony Config](http://symfony.com/doc/current/components/config.html) component provides the capability to locate configuration file, load them from either YAML or XML sources, and validate that they match a certain defined schema. Classes to find configuration files are also available.
184
185 If these features are needed, the results from `Symfony\Component\Config\Definition\Processor::processConfiguration()` may be provided directly to the `Consolidation\Config\Config::import()` method.
186
187 ### Use Configuration to Call Setter Methods
188
189 [Robo](https://robo.li) provides a facility for configuration files to [define default values for task setter methods](http://robo.li/getting-started/#configuration-for-task-settings). This is done via the `ConfigForSetters::apply()` method.
190 ```
191 $taskClass = static::configClassIdentifier($taskClass);
192 $configurationApplier = new \Consolidation\Config\Inject\ConfigForSetters($this->getConfig(), $taskClass, 'task.');
193 $configurationApplier->apply($task, 'settings');
194 ```
195 The `configClassIdentifier` method converts `\`-separated class and namespace names into `.`-separated identifiers; it is provided by ConfigAwareTrait:
196 ```
197 protected static function configClassIdentifier($classname)
198 {
199     $configIdentifier = strtr($classname, '\\', '.');
200     $configIdentifier = preg_replace('#^(.*\.Task\.|\.)#', '', $configIdentifier);
201
202     return $configIdentifier;
203 }
204 ```
205 A similar pattern may be used in other applications that may wish to inject values into objects using their setter methods.
206
207 ## Comparison to Existing Solutions
208
209 Drush has an existing procedural mechanism for loading configuration values from multiple files, and overlaying the results in priority order.  Command-specific options from configuration files and site aliases may also be applied.
210