You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@yetus.apache.org by aw...@apache.org on 2016/03/21 15:48:40 UTC
yetus git commit: YETUS-237. shelldocs should pass pylint
Repository: yetus
Updated Branches:
refs/heads/master 8fbdc79c0 -> 7b83fd81e
YETUS-237. shelldocs should pass pylint
Signed-off-by: Sean Busbey <bu...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/yetus/repo
Commit: http://git-wip-us.apache.org/repos/asf/yetus/commit/7b83fd81
Tree: http://git-wip-us.apache.org/repos/asf/yetus/tree/7b83fd81
Diff: http://git-wip-us.apache.org/repos/asf/yetus/diff/7b83fd81
Branch: refs/heads/master
Commit: 7b83fd81ef9848cb060461dae9df27772f88a955
Parents: 8fbdc79
Author: Allen Wittenauer <aw...@apache.org>
Authored: Sun Mar 20 13:16:50 2016 -0700
Committer: Allen Wittenauer <aw...@apache.org>
Committed: Mon Mar 21 07:48:27 2016 -0700
----------------------------------------------------------------------
shelldocs/shelldocs.py | 601 ++++++++++++++++++++++++--------------------
1 file changed, 329 insertions(+), 272 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/yetus/blob/7b83fd81/shelldocs/shelldocs.py
----------------------------------------------------------------------
diff --git a/shelldocs/shelldocs.py b/shelldocs/shelldocs.py
index 6b0b94f..e575add 100755
--- a/shelldocs/shelldocs.py
+++ b/shelldocs/shelldocs.py
@@ -18,10 +18,9 @@
import os
import re
import sys
-import string
from optparse import OptionParser
-asflicense='''
+ASFLICENSE = '''
<!---
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
@@ -41,280 +40,338 @@ asflicense='''
-->
'''
-def docstrip(key,string):
- string=re.sub("^## @%s " % key ,"",string)
- string=string.lstrip()
- string=string.rstrip()
- return string
-
-def toc(list):
- tocout=[]
- header=()
- for i in list:
- if header != i.getinter():
- header=i.getinter()
- line=" * %s\n" % (i.headerbuild())
- tocout.append(line)
- line=" * [%s](#%s)\n" % (i.getname().replace("_","\_"),i.getname())
- tocout.append(line)
- return tocout
-
-class ShellFunction:
- def __init__(self):
- self.reset()
-
- def __cmp__(self,other):
- if (self.audience == other.audience):
- if (self.stability == other.stability):
- if (self.replaceb == other.replaceb):
- return(cmp(self.name,other.name))
+
+def docstrip(key, dstr):
+ '''remove extra spaces from shelldoc phrase'''
+ dstr = re.sub("^## @%s " % key, "", dstr)
+ dstr = dstr.lstrip()
+ dstr = dstr.rstrip()
+ return dstr
+
+
+def toc(tlist):
+ '''build a table of contents'''
+ tocout = []
+ header = ()
+ for i in tlist:
+ if header != i.getinter():
+ header = i.getinter()
+ line = " * %s\n" % (i.headerbuild())
+ tocout.append(line)
+ line = " * [%s](#%s)\n" % (i.getname().replace("_", r"\_"),
+ i.getname())
+ tocout.append(line)
+ return tocout
+
+
+class ShellFunction(object):
+ """a shell function"""
+ def __init__(self):
+ '''Initializer'''
+ self.name = None
+ self.audience = None
+ self.stability = None
+ self.replaceb = None
+ self.returnt = None
+ self.desc = None
+ self.params = None
+
+ def __cmp__(self, other):
+ '''comparison'''
+ if self.audience == other.audience:
+ if self.stability == other.stability:
+ if self.replaceb == other.replaceb:
+ return cmp(self.name, other.name)
+ else:
+ if self.replaceb == "Yes":
+ return -1
+ else:
+ if self.stability == "Stable":
+ return -1
else:
- if (self.replaceb == "Yes"):
- return -1
- else:
- return 1
- else:
- if (self.stability == "Stable"):
- return -1
- else:
- return 1
- else:
- if (self.audience == "Public"):
- return -1
- else:
+ if self.audience == "Public":
+ return -1
return 1
- def reset(self):
- self.name=None
- self.audience=None
- self.stability=None
- self.replaceb=None
- self.returnt=None
- self.desc=None
- self.params=None
-
- def setname(self,text):
- definition=text.split();
- self.name=definition[1]
-
- def getname(self):
- if (self.name is None):
- return "None"
- else:
- return self.name
-
- def setaudience(self,text):
- self.audience=docstrip("audience",text)
- self.audience=self.audience.capitalize()
-
- def getaudience(self):
- if (self.audience is None):
- return "None"
- else:
- return self.audience
-
- def setstability(self,text):
- self.stability=docstrip("stability",text)
- self.stability=self.stability.capitalize()
-
- def getstability(self):
- if (self.stability is None):
- return "None"
- else:
- return self.stability
-
- def setreplace(self,text):
- self.replaceb=docstrip("replaceable",text)
- self.replaceb=self.replaceb.capitalize()
-
- def getreplace(self):
- if self.replaceb == "Yes":
- return self.replaceb
- else:
- return "No"
-
- def getinter(self):
- return ((self.getaudience(), self.getstability(), self.getreplace()))
-
- def addreturn(self,text):
- if (self.returnt is None):
- self.returnt = []
- self.returnt.append(docstrip("return",text))
-
- def getreturn(self):
- if (self.returnt is None):
- return "Nothing"
- else:
- return "\n\n".join(self.returnt)
-
- def adddesc(self,text):
- if (self.desc is None):
- self.desc = []
- self.desc.append(docstrip("description",text))
-
- def getdesc(self):
- if (self.desc is None):
- return "None"
- else:
- return " ".join(self.desc)
-
- def addparam(self,text):
- if (self.params is None):
- self.params = []
- self.params.append(docstrip("param",text))
-
- def getparams(self):
- if (self.params is None):
- return ""
- else:
- return " ".join(self.params)
-
- def getusage(self):
- line="%s %s" % (self.name, self.getparams())
- return line.rstrip()
-
- def headerbuild(self):
- if self.getreplace() == "Yes":
- replacetext="Replaceable"
- else:
- replacetext="Not Replaceable"
- line="%s/%s/%s" % (self.getaudience(), self.getstability(), replacetext)
- return(line)
-
- def getdocpage(self):
- line="### `%s`\n\n"\
- "* Synopsis\n\n"\
- "```\n%s\n"\
- "```\n\n" \
- "* Description\n\n" \
- "%s\n\n" \
- "* Returns\n\n" \
- "%s\n\n" \
- "| Classification | Level |\n" \
- "| :--- | :--- |\n" \
- "| Audience | %s |\n" \
- "| Stability | %s |\n" \
- "| Replaceable | %s |\n\n" \
- % (self.getname(),
- self.getusage(),
- self.getdesc(),
- self.getreturn(),
- self.getaudience(),
- self.getstability(),
- self.getreplace())
- return line
-
- def lint(self):
- getfuncs = {
- "audience" : self.getaudience,
- "stability" : self.getstability,
- "replaceable" : self.getreplace,
- }
- validvalues = {
- "audience" : ("Public", "Private"),
- "stability" : ("Stable", "Evolving"),
- "replaceable" : ("Yes", "No"),
- }
- messages = []
- for attr in ("audience", "stability", "replaceable"):
- value = getfuncs[attr]()
- if value == "None":
- messages.append("ERROR: function %s has no @%s" % (self.getname(), attr.lower()))
- elif value not in validvalues[attr]:
- validvalue = "|".join(v.lower() for v in validvalues[attr])
- messages.append("ERROR: function %s has invalid value (%s) for @%s (%s)" %
- (self.getname(), value.lower(), attr.lower(), validvalue))
- return "\n".join(messages)
-
- def __str__(self):
- line="{%s %s %s %s}" \
- % (self.getname(),
- self.getaudience(),
- self.getstability(),
- self.getreplace())
- return line
+ def reset(self):
+ '''empties current function'''
+ self.name = None
+ self.audience = None
+ self.stability = None
+ self.replaceb = None
+ self.returnt = None
+ self.desc = None
+ self.params = None
+
+ def setname(self, text):
+ '''set the name of the function'''
+ definition = text.split()
+ self.name = definition[1]
+
+ def getname(self):
+ '''get the name of the function'''
+ if self.name is None:
+ return "None"
+ else:
+ return self.name
+
+ def setaudience(self, text):
+ '''set the audience of the function'''
+ self.audience = docstrip("audience", text)
+ self.audience = self.audience.capitalize()
+
+ def getaudience(self):
+ '''get the audience of the function'''
+ if self.audience is None:
+ return "None"
+ else:
+ return self.audience
+
+ def setstability(self, text):
+ '''set the stability of the function'''
+ self.stability = docstrip("stability", text)
+ self.stability = self.stability.capitalize()
+
+ def getstability(self):
+ '''get the stability of the function'''
+ if self.stability is None:
+ return "None"
+ else:
+ return self.stability
+
+ def setreplace(self, text):
+ '''set the replacement state'''
+ self.replaceb = docstrip("replaceable", text)
+ self.replaceb = self.replaceb.capitalize()
+
+ def getreplace(self):
+ '''get the replacement state'''
+ if self.replaceb == "Yes":
+ return self.replaceb
+ else:
+ return "No"
+
+ def getinter(self):
+ '''get the function state'''
+ return self.getaudience(), self.getstability(), self.getreplace()
+
+ def addreturn(self, text):
+ '''add a return state'''
+ if self.returnt is None:
+ self.returnt = []
+ self.returnt.append(docstrip("return", text))
+
+ def getreturn(self):
+ '''get the complete return state'''
+ if self.returnt is None:
+ return "Nothing"
+ else:
+ return "\n\n".join(self.returnt)
+
+ def adddesc(self, text):
+ '''add to the description'''
+ if self.desc is None:
+ self.desc = []
+ self.desc.append(docstrip("description", text))
+
+ def getdesc(self):
+ '''get the description'''
+ if self.desc is None:
+ return "None"
+ else:
+ return " ".join(self.desc)
+
+ def addparam(self, text):
+ '''add a parameter'''
+ if self.params is None:
+ self.params = []
+ self.params.append(docstrip("param", text))
+
+ def getparams(self):
+ '''get all of the parameters'''
+ if self.params is None:
+ return ""
+ else:
+ return " ".join(self.params)
+
+ def getusage(self):
+ '''get the usage string'''
+ line = "%s %s" % (self.name, self.getparams())
+ return line.rstrip()
+
+ def headerbuild(self):
+ '''get the header for this function'''
+ if self.getreplace() == "Yes":
+ replacetext = "Replaceable"
+ else:
+ replacetext = "Not Replaceable"
+ line = "%s/%s/%s" % (self.getaudience(), self.getstability(),
+ replacetext)
+ return line
+
+ def getdocpage(self):
+ '''get the built document page for this function'''
+ line = "### `%s`\n\n"\
+ "* Synopsis\n\n"\
+ "```\n%s\n"\
+ "```\n\n" \
+ "* Description\n\n" \
+ "%s\n\n" \
+ "* Returns\n\n" \
+ "%s\n\n" \
+ "| Classification | Level |\n" \
+ "| :--- | :--- |\n" \
+ "| Audience | %s |\n" \
+ "| Stability | %s |\n" \
+ "| Replaceable | %s |\n\n" \
+ % (self.getname(),
+ self.getusage(),
+ self.getdesc(),
+ self.getreturn(),
+ self.getaudience(),
+ self.getstability(),
+ self.getreplace())
+ return line
+
+ def lint(self):
+ '''Lint this function'''
+ getfuncs = {
+ "audience": self.getaudience,
+ "stability": self.getstability,
+ "replaceable": self.getreplace,
+ }
+ validvalues = {
+ "audience": ("Public", "Private"),
+ "stability": ("Stable", "Evolving"),
+ "replaceable": ("Yes", "No"),
+ }
+ messages = []
+ for attr in ("audience", "stability", "replaceable"):
+ value = getfuncs[attr]()
+ if value == "None":
+ messages.append("ERROR: function %s has no @%s" %
+ (self.getname(), attr.lower()))
+ elif value not in validvalues[attr]:
+ validvalue = "|".join(v.lower() for v in validvalues[attr])
+ messages.append(
+ "ERROR: function %s has invalid value (%s) for @%s (%s)" %
+ (self.getname(), value.lower(), attr.lower(), validvalue))
+ return "\n".join(messages)
+
+ def __str__(self):
+ '''Generate a string for this function'''
+ line = "{%s %s %s %s}" \
+ % (self.getname(),
+ self.getaudience(),
+ self.getstability(),
+ self.getreplace())
+ return line
+
def main():
- parser=OptionParser(usage="usage: %prog [--skipprnorep] --output OUTFILE --input INFILE [--input INFILE ...]")
- parser.add_option("-o","--output", dest="outfile",
- action="store", type="string",
- help="file to create", metavar="OUTFILE")
- parser.add_option("-i","--input", dest="infile",
- action="append", type="string",
- help="file to read", metavar="INFILE")
- parser.add_option("--skipprnorep", dest="skipprnorep",
- action="store_true", help="Skip Private & Not Replaceable")
- parser.add_option("--lint", dest="lint",
- action="store_true", help="Enable lint mode")
- parser.add_option("-V", "--version", dest="release_version", action="store_true", default=False,
- help="display version information for shelldocs and exit.")
-
- (options, args)=parser.parse_args()
-
- if options.release_version:
- with open(os.path.join(os.path.dirname(__file__), "../VERSION"), 'r') as ver_file:
- print ver_file.read()
- sys.exit(0)
-
- if options.infile is None:
- parser.error("At least one input file needs to be supplied")
- elif options.outfile is None and options.lint is None:
- parser.error("At least one of output file and lint mode needs to be specified")
-
- allfuncs = []
- try:
- for filename in options.infile:
- with open(filename,"r") as shellcode:
- funcdef = ShellFunction()
- for line in shellcode:
- if line.startswith('## @description'):
- funcdef.adddesc(line)
- elif line.startswith('## @audience'):
- funcdef.setaudience(line)
- elif line.startswith('## @stability'):
- funcdef.setstability(line)
- elif line.startswith('## @replaceable'):
- funcdef.setreplace(line)
- elif line.startswith('## @param'):
- funcdef.addparam(line)
- elif line.startswith('## @return'):
- funcdef.addreturn(line)
- elif line.startswith('function'):
- funcdef.setname(line)
- if options.skipprnorep and \
- funcdef.getaudience() == "Private" and \
- funcdef.getreplace() == "No":
- pass
- else:
- allfuncs.append(funcdef)
- funcdef = ShellFunction()
- except IOError, err:
- print >> sys.stderr, "ERROR: Failed to read from file: %s. Aborting." % err.filename
- sys.exit(1)
-
- allfuncs = sorted(allfuncs)
-
- if options.lint:
- for funcs in allfuncs:
- message = funcs.lint()
- if 0 < len(message):
- print message
-
- if options.outfile is not None:
- with open(options.outfile, "w") as outfile:
- outfile.write(asflicense)
- for line in toc(allfuncs):
- outfile.write(line)
- outfile.write("\n------\n\n")
-
- header = []
- for funcs in allfuncs:
- if header != funcs.getinter():
- header = funcs.getinter()
- line = "## %s\n" % (funcs.headerbuild())
- outfile.write(line)
- outfile.write(funcs.getdocpage())
+ '''main entry point'''
+ parser = OptionParser(
+ usage=
+ "usage: %prog [--skipprnorep] --output OUTFILE --input INFILE [--input INFILE ...]")
+ parser.add_option("-o",
+ "--output",
+ dest="outfile",
+ action="store",
+ type="string",
+ help="file to create",
+ metavar="OUTFILE")
+ parser.add_option("-i",
+ "--input",
+ dest="infile",
+ action="append",
+ type="string",
+ help="file to read",
+ metavar="INFILE")
+ parser.add_option("--skipprnorep",
+ dest="skipprnorep",
+ action="store_true",
+ help="Skip Private & Not Replaceable")
+ parser.add_option("--lint",
+ dest="lint",
+ action="store_true",
+ help="Enable lint mode")
+ parser.add_option(
+ "-V",
+ "--version",
+ dest="release_version",
+ action="store_true",
+ default=False,
+ help="display version information for shelldocs and exit.")
+
+ (options, args) = parser.parse_args()
+
+ if options.release_version:
+ with open(
+ os.path.join(
+ os.path.dirname(__file__), "../VERSION"), 'r') as ver_file:
+ print ver_file.read()
+ sys.exit(0)
+
+ if options.infile is None:
+ parser.error("At least one input file needs to be supplied")
+ elif options.outfile is None and options.lint is None:
+ parser.error(
+ "At least one of output file and lint mode needs to be specified")
+
+ allfuncs = []
+ try:
+ for filename in options.infile:
+ with open(filename, "r") as shellcode:
+ funcdef = ShellFunction()
+ for line in shellcode:
+ if line.startswith('## @description'):
+ funcdef.adddesc(line)
+ elif line.startswith('## @audience'):
+ funcdef.setaudience(line)
+ elif line.startswith('## @stability'):
+ funcdef.setstability(line)
+ elif line.startswith('## @replaceable'):
+ funcdef.setreplace(line)
+ elif line.startswith('## @param'):
+ funcdef.addparam(line)
+ elif line.startswith('## @return'):
+ funcdef.addreturn(line)
+ elif line.startswith('function'):
+ funcdef.setname(line)
+ if options.skipprnorep and \
+ funcdef.getaudience() == "Private" and \
+ funcdef.getreplace() == "No":
+ pass
+ else:
+ allfuncs.append(funcdef)
+ funcdef = ShellFunction()
+ except IOError, err:
+ print >> sys.stderr, "ERROR: Failed to read from file: %s. Aborting." % err.filename
+ sys.exit(1)
+
+ allfuncs = sorted(allfuncs)
+
+ if options.lint:
+ for funcs in allfuncs:
+ message = funcs.lint()
+ if len(message) > 0:
+ print message
+
+ if options.outfile is not None:
+ with open(options.outfile, "w") as outfile:
+ outfile.write(ASFLICENSE)
+ for line in toc(allfuncs):
+ outfile.write(line)
+ outfile.write("\n------\n\n")
+
+ header = []
+ for funcs in allfuncs:
+ if header != funcs.getinter():
+ header = funcs.getinter()
+ line = "## %s\n" % (funcs.headerbuild())
+ outfile.write(line)
+ outfile.write(funcs.getdocpage())
-if __name__ == "__main__":
- main()
+if __name__ == "__main__":
+ main()