7 from pprint import pprint
9 from jsonschema import validate
11 from subprocess import run, PIPE
13 # VPP feature JSON schema
15 "$schema": "http://json-schema.org/schema#",
18 "name": {"type": "string"},
19 "description": {"type": "string"},
20 "maintainer": {"$ref": "#/definitions/maintainers"},
21 "state": {"type": "string",
22 "enum": ["production", "experimental", "development"]},
23 "features": {"$ref": "#/definitions/features"},
24 "missing": {"$ref": "#/definitions/features"},
25 "properties": {"type": "array",
26 "items": {"type": "string",
27 "enum": ["API", "CLI", "STATS",
31 "additionalProperties": False,
36 "items": {"type": "string"},
43 "patternProperties": {
44 "^.*$": {"$ref": "#/definitions/features"},
49 "items": {"anyOf": [{"$ref": "#/definitions/featureobject"},
58 def filelist_from_git_status():
60 git_status = 'git status --porcelain */FEATURE.yaml'
61 rv = run(git_status.split(), stdout=PIPE, stderr=PIPE)
62 if rv.returncode != 0:
63 sys.exit(rv.returncode)
65 for l in rv.stdout.decode('ascii').split('\n'):
67 filelist.append(l.split()[1])
71 def filelist_from_git_ls():
73 git_ls = 'git ls-files :(top)*/FEATURE.yaml'
74 rv = run(git_ls.split(), stdout=PIPE, stderr=PIPE)
75 if rv.returncode != 0:
76 sys.exit(rv.returncode)
78 for l in rv.stdout.decode('ascii').split('\n'):
84 def output_features(indent, fl):
87 for k, v in f.items():
88 print('{}- {}'.format(' ' * indent, k))
89 output_features(indent + 2, v)
91 print('{}- {}'.format(' ' * indent, f))
94 def output_markdown(features):
95 for k, v in features.items():
96 print('# {}'.format(v['name']))
97 if type(v['maintainer']) is list:
98 print('Maintainers: ' +
99 ', '.join('{}'.format(m) for m in v['maintainer']))
101 print('Maintainer: {} '.format(v['maintainer']))
102 print('State: {}\n'.format(v['state']))
103 print('{}\n'.format(v['description']))
104 output_features(0, v['features'])
106 print('\n## Missing')
107 output_features(0, v['missing'])
112 parser = argparse.ArgumentParser(description='VPP Feature List.')
113 parser.add_argument('--validate', dest='validate', action='store_true',
114 help='validate the FEATURE.yaml file')
115 parser.add_argument('--git-status', dest='git_status', action='store_true',
116 help='Get filelist from git status')
117 parser.add_argument('--all', dest='all', action='store_true',
118 help='Validate all files in repository')
119 parser.add_argument('--markdown', dest='markdown', action='store_true',
120 help='Output feature table in markdown')
121 parser.add_argument('infile', nargs='?', type=argparse.FileType('r'),
123 args = parser.parse_args()
128 filelist = filelist_from_git_status()
130 filelist = filelist_from_git_ls()
132 filelist = args.infile
134 for featurefile in filelist:
135 featurefile = featurefile.rstrip()
137 # Load configuration file
138 with open(featurefile) as f:
139 cfg = yaml.load(f, Loader=yaml.SafeLoader)
140 validate(instance=cfg, schema=schema)
141 features[featurefile] = cfg
144 output_markdown(features)
147 if __name__ == '__main__':