1CLI Usage
2===========
3
4python-anyconfig contains a CLI frontend 'anyconfig_cli' to demonstrate the
5power of this library.
6
7It can process config files in any formats supported in your environment and:
8
9- output merged/converted config outputs w/ modifications needed
10- output schema file for given inputs
11- merge/convert input config and extract part of the config
12
13.. code-block:: console
14
15  ssato@localhost% anyconfig_cli -h
16  Usage: anyconfig_cli [Options...] CONF_PATH_OR_PATTERN_0 [CONF_PATH_OR_PATTERN_1 ..]
17
18  Examples:
19    anyconfig_cli --list  # -> Supported config types: configobj, ini, json, ...
20    # Merge and/or convert input config to output config [file]
21    anyconfig_cli -I yaml -O yaml /etc/xyz/conf.d/a.conf
22    anyconfig_cli -I yaml '/etc/xyz/conf.d/*.conf' -o xyz.conf --otype json
23    anyconfig_cli '/etc/xyz/conf.d/*.json' -o xyz.yml \
24      --atype json -A '{"obsoletes": "sysdata", "conflicts": "sysdata-old"}'
25    anyconfig_cli '/etc/xyz/conf.d/*.json' -o xyz.yml \
26      -A obsoletes:sysdata;conflicts:sysdata-old
27    anyconfig_cli /etc/foo.json /etc/foo/conf.d/x.json /etc/foo/conf.d/y.json
28    anyconfig_cli '/etc/foo.d/*.json' -M noreplace
29    # Get/set part of input config
30    anyconfig_cli '/etc/foo.d/*.json' --get a.b.c
31    anyconfig_cli '/etc/foo.d/*.json' --set a.b.c=1
32
33  Options:
34    --version             show program's version number and exit
35    -h, --help            show this help message and exit
36    -o OUTPUT, --output=OUTPUT
37                          Output file path
38    -I ITYPE, --itype=ITYPE
39                          Select type of Input config files from configobj, ini,
40                          json, msgpack, xml, yaml [Automatically detected by
41                          file ext]
42    -O OTYPE, --otype=OTYPE
43                          Select type of Output config files from configobj,
44                          ini, json, msgpack, xml, yaml [Automatically detected
45                          by file ext]
46    -M MERGE, --merge=MERGE
47                          Select strategy to merge multiple configs from
48                          replace, noreplace, merge_dicts, merge_dicts_and_lists
49                          [merge_dicts]
50    -A ARGS, --args=ARGS  Argument configs to override
51    --atype=ATYPE         Explicitly select type of argument to provide configs
52                          from configobj, ini, json, msgpack, xml, yaml.  If
53                          this option is not set, original parser is used: 'K:V'
54                          will become {K: V}, 'K:V_0,V_1,..' will become {K:
55                          [V_0, V_1, ...]}, and 'K_0:V_0;K_1:V_1' will become
56                          {K_0: V_0, K_1: V_1} (where the tyep of K is str, type
57                          of V is one of Int, str, etc.
58    -x, --ignore-missing  Ignore missing input files
59    -T, --template        Enable template config support
60    -E, --env             Load configuration defaults from environment values
61    -S SCHEMA, --schema=SCHEMA
62                          Specify Schema file[s] path
63    -s, --silent          Silent or quiet mode
64    -q, --quiet           Same as --silent option
65    -v, --verbose         Verbose mode
66
67    List specific options:
68      -L, --list          List supported config types
69
70    Schema specific options:
71      --validate          Only validate input files and do not output. You must
72                          specify schema file with -S/--schema option.
73      --gen-schema        Generate JSON schema for givne config file[s] and
74                          output it instead of (merged) configuration.
75
76    Get/set options:
77      -Q QUERY, --query=QUERY
78                          Query with JMESPath expression language. See
79                          http://jmespath.org for more about JMESPath
80                          expression. This option is not used with --get option
81                          at the same time. Please note that python module to
82                          support JMESPath expression
83                          (https://pypi.python.org/pypi/jmespath/) is required
84                          to use this option
85      --get=GET           Specify key path to get part of config, for example, '
86                          --get a.b.c' to config {'a': {'b': {'c': 0, 'd': 1}}}
87                          gives 0 and '--get a.b' to the same config gives {'c':
88                          0, 'd': 1}.
89      --set=SET           Specify key path to set (update) part of config, for
90                          example, '--set a.b.c=1' to a config {'a': {'b': {'c':
91                          0, 'd': 1}}} gives {'a': {'b': {'c': 1, 'd': 1}}}.
92  ssato@localhost%
93
94List supported config types (formats)
95---------------------------------------
96
97anyconfig_cli lists config types (formats) supported in your environment with -L/--list option:
98
99.. code-block:: console
100
101  $ anyconfig_cli -L
102  Supported config types: configobj, ini, json, msgpack, xml, yaml
103  $ anyconfig_cli --list
104  Supported config types: configobj, ini, json, msgpack, xml, yaml
105  $
106
107Merge and/or convert input config
108-----------------------------------
109
110anyconfig_cli can process a config file or config files and output merged
111config in various formats it can support in your environment.
112
113Here are some such examples.
114
115- single input config file, input type is automatically detected from the input file's extension:
116
117.. code-block:: console
118
119  $ cat /tmp/a.yml
120  a: 1
121  b:
122    c:
123      - aaa
124      - bbb
125  d:
126    e:
127      f: xyz
128      g: true
129  $ anyconfig_cli -O json /tmp/a.yml
130  Loading: /tmp/a.yml
131  {"a": 1, "b": {"c": ["aaa", "bbb"]}, "d": {"e": {"g": true, "f": "xyz"}}}
132
133- single input config file with the input type and output option:
134
135.. code-block:: console
136
137  $ diff -u /tmp/a.{yml,conf}
138  $ anyconfig_cli -I yaml -O configobj /tmp/a.conf -o /tmp/a.ini --silent
139  $ cat /tmp/a.ini
140  a = 1
141  [b]
142  c = aaa, bbb
143  [d]
144  [[e]]
145  g = True
146  f = xyz
147  $
148
149- multiple input config files:
150
151.. code-block:: console
152
153  $ cat /tmp/b.yml
154  b:
155    i:
156      j: 123
157  d:
158    e:
159      g: hello, world
160  l: -1
161  $ anyconfig_cli /tmp/{a,b}.yml --silent
162  a: 1
163  b:
164    c: [aaa, bbb]
165    i: {j: 123}
166  d:
167    e: {f: xyz, g: 'hello, world'}
168  l: -1
169
170  $
171
172- multiple input config files with merge strategy option:
173
174.. code-block:: console
175
176  $ anyconfig_cli /tmp/{a,b}.yml -M replace --silent
177  a: 1
178  b:
179    i: {j: 123}
180  d:
181    e: {g: 'hello, world'}
182  l: -1
183
184  $
185
186- multiple input config files with template option:
187
188.. code-block:: console
189
190  $ cat /tmp/c.yml
191  m: {{ d.e.g }}
192  n: {{ b.i.j }}
193  $ anyconfig_cli /tmp/{a,b,c}.yml --silent --template
194  a: 1
195  b:
196    c: [aaa, bbb]
197    i: {j: 123}
198  d:
199    e: {f: xyz, g: 'hello, world'}
200  l: -1
201  m: hello, world
202  n: 123
203
204  $ ls /tmp/*.yml
205  /tmp/a.yml  /tmp/b.yml  /tmp/c.yml
206  $ # Same as the privious one but inputs are given in a glob pattern.
207  $ anyconfig_cli '/tmp/*.yml' --silent --template  # same as the privious one
208  a: 1
209  b:
210    c: [aaa, bbb]
211    i: {j: 123}
212  d:
213    e: {f: xyz, g: 'hello, world'}
214  l: -1
215  m: hello, world
216  n: 123
217
218  $
219
220- Missing input config files:
221
222.. code-block:: console
223
224  $ ls /tmp/not-exist-file.yml
225  ls: cannot access /tmp/not-exist-file.yml: No such file or directory
226  $ anyconfig_cli --ignore-missing /tmp/not-exist-file.yml -s
227  {}
228
229  $ anyconfig_cli --ignore-missing /tmp/not-exist-file.yml -s -A "a: aaa"
230  No config type was given. Try to parse...
231  {a: aaa}
232
233  $ anyconfig_cli --ignore-missing /tmp/not-exist-file.yml -s -A "a: aaa; b: 123"
234  No config type was given. Try to parse...
235  {a: aaa, b: 123}
236
237  $
238
239Schema generation and validation
240----------------------------------
241
242anyconfig_cli can process input config file[s] and generate JSON schema file to
243validate the config like this:
244
245- An usage example of schema generation option --gen-schema of anyconfig_cli:
246
247.. code-block:: console
248
249  $ cat /tmp/a.yml
250  a: 1
251  b:
252    c:
253      - aaa
254      - bbb
255  d:
256    e:
257      f: xyz
258      g: true
259  $ anyconfig_cli --gen-schema /tmp/a.yml -s -o /tmp/a.schema.json
260  $ jq '.' /tmp/a.schema.json
261  {
262    "properties": {
263      "d": {
264        "properties": {
265          "e": {
266            "properties": {
267              "f": {
268                "type": "string"
269              },
270              "g": {
271                "type": "boolean"
272              }
273            },
274            "type": "object"
275          }
276        },
277        "type": "object"
278      },
279      "b": {
280        "properties": {
281          "c": {
282            "type": "array",
283            "items": {
284              "type": "string"
285            }
286          }
287        },
288        "type": "object"
289      },
290      "a": {
291        "type": "integer"
292      }
293    },
294    "type": "object"
295  }
296  $
297
298- and schema validation option --validate (and --schema) of anyconfig_cli:
299
300.. code-block:: console
301
302  $ anyconfig_cli -A 'a: aaa' --atype yaml /tmp/a.yml -o /tmp/a2.yml --silent
303  $ head -n 1 /tmp/a.yml
304  a: 1
305  $ head -n 1 /tmp/a2.yml
306  a: aaa
307  $ anyconfig_cli --validate --schema /tmp/a.schema.json /tmp/a.yml
308  Loading: /tmp/a.schema.json
309  Loading: /tmp/a.yml
310  Validation succeeds
311  $ anyconfig_cli --validate --schema /tmp/a.schema.json /tmp/a.yml -s; echo $?
312  0
313  $ anyconfig_cli --validate --schema /tmp/a.schema.json /tmp/a2.yml -s; echo $?
314  'aaa' is not of type u'integer'
315
316  Failed validating u'type' in schema[u'properties'][u'a']:
317      {u'type': u'integer'}
318
319  On instance[u'a']:
320      'aaa'
321  Validation failed1
322  $
323
324Query/Get/set - extract or set part of input config
325------------------------------------------------------
326
327Here is usage examples of --get option of anyconfig_cli:
328
329.. code-block:: console
330
331  $ cat /tmp/a.yml
332  a: 1
333  b:
334    c:
335      - aaa
336      - bbb
337  d:
338    e:
339      f: xyz
340      g: true
341  $ anyconfig_cli /tmp/a.yml --get d.e.f --silent
342  xyz
343  $ anyconfig_cli /tmp/a.yml --get b.c --silent
344  ['aaa', 'bbb']
345  $ anyconfig_cli /tmp/a.yml --query d.e.g --silent
346  True
347  $ anyconfig_cli /tmp/a.yml --query 'b.c[::-1]' --silent
348  ['bbb', 'aaa']
349
350and an usage example of --set option of anyconfig_cli with same input:
351
352.. code-block:: console
353
354  $ anyconfig_cli /tmp/a.yml --set "d.e.g=1000" --set "b.c=ccc," --silent
355  a: 1
356  b:
357    c: [ccc]
358  d:
359    e: {f: xyz, g: true}
360
361  $
362
363.. vim:sw=2:ts=2:et:
364