|
1 | 1 | from __future__ import print_function |
2 | 2 |
|
3 | 3 | import argparse |
| 4 | +import collections |
4 | 5 | import sys |
5 | 6 |
|
6 | 7 | import yaml |
|
11 | 12 | Loader = yaml.SafeLoader |
12 | 13 |
|
13 | 14 |
|
| 15 | +def _exhaust(gen): |
| 16 | + for _ in gen: |
| 17 | + pass |
| 18 | + |
| 19 | + |
| 20 | +def _parse_unsafe(*args, **kwargs): |
| 21 | + _exhaust(yaml.parse(*args, **kwargs)) |
| 22 | + |
| 23 | + |
14 | 24 | def _load_all(*args, **kwargs): |
15 | | - # need to exhaust the generator |
16 | | - return tuple(yaml.load_all(*args, **kwargs)) |
| 25 | + _exhaust(yaml.load_all(*args, **kwargs)) |
| 26 | + |
| 27 | + |
| 28 | +Key = collections.namedtuple('Key', ('multi', 'unsafe')) |
| 29 | +LOAD_FNS = { |
| 30 | + Key(multi=False, unsafe=False): yaml.load, |
| 31 | + Key(multi=False, unsafe=True): _parse_unsafe, |
| 32 | + Key(multi=True, unsafe=False): _load_all, |
| 33 | + Key(multi=True, unsafe=True): _parse_unsafe, |
| 34 | +} |
17 | 35 |
|
18 | 36 |
|
19 | 37 | def check_yaml(argv=None): |
20 | 38 | parser = argparse.ArgumentParser() |
21 | 39 | parser.add_argument( |
22 | | - '-m', '--allow-multiple-documents', dest='yaml_load_fn', |
23 | | - action='store_const', const=_load_all, default=yaml.load, |
| 40 | + '-m', '--multi', '--allow-multiple-documents', action='store_true', |
| 41 | + ) |
| 42 | + parser.add_argument( |
| 43 | + '--unsafe', action='store_true', |
| 44 | + help=( |
| 45 | + 'Instead of loading the files, simply parse them for syntax. ' |
| 46 | + 'A syntax-only check enables extensions and unsafe contstructs ' |
| 47 | + 'which would otherwise be forbidden. Using this option removes ' |
| 48 | + 'all guarantees of portability to other yaml implementations. ' |
| 49 | + 'Implies --allow-multiple-documents' |
| 50 | + ), |
24 | 51 | ) |
25 | 52 | parser.add_argument('filenames', nargs='*', help='Yaml filenames to check.') |
26 | 53 | args = parser.parse_args(argv) |
27 | 54 |
|
| 55 | + load_fn = LOAD_FNS[Key(multi=args.multi, unsafe=args.unsafe)] |
| 56 | + |
28 | 57 | retval = 0 |
29 | 58 | for filename in args.filenames: |
30 | 59 | try: |
31 | | - args.yaml_load_fn(open(filename), Loader=Loader) |
| 60 | + load_fn(open(filename), Loader=Loader) |
32 | 61 | except yaml.YAMLError as exc: |
33 | 62 | print(exc) |
34 | 63 | retval = 1 |
|
0 commit comments