Git Product home page Git Product logo

roslint's Introduction

roslint

Build Status

Catkin macros which provide standard linter configurations for C++ and Python.

roslint's People

Contributors

alexhenning avatar andriypt avatar arne48 avatar asiron avatar jack-oquin avatar mikepurvis avatar mistoll avatar peci1 avatar sloretz avatar timple avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

roslint's Issues

FIx Differences between ROS Style Guide and Google Style Guide

It looks like roslint's CPP module uses the Google style guide, which is slightly different from ROS's long-standing one (http://wiki.ros.org/CppStyleGuide). Notable items below.

ROS style guide specifies putting opening brace on it's own line, current rules throw:

{ should almost always be at the end of the previous line  [whitespace/braces] [4]
An else should appear on the same line as the preceding }  [whitespace/newline] [4]

Examples, and most of ROS core code put "public:" and similar labels at the beginning of the line. Style guide linked above also shows it this way. Causes the following to be thrown:

Labels should always be indented at least one space.  If this is a member-initializer list in a constructor or the base class list in a class definition, the colon should be on the following line.  [whitespace/labels] [4]

ROS Services use non-const references, causes:

Is this a non-const reference? If so, make const or use a pointer.  [runtime/references] [2]

roslint doesn't seem to check function name style

This is a follow-up from http://answers.ros.org/question/246677

According to the ROS C++ style guide, function names should be camelCased (lower-case first letter), not CamelCased (capital-case first letter). However, roslint doesn't seem to complain about CamelCased function names. Actually, it doesn't complain even if a function name is under_scored ๐Ÿค”

Here's a proof of concept:

void my_silly_test() {
    return;
}

And here's the output of catkin build --no-deps <package> --make-args roslint_<package>:

when starting a new scope, { should be on a line by itself  [whitespace/braces]

It correctly complains about the scope delimiter, but not the function name.

pylint too big

This speaks for itself:

$ sudo apt-get install pylint
Reading package lists... Done
Building dependency tree
Reading state information... Done
The following extra packages will be installed:
  blt libdrm-intel1 libdrm-nouveau2 libdrm-radeon1 libfontenc1 libgl1-mesa-dri libgl1-mesa-glx libglapi-mesa libllvm3.2
  libpciaccess0 libtxc-dxtn-s2tc0 libutempter0 libx11-xcb1 libxcb-dri2-0 libxcb-glx0 libxcb-shape0 libxss1 libxtst6 libxv1
  libxxf86dga1 libxxf86vm1 python-egenix-mxdatetime python-egenix-mxtools python-logilab-astng python-logilab-common python-tk
  tcl8.5 tcl8.5-lib tk8.5 tk8.5-lib x11-utils xbitmaps xterm
Suggested packages:
  blt-demo libglide3 python-egenix-mxdatetime-dbg python-egenix-mxdatetime-doc python-egenix-mxtools-dbg
  python-egenix-mxtools-doc pyro python-unittest2 tix python-tk-dbg tcl-tclreadline mesa-utils xfonts-cyrillic
Recommended packages:
  libtxc-dxtn0
The following NEW packages will be installed:
  blt libdrm-intel1 libdrm-nouveau2 libdrm-radeon1 libfontenc1 libgl1-mesa-dri libgl1-mesa-glx libglapi-mesa libllvm3.2
  libpciaccess0 libtxc-dxtn-s2tc0 libutempter0 libx11-xcb1 libxcb-dri2-0 libxcb-glx0 libxcb-shape0 libxss1 libxtst6 libxv1
  libxxf86dga1 libxxf86vm1 pylint python-egenix-mxdatetime python-egenix-mxtools python-logilab-astng python-logilab-common
  python-tk tcl8.5 tcl8.5-lib tk8.5 tk8.5-lib x11-utils xbitmaps xterm
0 upgraded, 34 newly installed, 0 to remove and 150 not upgraded.
Need to get 17.1 MB of archives.
After this operation, 59.7 MB of additional disk space will be used.
Do you want to continue [Y/n]?

There's no way a linter should require 60MB of stuff. The issue is the dependency on python-logilab-astng, which brings in all kinds of xwindows junk.

Given #2 as well, I think we should swap out pylint for https://pypi.python.org/pypi/pep8

Unnamed function parameter mistaken for a C-style cast

In the following file:

/*********************************************************************
 *  Copyright (c) XXXXX, Inc.
 *********************************************************************/
void *testFunction(void * /*unused_param*/)
{
}

Cpplint returns:

test.cpp:4:  Using C-style cast.  Use reinterpret_cast<void *>(...) instead  [readability/casting] [4]

In cpplint.py here there is already a case to cover this. But the problem is that this condition only gets checked if the line ends (among other things) with the character {, as you can see here.

So that case would be correctly caught if we use

/*********************************************************************
 *  Copyright (c) XXXXX, Inc.
 *********************************************************************/
void *testFunction(void * /*unused_param*/) {
}

but then of course we get an error about the position of the braces.

test.cpp:4:  when starting a new scope, { should be on a line by itself  [whitespace/braces] [4]

cpplint: Erroneously warns for do while loops

cpplint currently doesn't like do while loops and erroneously warns about them. The problem seems to be due to the change in brace styles: https://github.com/ros/roslint/blob/master/src/roslint/cpplint.py#L3130

Given:

// Copyright 2015 Alex Henning

void dowhile()
{
  do
  {
    // Do some stuff
  }
  while (true);
}

Result:

dowhile.cpp:9:  Empty loop bodies should use {} or continue  [whitespace/empty_loop_body] [5]
Done processing dowhile.cpp
Total errors found: 1

Support being passed a path

Right now, the roslint_python and roslint_cpp macros support being passed lists of source files, or nothing, where the "nothing" behaviour is to glob and lint everything in the package. It would be great to be able to specify a path to lint everything below, eg:

roslint_cpp(DIRECTORY include)

Part of this could be supporting an optional corresponding FILES mode, which would be the same as the current behaviour for loose arguments, so the following would be equivalent:

roslint_cpp(FILES src/main.cpp src/foo.cpp)
roslint_cpp(src/main.cpp src/foo.cpp)

In this scenario, the follow calls would also be equivalent:

roslint_cpp(DIRECTORY .)
roslint_cpp()

Implement EXCLUDE

To eliminate files from linting (eg, tests, files which come from elsewhere, etc).

Should support individual files or globs.

cpplint: Erroneously warns about accessors in structs

Accessors for structs should be indented the same as they would in classes (not at all). However, cpplint warns that they should be indented one space. This can likely be updated the same way it was for classes.

Given:

// Copyright 2015 Alex Henning

struct A
{
public:
}

Result:

structs.cpp:5:  public: should be indented +1 space inside struct A  [whitespace/indent] [3]
Done processing structs.cpp
Total errors found: 1

Need to resolve <build_depend> rosdep keys

There are currently no rosdep keys defined for python-pylint or python-cpplint, which are needed to resolve the roslint package build dependencies.

Plus, these probably need to use the transitive <run_depend> instead, since they are needed at build time by packages that depend on roslint. (With package format 2, that will become a <build_export_depend>, see the rep-0140 draft).

Noetic source entry?

It looks like roslint does not have a source entry for Noetic and is directly blocking 54 other repos. Mind adding a source entry for it? Will the noetic release use the master branch?

A source entry signals to other packages it is being worked on, and makes it possible for downstream maintainers to use rosinstall_generator to download their dependencies while they work on Python 3 incompatibilities.

I didn't see any Python 3 syntax errors, and all the tests appeared to pass using Python 3 on Debian Buster. Is roslint already compatible with Python 3?

Better XML generation

As discussed here: 0136f53

Use the python facilities provided by rosunit for this, rather than a template baked into the bash wrapper.

linter for package.xml and CMakeLists.txt

I think we can share some syntaxes for package.xml.

like
CMakeLists.txt

  • alphabetical order for msgs and srvs

package.xml

  • alphabetical order for build_depend and run_depend
  • Order: buildtool_depend -> build_depend -> run_depend -> test_depend

Any idea?

do/while formatting

In my code I have a do/while loop as follows:

do
{
    // do something ....
} while (!msg_received);

I get the following error from lint:

} should be on a line by itself  [whitespace/braces] [4]

But if I move the while statement to a new line, I get the next error:

Empty loop bodies should use {} or continue  [whitespace/empty_loop_body] [5]

Is there anyway to solve this issue?

C++11 bracer-init-list fails to pass

The following code:

server = registerServer("server_name", {State::First, State::Second});

where we pass C++11 bracer-init-list as the second argument fails to pass the CheckBracers. The special case where both bracers happen to be on the same line fails because only one character is expected after the closing bracer }, but in our case we have 2 characters });

def CheckBraces(fn, filename, clean_lines, linenum, error):
""" Complete replacement for cpplint.CheckBraces, since the brace rules for ROS C++ Style
are completely different from the Google style guide ones. """
line = clean_lines.elided[linenum]
if Match(r'^(.*){(.*)}.?$', line):
# Special case when both braces are on the same line together, as is the
# case for one-line getters and setters, for example, or rows of a multi-
# dimenstional array initializer.
pass

Chaninging the line

if Match(r'^(.*){(.*)}.?$', line):

to

if Match(r'^(.*){(.*)}.+$', line): 

would probably solve the issue, but as I am not an expert in writing linters, it could potentially break other stuff.
Any suggestions ?

Impossible brace+paren combo

I need to write some code that uses std::transform, like this:

  std::transform(rows.begin(), rows.end(), std::back_inserter(concepts), [this](const mysqlx::Row & row)
  {
    return Concept(row[0], *this);
  });

This will generate } should be on a line by itself [whitespace/braces] [4]. If I do this though, I'll just get closing ) should be moved to the previous line [whitespace/parens] [2].

XML linter

Check for well-formedness, sane indentation.

Add package.xml checks

It might be useful to add basic checks on the package.xml for a package.

Particularly, I've seen a few packages use <license></license> which doesn't cause any errors, but makes RPM generation fail, and is really against the package.xml format rep: http://www.ros.org/reps/rep-0127.html#license-multiple-but-at-least-one

For the packages who did this, they left it blank because the code was in public domain and was not licensed. I recommended using <license>Public Domain</license>, and all so far have adopted it.

There could also be checks for things such as properly formatted E-mail addresses for authors and maintainers, and properly formatted (and non-empy) URLs.

With the v2 package.xml spec rolling out soon, there will likely be more nuances like this that a lint tool should check.

Great work here!

Store lint output in the build tree

Creating an output file would be useful for users.

Such a target should cause the lint command only to run again when its dependencies change.

Scheme for silencing warnings/errors

Especially important for:

  • situations where a warning is acknowledged, but not actually valid.
  • maintainers who don't have the resources to clean everything up now, but would like to broadly enforce no new violations, particularly in conjunction with using Travis to pre-screen PRs.

CMake linter

Apart from catkin_lint, primarily check for:

  • two-space indentation.
  • lowercase function and macro names.
  • uppercase variable names.

Add option to run linter with tests

For example:

roslint_python(src/mypkg/foo.py AS_TEST lint_python)

We would create the roslint and roslint_mypkg targets as usual, but also create a run_tests_mypkg_lint_python target, depended upon by run_tests. The idea would be that you could optionally have the linter check run as part of the CI's run_tests build.

On the implementation side, we should be able to call catkin_run_tests_target to wire it up, though you need to provide xunit xml output for that; that aspect of this intersects with #9. (And there may need to be transformation stage in there, to coerce the line-by-line output into the requisite XML.)

roslint_cpp default add .hpp suffix

Can roslint_cpp default glob files add .hpp suffix? or add another option for the function?

# Run cpplint on a list of file names.
#
function(roslint_cpp)
if ("${ARGN}" STREQUAL "")
file(GLOB_RECURSE ARGN *.cpp *.h)
endif()
if (NOT DEFINED ROSLINT_CPP_CMD)
set(ROSLINT_CPP_CMD ${ROSLINT_SCRIPTS_DIR}/cpplint)
endif()
roslint_custom("${ROSLINT_CPP_CMD}" "${ROSLINT_CPP_OPTS}" ${ARGN})
endfunction()

roslint_launch

At the very least, could check for valid XML, but perhaps also for deprecated tags, absolute paths, etc.

A LICENSE file missing in the repo

I cannot see the LICENSE file (explicit, including copyright holders and year). This makes it hard to reuse the code from this repo lawfully.

cpplint: Fails to warn about many brackets

The current brace check overlooks many instances of the braces being on the same line. This is due to the fact that in line 99 it suppresses any warnings where there is an = sign on the line. However, this occurs in many common cases:

if (i == 0) {
for (int i = 0; i < 10; i++) {
while (i == 0) {

I think the best fix is to check if the { is preceded by a ) in which case it is likely one of the above. I don't think that would occur with a brace initializer.

@mikepurvis Thoughts?

cpplint: Add testing

Add cpplint tests in order to allow cpplint.py to be updated more confidently.

Header files not in "include" cause roslint to hang

Patched GetHeaderGuardCPPVariable method expects to find "include" in a header file's path. When "include" is not found in the file's path this method hangs in a continuous loop:

    var_parts = list()
    head = filename
    while head:
        head, tail = os.path.split(head)
        var_parts.insert(0, tail)
        if head.endswith('include'):
            break

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.