Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ament{_cmake,}_yamllint packages #351

Open
wants to merge 1 commit into
base: rolling
Choose a base branch
from
Open

Conversation

cottsay
Copy link
Contributor

@cottsay cottsay commented Jan 25, 2022

The yamllint tool is widely used to validate YAML style. This change adds ament_lint support for that tool.

At present, the ament_lint_auto glue for ament_cmake_yamllint is omitted. We'll need to clean up all of the violations across the
codebase before we can enable it automatically.

For now, having the tool available may help us prevent further regressions.

Requires: ros2/ci#613

CI:

  • Linux Build Status
  • Linux-aarch64 Build Status
  • Linux-RHEL Build Status
  • Windows Build Status

@cottsay cottsay added the enhancement New feature or request label Jan 25, 2022
@cottsay cottsay self-assigned this Jan 25, 2022
Copy link
Contributor

@clalancette clalancette left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks structurally reasonable. I've left some things to consider fixing in the Python code, but it is really nothing major.

Comment on lines +54 to +55
help='The files or directories to check. For directories files ending '
'in %s will be considered.' %
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
help='The files or directories to check. For directories files ending '
'in %s will be considered.' %
help='The files or directories to check. For each directory only files ending '
'in %s will be considered.' %

(or something like that; having directories files looks weird)

Also, if you list a directory is it searched recursively?

Comment on lines +62 to +63
# not using a file handle directly
# in order to prevent leaving an empty file when something fails early
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear to me what this comment refers to.

for path in paths:
if os.path.isdir(path):
for dirpath, dirnames, filenames in os.walk(path):
if 'AMENT_IGNORE' in dirnames + filenames:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a question, not a statement: should we extend this to honor COLCON_IGNORE as well?

Comment on lines +166 to +168
def invoke_yamllint(files, yamllint_bin=None, config_file=None):
if yamllint_bin is None:
yamllint_bin = find_executable('yamllint')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems unnecessary to have yamllint_bin be an argument here; there are no situations where we use it. I guess I would just remove it and just unconditionally do yamllint_bin = find_executable('yamllint')

Comment on lines +93 to +103
temp_config_fd, temp_config_file = tempfile.mkstemp(suffix='.yaml',
prefix='yamllint_')
with os.fdopen(temp_config_fd, 'w') as f:
yaml.dump(yamllint_config, f)

try:
report = invoke_yamllint(files, config_file=temp_config_file)
except: # noqa: E722
raise
finally:
os.remove(temp_config_file)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this whole thing might be better done with a NamedTemporaryFile in a context. That way we are always sure it is removed, even if yaml.dump, for instance, throws an exception.

Comment on lines +181 to +204
except subprocess.CalledProcessError as e:
if e.stderr:
print(e.stderr.decode())
stdout = e.stdout.decode()
print(stdout, end='')
if not stdout or e.returncode not in (1, 2):
raise
parser = re.compile(r'^(.+):(\d+):(\d+): \[(.+)\] (.*) \((.+)\)$')
for line in stdout.splitlines():
m = parser.match(line)
if not m:
raise ValueError(
'Failed to parse yamllint output: %s' % (line,))
try:
report[m.group(1)].append({
'line': int(m.group(2)),
'col': int(m.group(3)),
'severity': m.group(4),
'msg': m.group(5),
'id': m.group(6),
})
except NameError:
raise ValueError(
'Got failures for unknown file: %s' % (m.group(1),))
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not a huge fan of doing tons of work inside of an exception handler. While Python 3 is far better at dealing with this than Python 2 was, it can still be confusing to read the backtrace where multiple exceptions happened inside of one another. My preferred solution here is to just check what we need to if we intend to re-raise, then save off what we need in the exception handler and continue on. All other work can be done in the "main" context by checking whether any data was saved from the exception handler.

That said, I don't feel that strongly about it, so if you don't think this is worthwhile, I won't block on it.

The yamllint tool is widely used to validate YAML style. This change
adds ament_lint support for that tool.

At present, the ament_lint_auto glue for ament_cmake_yamllint is
omitted. We'll need to clean up all of the violations across the
codebase before we can enable it automatically.

For now, having the tool available may help us prevent further
regressions.

Signed-off-by: Scott K Logan <[email protected]>
@audrow audrow changed the base branch from master to rolling June 28, 2022 14:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants