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

feat: Handle missing yamllint as rule violation #1538

Closed
wants to merge 1 commit into from

Conversation

dosmanak
Copy link

ansible-lint ignores the fact yamllint is not installed. This way, important yaml linting might be missed, because the output does not inform the user, that yamllint is not present.
I made the change so when yamllint is not detected, the ansible-lint will handle it as rule violation so that it can be disabled using .ansible-lint configuration file if necessary.

filename and linenumber are filled arbitrary so it points the code with the text:

# yamllint is a soft-dependency (not installed by default)

@dosmanak dosmanak marked this pull request as draft April 27, 2021 10:33
@dosmanak dosmanak marked this pull request as ready for review April 27, 2021 11:37
@dosmanak
Copy link
Author

The error that occured in the pipeline doesn't seem to be related to my changes.
Even the current version of ansible-lint fails on the repo https://opendev.org/zuul/zuul-jobs.

message="yamllint.config module is not present",
details="Install yamllint package so ansiblelint can invoke it.",
filename="YamllintRule.py",
linenumber=15,
Copy link
Contributor

Choose a reason for hiding this comment

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

Why is this line number here? I would assume that line number is irrelevant if yamllint is not installed.

Copy link
Author

Choose a reason for hiding this comment

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

Please see the PR description.

Copy link
Contributor

Choose a reason for hiding this comment

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

That does not make any sense. When users run ansiblelint, they expect file names and line numbers to point to the problematic points in roles and playbooks being analyzed, not to the linter code.

Also, since yamllint is an optional component of ansiblelint, I am not sure if the scenario where it is missing needs any special treatment. Also, this would be a backward-incompatible change that would require us to bump the major version of ansiblelint.

@ssbarnea
Copy link
Member

The current for of this PR does not make any sense but there is hope. I think that @dosmanak did not fully understood the concept of a soft-dependency. Ansible list is expected to gracefully degrade when yamllint is missing.

If you really want to add a feature that would cause a failure when yamllint is missing, you can do it by checking if yaml is included in enable_list and causing a failure.

Keep in mind that absence of yamllint library should be ignored unless yaml is added to enable_list. Also keep in mind to document this behavior in two places: yaml rule description and our sample .ansiblelint configuration file, where you should add it as commented, w/o extra line explaining what it does.

@ssbarnea ssbarnea self-requested a review April 30, 2021 11:04
Copy link
Member

@ssbarnea ssbarnea left a comment

Choose a reason for hiding this comment

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

Needs rewrite, see previous comment.

@ssbarnea ssbarnea changed the title feat: Handle uninstalled yamllint as rule violation feat: Handle missing yamllint as rule violation Apr 30, 2021
@dosmanak
Copy link
Author

dosmanak commented May 3, 2021

Before all thanks for focus you are giving on my PR.

The current for of this PR does not make any sense but there is hope. I think that @dosmanak did not fully understood the concept of a soft-dependency. Ansible list is expected to gracefully degrade when yamllint is missing.

I don't see soft-dependency used anywhere else, and I didn't found any description for that so it is possible I do not understand the concept.

If you really want to add a feature that would cause a failure when yamllint is missing, you can do it by checking if yaml is included in enable_list and causing a failure.

I went through the code and it seems that all rules are enabled unless tagged with 'opt-in'.

207     def register(self, obj: AnsibleLintRule) -> None:                                                     
208         # We skip opt-in rules which were not manually enabled
209         if 'opt-in' not in obj.tags or obj.id in self.options.enable_list:
210             self.rules.append(obj)

And only rule NoSameOwnerRule uses the tag.

Keep in mind that absence of yamllint library should be ignored unless yaml is added to enable_list. Also keep in mind to document this behaviour in two places: yaml rule description and our sample .ansiblelint configuration file, where you should add it as commented, w/o extra line explaining what it does.

If that is correct, then the YamllintRule misses the tag opt-in, but adding it would change the behaviour heavily.

Motivation

I installed ansible-lint but my output looked different than colleague's with the same config. I realized I did not installed the yamllint and when I did, the output were identical to my colleague's output. So I thought the ansible-lint shoul at least warn me the yamllint is not installed but I found the logging facility in ansible-lint is weird so I implemented the warning as violation of the rule.

Outcome

Based on the stated peculiarities I would like to know the concept of soft-dependency and opt-in rules. The current behaviour of the YamllintRule which is invoked if yamllint is detected in the system, but succeeds silently when not present is undeterministic to me and should be fixed somehow.

@ssbarnea
Copy link
Member

ssbarnea commented May 3, 2021

The reason why you can your college got different results running the linter is because you did use different ways to install it. Check https://github.com/ansible-community/ansible-lint/blob/master/docs/installing.rst -- there you can see the mention of yamllint as an optional/soft/extra dependency. Missing it is treated as an ignore instead of error or warning. Its presence does enable the yaml checks.

This is different than opt-in and it an unique property of yaml rule, at least for now. In the future we may want to add other similar checks.

I do understand that you may want to enforce a failure if the library is missing and I can see this use-case as making sense (when the maintainer wants to be sure the users are using the desired set of rules and not only a subset.

ssbarnea added a commit that referenced this pull request May 3, 2021
ssbarnea added a commit that referenced this pull request May 3, 2021
@dosmanak
Copy link
Author

dosmanak commented May 3, 2021

Thank you for pointing out for installation guide, but I installed it using system package manager (dnf on Fedora)

Its (yamllint) presence does enable the yaml checks.

Not from my experience, solely the installation of yamllint causes the ansible-lint will enable the yaml checks. Is that intended?

@ssbarnea
Copy link
Member

ssbarnea commented May 3, 2021

Thank you for pointing out for installation guide, but I installed it using system package manager (dnf on Fedora)

Its (yamllint) presence does enable the yaml checks.

Not from my experience, solely the installation of yamllint causes the ansible-lint will enable the yaml checks. Is that intended?

Take a look at #1543 and you will see how you could force a repository to require use of yamllint.

ssbarnea added a commit that referenced this pull request May 3, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants