X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fscripts%2Ffts.py;h=e8ff477c7887f6fb40f48e26750c8435548a4f94;hb=d9b0c6fbf7aa5bd9af84264105b39c82028a4a29;hp=f2b877fb2c7062811f7b3025e0ca9d107749e904;hpb=f90348bcb4afd0af2611cefc43b17ef3042b511c;p=vpp.git diff --git a/src/scripts/fts.py b/src/scripts/fts.py index f2b877fb2c7..e8ff477c788 100755 --- a/src/scripts/fts.py +++ b/src/scripts/fts.py @@ -21,25 +21,28 @@ schema = { "name": {"type": "string"}, "description": {"type": "string"}, "maintainer": {"$ref": "#/definitions/maintainers"}, - "state": {"type": "string", - "enum": ["production", "experimental", "development"]}, + "state": { + "type": "string", + "enum": ["production", "experimental", "development"], + }, "features": {"$ref": "#/definitions/features"}, "missing": {"$ref": "#/definitions/features"}, - "properties": {"type": "array", - "items": {"type": "string", - "enum": ["API", "CLI", "STATS", - "MULTITHREAD"]}, - }, + "properties": { + "type": "array", + "items": {"type": "string", "enum": ["API", "CLI", "STATS", "MULTITHREAD"]}, + }, }, "additionalProperties": False, "definitions": { "maintainers": { - "anyof": [{ - "type": "array", - "items": {"type": "string"}, - "minItems": 1, - }, - {"type": "string"}], + "anyof": [ + { + "type": "array", + "items": {"type": "string"}, + "minItems": 1, + }, + {"type": "string"}, + ], }, "featureobject": { "type": "object", @@ -49,9 +52,12 @@ schema = { }, "features": { "type": "array", - "items": {"anyOf": [{"$ref": "#/definitions/featureobject"}, - {"type": "string"}, - ]}, + "items": { + "anyOf": [ + {"$ref": "#/definitions/featureobject"}, + {"type": "string"}, + ] + }, "minItems": 1, }, }, @@ -59,14 +65,15 @@ schema = { DEFAULT_REPO_LINK = "https://github.com/FDio/vpp/blob/master/" + def filelist_from_git_status(): filelist = [] - git_status = 'git status --porcelain */FEATURE*.yaml' + git_status = "git status --porcelain */FEATURE*.yaml" rv = run(git_status.split(), stdout=PIPE, stderr=PIPE) if rv.returncode != 0: sys.exit(rv.returncode) - for l in rv.stdout.decode('ascii').split('\n'): + for l in rv.stdout.decode("ascii").split("\n"): if len(l): filelist.append(l.split()[1]) return filelist @@ -74,24 +81,26 @@ def filelist_from_git_status(): def filelist_from_git_ls(): filelist = [] - git_ls = 'git ls-files :(top)*/FEATURE*.yaml' + git_ls = "git ls-files :(top)*/FEATURE*.yaml" rv = run(git_ls.split(), stdout=PIPE, stderr=PIPE) if rv.returncode != 0: sys.exit(rv.returncode) - for l in rv.stdout.decode('ascii').split('\n'): + for l in rv.stdout.decode("ascii").split("\n"): if len(l): filelist.append(l) return filelist + def version_from_git(): - git_describe = 'git describe' + git_describe = "git describe" rv = run(git_describe.split(), stdout=PIPE, stderr=PIPE) if rv.returncode != 0: sys.exit(rv.returncode) - return rv.stdout.decode('ascii').split('\n')[0] + return rv.stdout.decode("ascii").split("\n")[0] + -class MarkDown(): +class MarkDown: _dispatch = {} def __init__(self, stream): @@ -101,102 +110,115 @@ class MarkDown(): def print_maintainer(self, o): write = self.stream.write if type(o) is list: - write('Maintainers: ' + - ', '.join('{m}'.format(m=m) for m in - o) + ' \n') + write("Maintainers: " + ", ".join("{m}".format(m=m) for m in o) + " \n") else: - write('Maintainer: {o} \n'.format(o=o)) + write("Maintainer: {o} \n".format(o=o)) - _dispatch['maintainer'] = print_maintainer + _dispatch["maintainer"] = print_maintainer def print_features(self, o, indent=0): write = self.stream.write for f in o: - indentstr = ' ' * indent + indentstr = " " * indent if type(f) is dict: for k, v in f.items(): - write('{indentstr}- {k}\n'.format(indentstr=indentstr, k=k)) + write("{indentstr}- {k}\n".format(indentstr=indentstr, k=k)) self.print_features(v, indent + 2) else: - write('{indentstr}- {f}\n'.format(indentstr=indentstr, f=f)) - write('\n') - _dispatch['features'] = print_features + write("{indentstr}- {f}\n".format(indentstr=indentstr, f=f)) + write("\n") + + _dispatch["features"] = print_features def print_markdown_header(self, o): write = self.stream.write - write('## {o}\n'.format(o=o)) - _dispatch['markdown_header'] = print_markdown_header + write("## {o}\n".format(o=o)) + + _dispatch["markdown_header"] = print_markdown_header def print_name(self, o): write = self.stream.write - write('### {o}\n'.format(o=o)) + write("### {o}\n".format(o=o)) self.toc.append(o) - _dispatch['name'] = print_name + + _dispatch["name"] = print_name def print_description(self, o): write = self.stream.write - write('\n{o}\n\n'.format(o=o)) - _dispatch['description'] = print_description + write("\n{o}\n\n".format(o=o)) + + _dispatch["description"] = print_description def print_state(self, o): write = self.stream.write - write('Feature maturity level: {o} \n'.format(o=o)) - _dispatch['state'] = print_state + write("Feature maturity level: {o} \n".format(o=o)) + + _dispatch["state"] = print_state def print_properties(self, o): write = self.stream.write - write('Supports: {s} \n'.format(s=" ".join(o))) - _dispatch['properties'] = print_properties + write("Supports: {s} \n".format(s=" ".join(o))) + + _dispatch["properties"] = print_properties def print_missing(self, o): write = self.stream.write - write('\nNot yet implemented: \n') + write("\nNot yet implemented: \n") self.print_features(o) - _dispatch['missing'] = print_missing + + _dispatch["missing"] = print_missing def print_code(self, o): write = self.stream.write - write('Source Code: [{o}]({o}) \n'.format(o=o)) - _dispatch['code'] = print_code + write("Source Code: [{o}]({o}) \n".format(o=o)) + + _dispatch["code"] = print_code def print(self, t, o): write = self.stream.write if t in self._dispatch: - self._dispatch[t](self, o,) + self._dispatch[t]( + self, + o, + ) else: - write('NOT IMPLEMENTED: {t}\n') + write("NOT IMPLEMENTED: {t}\n") + def output_toc(toc, stream): write = stream.write - write('# VPP Supported Features\n') + write("# VPP Supported Features\n") for t in toc: - ref = t.lower().replace(' ', '-') - write('[{t}](#{ref}) \n'.format(t=t, ref=ref)) + ref = t.lower().replace(" ", "-") + write("[{t}](#{ref}) \n".format(t=t, ref=ref)) + def featuresort(k): - return k[1]['name'] + return k[1]["name"] + def featurelistsort(k): orderedfields = { - 'name': 0, - 'maintainer': 1, - 'description': 2, - 'features': 3, - 'state': 4, - 'properties': 5, - 'missing': 6, - 'code': 7, + "name": 0, + "maintainer": 1, + "description": 2, + "features": 3, + "state": 4, + "properties": 5, + "missing": 6, + "code": 7, } return orderedfields[k[0]] + def output_markdown(features, fields, notfields, repository_url): stream = StringIO() m = MarkDown(stream) - m.print('markdown_header', 'Feature Details:') + m.print("markdown_header", "Feature Details:") for path, featuredef in sorted(features.items(), key=featuresort): codeurl = urllib.parse.urljoin(repository_url, os.path.dirname(path)) - featuredef['code'] = codeurl + featuredef["code"] = codeurl for k, v in sorted(featuredef.items(), key=featurelistsort): if notfields: if k not in notfields: @@ -211,24 +233,45 @@ def output_markdown(features, fields, notfields, repository_url): output_toc(m.toc, tocstream) return tocstream, stream + def main(): - parser = argparse.ArgumentParser(description='VPP Feature List.') - parser.add_argument('--validate', dest='validate', action='store_true', - help='validate the FEATURE.yaml file') - parser.add_argument("--repolink", metavar="repolink", default=DEFAULT_REPO_LINK, - help="Link to public repository [%s]" % - DEFAULT_REPO_LINK) - parser.add_argument('--git-status', dest='git_status', action='store_true', - help='Get filelist from git status') - parser.add_argument('--all', dest='all', action='store_true', - help='Validate all files in repository') - parser.add_argument('--markdown', dest='markdown', action='store_true', - help='Output feature table in markdown') - parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), - default=sys.stdin) + parser = argparse.ArgumentParser(description="VPP Feature List.") + parser.add_argument( + "--validate", + dest="validate", + action="store_true", + help="validate the FEATURE.yaml file", + ) + parser.add_argument( + "--repolink", + metavar="repolink", + default=DEFAULT_REPO_LINK, + help="Link to public repository [%s]" % DEFAULT_REPO_LINK, + ) + parser.add_argument( + "--git-status", + dest="git_status", + action="store_true", + help="Get filelist from git status", + ) + parser.add_argument( + "--all", + dest="all", + action="store_true", + help="Validate all files in repository", + ) + parser.add_argument( + "--markdown", + dest="markdown", + action="store_true", + help="Output feature table in markdown", + ) + parser.add_argument( + "infile", nargs="?", type=argparse.FileType("r"), default=sys.stdin + ) group = parser.add_mutually_exclusive_group() - group.add_argument('--include', help='List of fields to include') - group.add_argument('--exclude', help='List of fields to exclude') + group.add_argument("--include", help="List of fields to include") + group.add_argument("--exclude", help="List of fields to exclude") args = parser.parse_args() features = {} @@ -240,11 +283,11 @@ def main(): filelist = args.infile if args.include: - fields = args.include.split(',') + fields = args.include.split(",") else: fields = [] if args.exclude: - notfields = args.exclude.split(',') + notfields = args.exclude.split(",") else: notfields = [] @@ -252,13 +295,15 @@ def main(): featurefile = featurefile.rstrip() # Load configuration file - with open(featurefile, encoding='utf-8') as f: + with open(featurefile, encoding="utf-8") as f: cfg = yaml.load(f, Loader=yaml.SafeLoader) try: validate(instance=cfg, schema=schema) except exceptions.ValidationError: - print('File does not validate: {featurefile}' \ - .format(featurefile=featurefile), file=sys.stderr) + print( + "File does not validate: {featurefile}".format(featurefile=featurefile), + file=sys.stderr, + ) raise features[featurefile] = cfg @@ -270,5 +315,5 @@ def main(): stream.close() -if __name__ == '__main__': +if __name__ == "__main__": main()