docs: fix issues with src/scripts/fts.py
[vpp.git] / src / scripts / fts.py
1 #!/usr/bin/env python3
2
3 import sys
4 import os
5 import ipaddress
6 import yaml
7 from pprint import pprint
8 import re
9 from jsonschema import validate
10 import argparse
11 from subprocess import run, PIPE
12
13 # VPP feature JSON schema
14 schema = {
15     "$schema": "http://json-schema.org/schema#",
16     "type": "object",
17     "properties": {
18         "name": {"type": "string"},
19         "description": {"type": "string"},
20         "maintainer": {"type": "string"},
21         "state": {"type": "string",
22                   "enum": ["production", "experimental"]},
23         "features": {"$ref": "#/definitions/features"},
24         "missing": {"$ref": "#/definitions/features"},
25         "properties": {"type": "array",
26                        "items": {"type": "string",
27                                  "enum": ["API", "CLI", "STATS",
28                                           "MULTITHREAD"]},
29                        },
30     },
31     "additionalProperties": False,
32     "definitions": {
33         "featureobject": {
34             "type": "object",
35             "patternProperties": {
36                 "^.*$": {"$ref": "#/definitions/features"},
37             },
38         },
39         "features": {
40             "type": "array",
41             "items": {"anyOf": [{"$ref": "#/definitions/featureobject"},
42                                 {"type": "string"},
43                                 ]},
44             "minItems": 1,
45         },
46     },
47 }
48
49
50 def filelist_from_git_status():
51     filelist = []
52     git_status = 'git status --porcelain */FEATURE.yaml'
53     rv = run(git_status.split(), stdout=PIPE, stderr=PIPE)
54     if rv.returncode != 0:
55         sys.exit(rv.returncode)
56
57     for l in rv.stdout.decode('ascii').split('\n'):
58         if len(l):
59             filelist.append(l.split()[1])
60     return filelist
61
62
63 def filelist_from_git_ls():
64     filelist = []
65     git_ls = 'git ls-files :(top)*/FEATURE.yaml'
66     rv = run(git_ls.split(), stdout=PIPE, stderr=PIPE)
67     if rv.returncode != 0:
68         sys.exit(rv.returncode)
69
70     for l in rv.stdout.decode('ascii').split('\n'):
71         if len(l):
72             filelist.append(l)
73     return filelist
74
75
76 def output_features(indent, fl):
77     for f in fl:
78         if type(f) is dict:
79             for k, v in f.items():
80                 print('{}- {}'.format(' ' * indent, k))
81                 output_features(indent + 2, v)
82         else:
83             print('{}- {}'.format(' ' * indent, f))
84
85
86 def output_markdown(features):
87     for k, v in features.items():
88         print('# {}'.format(v['name']))
89         print('Maintainer: {}  '.format(v['maintainer']))
90         print('State: {}\n'.format(v['state']))
91         print('{}\n'.format(v['description']))
92         output_features(0, v['features'])
93         if 'missing' in v:
94             print('\n## Missing')
95             output_features(0, v['missing'])
96         print()
97
98
99 def main():
100     parser = argparse.ArgumentParser(description='VPP Feature List.')
101     parser.add_argument('--validate', dest='validate', action='store_true',
102                         help='validate the FEATURE.yaml file')
103     parser.add_argument('--git-status', dest='git_status', action='store_true',
104                         help='Get filelist from git status')
105     parser.add_argument('--all', dest='all', action='store_true',
106                         help='Validate all files in repository')
107     parser.add_argument('--markdown', dest='markdown', action='store_true',
108                         help='Output feature table in markdown')
109     parser.add_argument('infile', nargs='?', type=argparse.FileType('r'),
110                         default=sys.stdin)
111     args = parser.parse_args()
112
113     features = {}
114
115     if args.git_status:
116         filelist = filelist_from_git_status()
117     elif args.all:
118         filelist = filelist_from_git_ls()
119     else:
120         filelist = args.infile
121
122     for featurefile in filelist:
123         featurefile = featurefile.rstrip()
124
125         # Load configuration file
126         with open(featurefile) as f:
127             cfg = yaml.load(f, Loader=yaml.SafeLoader)
128         validate(instance=cfg, schema=schema)
129         features[featurefile] = cfg
130
131     if args.markdown:
132         output_markdown(features)
133
134
135 if __name__ == '__main__':
136     main()