lint.py
Go to the documentation of this file.
00001 """
00002 The lint command lints a package.
00003 
00004 Copyright 2015 Fetch Robotics Inc.
00005 Author: Alex Henning
00006 """
00007 
00008 import fnmatch
00009 import os
00010 import subprocess
00011 import sys
00012 
00013 name = "lint"
00014 help_text = "Lint a package in your workspace"
00015 
00016 
00017 def main(args):
00018     # TODO(enhancement): Allow level of detail to be controlled
00019     # TODO(enhancement): Allow catkin_lint to be turned off
00020     # TODO(enhancement): Allow C++ to be turned off
00021     # TODO(enhancement): Allow python to be turned off
00022 
00023     if os.path.isfile(args.package):
00024         print "Linting file %s" % (args.package)
00025         print "-------------" + ("-" * len(args.package)) + "\n"
00026         for ending in cpp_endings:
00027             if args.package.endswith(ending):
00028                 sys.exit(cpplint([args.package]))
00029         if args.package.endswith(".py"):
00030             sys.exit(pep8([args.package]))
00031         print "ERROR: can't lint file"
00032         sys.exit(1)
00033     elif os.path.isdir(args.package):
00034         print "Linting directory %s" % (args.package)
00035         print "------------------" + ("-" * len(args.package)) + "\n"
00036         sys.exit(lint_directory(args.package))
00037     else:
00038         print "Linting package %s" % (args.package)
00039         print "----------------" + ("-" * len(args.package)) + "\n"
00040         sys.exit(lint_package(args.package))
00041 
00042 
00043 def add_arguments(parser):
00044     parser.add_argument("package", action="store",
00045                         metavar="FILE|DIRECTORY|PACKAGE",
00046                         help="File, directory or ROS package to lint")
00047 
00048 
00049 def merge(c1, c2):
00050     return c2 if c2 != 0 else c1
00051 
00052 
00053 def lint_package(package):
00054     proc = subprocess.Popen(["catkin_lint", "--pkg", package,
00055                              "-W2", "--explain"])
00056     proc.wait()
00057     if proc.returncode != 0:
00058         print "WARNING: Catkin lint failed"
00059     returncode = proc.returncode
00060     print
00061 
00062     package_directory = subprocess.check_output(["rospack", "find", package]) \
00063                                   .strip()
00064     return merge(lint_directory(package_directory), returncode)
00065 
00066 
00067 def lint_directory(directory):
00068     cpp_files = []
00069     for root, _, filenames in os.walk(directory):
00070         for ending in cpp_endings:
00071             for filename in fnmatch.filter(filenames, "*"+ending):
00072                 cpp_files.append(os.path.join(root, filename))
00073     returncode = cpplint(cpp_files)
00074     print
00075 
00076     py_files = []
00077     for root, _, filenames in os.walk(directory):
00078         for filename in fnmatch.filter(filenames, "*.py"):
00079             py_files.append(os.path.join(root, filename))
00080     returncode = merge(pep8(py_files), returncode)
00081     return returncode
00082 
00083 
00084 cpp_endings = [".c", ".cpp", ".cc", ".h", ".hpp", ".hh"]
00085 
00086 
00087 def cpplint(files):
00088     if files:
00089         proc = subprocess.Popen([
00090             "/opt/ros/indigo/lib/roslint/cpplint",
00091             "--counting=detailed",
00092             "--filter=+,-runtime/references,-runtime/threadsafe_fn",
00093         ] + files)
00094         proc.wait()
00095         if proc.returncode != 0:
00096             print "WARNING: C++ lint failed"
00097         return proc.returncode
00098     return 0
00099 
00100 
00101 def pep8(files):
00102     acceptable = [
00103         "R0902",  # Allow for many class attributes.
00104         "C0111",  # Docstrings in ## style (required by Doxygen) are not.
00105                   # recognized, so ignore warning that they are missing.
00106         "C0103",  # Allows 'constant' names to be lower case. This is normal
00107                   # in the if __name__ == '__main__' block.
00108         "C0325",  # Don't complain about print() vs print.
00109         "W0142",  # ** arguments are ok. Just a little "magic".
00110         "R0913",  # Allow for more than 4 arguments to _init__.
00111         "R0903",  # Allow classes to have one or two public methods.
00112         "E266",   # Allow comments to start with "## " for doxygen
00113     ]
00114     if files:
00115         proc = subprocess.Popen([
00116             "/opt/ros/indigo/lib/roslint/pep8",
00117             "--ignore=" + ",".join(acceptable),
00118             "--statistics",
00119             "--count"
00120         ] + files)
00121         proc.wait()
00122         if proc.returncode != 0:
00123             print "WARNING: Python lint failed"
00124         return proc.returncode
00125     return 0


fetch_tools
Author(s): Alex Henning
autogenerated on Thu Jun 6 2019 21:10:20