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

Version 0.2.0 Release #121

Merged
merged 30 commits into from
Nov 22, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
ace3fe3
changed copyright to Warpnet
matthijswendelaar Nov 5, 2019
9a19f90
Merge pull request #94 from matthijswendelaar/fix_copyright
matthijswendelaar Nov 5, 2019
ead1745
Add Python 3.8 job to Travis CI
roaldnefs Nov 7, 2019
f1b180e
Update py38 job in Travis configuration
roaldnefs Nov 7, 2019
98646bb
Add distro as a dependency for py38
roaldnefs Nov 8, 2019
6cb7a0b
Remove salt as a tox depedency
roaldnefs Nov 8, 2019
8f082f4
Update Travis configuration
roaldnefs Nov 8, 2019
e1ed6a1
Add coverage configuration
roaldnefs Nov 8, 2019
e4a42b4
Merge pull request #95 from warpnet/add-py38-travis
roaldnefs Nov 8, 2019
4b34347
Update README
jbouter Nov 10, 2019
c29066a
Update README
jbouter Nov 10, 2019
f80072f
Merge pull request #98 from warpnet/readme-plugins
jbouter Nov 10, 2019
4c59ed1
Fix typos in saltlint/linter.py
roaldnefs Nov 11, 2019
8a884a3
Merge pull request #103 from warpnet/fix/typos
jbouter Nov 13, 2019
2d20ba4
Added fixes for common issues
Nov 13, 2019
451c566
Merge branch 'develop' into feature/improved-readme
roaldnefs Nov 13, 2019
6c75f7d
Merge pull request #108 from hbokh/feature/improved-readme
roaldnefs Nov 13, 2019
7d2a223
Update documentation
jbouter Nov 13, 2019
c66960f
Update README.md
jbouter Nov 13, 2019
a753d72
Merge pull request #109 from warpnet/update-readme
roaldnefs Nov 13, 2019
efbd290
Add severity to standard output. Fixes #93
mew1033 Nov 14, 2019
cfbfd58
Add add-severity to README
mew1033 Nov 14, 2019
7bbfb11
Json parameter now works in config file
mew1033 Nov 15, 2019
8d936a4
Add brackets around severity in nocolor output
mew1033 Nov 15, 2019
b604251
Merge pull request #112 from mew1033/bugfix
roaldnefs Nov 15, 2019
8bf8b3c
Update CLI options to support British
jbouter Nov 15, 2019
8667afe
Merge pull request #113 from warpnet/union-jack
jbouter Nov 15, 2019
b611de7
Make severity formatter more in line with ansible-lint
mew1033 Nov 20, 2019
4a78467
Merge pull request #111 from mew1033/add-severity
roaldnefs Nov 21, 2019
45f260d
Bump version to v0.2.0
roaldnefs Nov 21, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[run]
branch = True

[report]
exclude_lines =
# Don't complain if non-runnable code isn't run:
if __name__ == .__main__.:
119 changes: 61 additions & 58 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,68 +2,71 @@
dist: bionic
language: python

matrix:
cache: pip

git:
depth: 100

jobs:
fast_finish: true

include:
- env: TOXENV=flake8
install:
- pip install tox
script:
- tox
- python: 3.7
name: Running linters
script:
- flake8

- python: 3.8
before_install:
- pip install distro

- python: 3.7

- python: 3.6

- python: 2.7
env: TOXENV=py27
install:
- pip install tox
script:
- tox
- python: 3.5

- python: 3.5
env: TOXENV=py35
install:
- pip install tox
script:
- tox
- python: 2.7

- python: 3.6
env: TOXENV=py36
install:
- pip install tox
script:
- tox
- language: generic
name: Running hadolint
sudo: false
env:
HADOLINT: "${HOME}/hadolint"
install:
# Download hadolint binary and set it as executable
- curl -sL -o ${HADOLINT} "https://github.com/hadolint/hadolint/releases/download/v1.16.0/hadolint-$(uname -s)-$(uname -m)"
&& chmod 700 ${HADOLINT}
script:
# List files which name starts with 'Dockerfile'
# eg. Dockerfile, Dockerfile.build, etc.
- git ls-files --exclude='Dockerfile*' --ignored | xargs --max-lines=1 ${HADOLINT}

- python: 3.7
env: TOXENV=py37
install:
- pip install tox
script:
- tox
- python: 3.7
stage: Deploy
name: Publishing current Git tagged version of dist to PyPI
if: repo == "warpnet/salt-lint" AND tag IS present AND branch == "master" AND type NOT IN (cron, pull_request)
before_install: []
# Deploy a new release to PyPi for every new tag on the 'master' branch on the
# repository 'warpnet/salt-lint'.
deploy:
provider: pypi
user: __token__
password:
# A PyPI API token can be generated by a PyPi maintainer on:
# https://pypi.org/help/#apitoken
# The API token in encrypted using `travis encrypt api-token`.
secure: "fL3/pkTaRA+cmTdC5Qxo9xoDoxXv6VbwbT3fM5JwW1F0NPbqR7Kw+oMJl2ZKQZrbRxvtPps8dYzxqC0axZ+WRFeVz+FzFeosziU/1kk1U5Bks5VK1my0kPl9jlD1kM0gS8mSm6gdNHJ6Z8quEXuYCMtMhqyCMgw0PWRaMOuuQ5Yi6/olUPjDxkMsFeh+03VIXTXGHPk7GxR3OTbOUaIaQXkbt7RQ7usDHnd1W6jeW5a1Q2h2cvugHfk6B9UYaXnIacCSejD4NJHkE+j3lbVI6QuzBO3MdaEM6V/+P3zDh0ZF9SK2BfXdNqMtCij/u8q0er+Y6ZU1LGDrRuXe6bmRr6KyJfiOsgKOCyLXSNqGGim01eJHO14DUgGrc8qWo1KKywtxagIriMcTxAOccW8RDRy3zkKYdEHgdFs6MtVL2JV+wyhdxxoU6DOZsNn6N8d9WninpAcIPtfiYzBRerQqR0OiKmpDK4Oee9IKCfRhMhWAY7Rs/RV33YluEJbv4bWPcPMPciEUp/xXxwPMWFQ45VoR4ZiwBYz0KoOMb/QrVfN8m8pdEtQpSUX51PFTFzmrreB6OvwJ5aphMrxIpvCJNZ65mfZthDKJUhSo0EG6ix/g4nOR7qlLNMVsQF4qSRCKDJlqUlzXYpQuy0u/QXoihCReO5rI6nWdV/KTfHCYgdo="
on:
repo: warpnet/salt-lint
tags: true
branch: master
python: 3.7

- language: generic
sudo: false
env:
HADOLINT: "${HOME}/hadolint"
install:
# Download hadolint binary and set it as executable
- curl -sL -o ${HADOLINT} "https://github.com/hadolint/hadolint/releases/download/v1.16.0/hadolint-$(uname -s)-$(uname -m)"
&& chmod 700 ${HADOLINT}
script:
# List files which name starts with 'Dockerfile'
# eg. Dockerfile, Dockerfile.build, etc.
- git ls-files --exclude='Dockerfile*' --ignored | xargs --max-lines=1 ${HADOLINT}
install:
- pip install -r test-deps.txt
- pip install .

# Deploy a new release to PyPi for every new tag on the 'master' branch on the
# repository 'warpnet/salt-lint'.
deploy:
provider: pypi
user: __token__
password:
# A PyPI API token can be generated by a PyPi maintainer on:
# https://pypi.org/help/#apitoken
# The API token in encrypted using `travis encrypt api-token`.
secure: "fL3/pkTaRA+cmTdC5Qxo9xoDoxXv6VbwbT3fM5JwW1F0NPbqR7Kw+oMJl2ZKQZrbRxvtPps8dYzxqC0axZ+WRFeVz+FzFeosziU/1kk1U5Bks5VK1my0kPl9jlD1kM0gS8mSm6gdNHJ6Z8quEXuYCMtMhqyCMgw0PWRaMOuuQ5Yi6/olUPjDxkMsFeh+03VIXTXGHPk7GxR3OTbOUaIaQXkbt7RQ7usDHnd1W6jeW5a1Q2h2cvugHfk6B9UYaXnIacCSejD4NJHkE+j3lbVI6QuzBO3MdaEM6V/+P3zDh0ZF9SK2BfXdNqMtCij/u8q0er+Y6ZU1LGDrRuXe6bmRr6KyJfiOsgKOCyLXSNqGGim01eJHO14DUgGrc8qWo1KKywtxagIriMcTxAOccW8RDRy3zkKYdEHgdFs6MtVL2JV+wyhdxxoU6DOZsNn6N8d9WninpAcIPtfiYzBRerQqR0OiKmpDK4Oee9IKCfRhMhWAY7Rs/RV33YluEJbv4bWPcPMPciEUp/xXxwPMWFQ45VoR4ZiwBYz0KoOMb/QrVfN8m8pdEtQpSUX51PFTFzmrreB6OvwJ5aphMrxIpvCJNZ65mfZthDKJUhSo0EG6ix/g4nOR7qlLNMVsQF4qSRCKDJlqUlzXYpQuy0u/QXoihCReO5rI6nWdV/KTfHCYgdo="
on:
repo: warpnet/salt-lint
tags: true
branch: master
python: 3.6
condition: "$TOXENV = py36"
script:
- coverage run --source=saltlint setup.py test
- coveralls
34 changes: 30 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Options:
-L list all the rules
-r RULESDIR specify one or more rules directories using one or
more -r arguments. Any -r flags override the default
rules in /path/to/salt-lint/saltlint/rules, unless
rules in /path/to/salt-lint/saltlint/rules, unless
-R is also used.
-R Use default rules in
/path/to/salt-lint/saltlint/rules in addition to any
Expand All @@ -54,6 +54,7 @@ Options:
path to directories or files to skip. This option is
repeatable.
--json parse the output as JSON
--severity add the severity to the standard output
-c C Specify configuration file to use. Defaults to
".salt-lint"
```
Expand Down Expand Up @@ -112,6 +113,7 @@ rules:
*.jinja
210:
ignore: 'exclude_this_file.sls'
severity: True
```

## Pre-commit Setup
Expand All @@ -134,15 +136,14 @@ To use salt-lint with [pre-commit](https://pre-commit.com), just add the follow

# Rules


## List of rules

Rule | Description
:-:|:--
[201](https://github.com/warpnet/salt-lint/wiki/201) | Trailing whitespace
[202](https://github.com/warpnet/salt-lint/wiki/202) | Jinja statement should have spaces before and after: `{% statement %}`
[203](https://github.com/warpnet/salt-lint/wiki/203) | Most files should not contain tabs
[204](https://github.com/warpnet/salt-lint/wiki/204) | Lines should be no longer that 160 chars
[204](https://github.com/warpnet/salt-lint/wiki/204) | Lines should be no longer than 160 chars
[205](https://github.com/warpnet/salt-lint/wiki/205) | Use ".sls" as a Salt State file extension
[206](https://github.com/warpnet/salt-lint/wiki/206) | Jinja variables should have spaces before and after `{{ var_name }}`
[207](https://github.com/warpnet/salt-lint/wiki/207) | File modes should always be encapsulated in quotation marks
Expand All @@ -152,7 +153,6 @@ Rule | Description
[211](https://github.com/warpnet/salt-lint/wiki/211) | `pillar.get` or `grains.get` should be formatted differently
[212](https://github.com/warpnet/salt-lint/wiki/212) | Most files should not contain irregular spaces


## False Positives: Skipping Rules

Some rules are bit of a rule of thumb. To skip a specific rule for a specific task, inside your state add `# noqa [rule_id]` at the end of the line. You can skip multiple rules via a space-separated list. Example:
Expand All @@ -163,6 +163,32 @@ Some rules are bit of a rule of thumb. To skip a specific rule for a specific ta
- source: salt://{{unspaced_var}}/example # noqa: 206
```

# Plugins

Currently, there is a `salt-lint` plugin available for the following applications:

Application | GitHub Link | Store/Marketplace
:-:|:--|:--
Visual Studio Code | [warpnet/vscode-salt-lint](https://github.com/warpnet/vscode-salt-lint) | [VisualStudio Marketplace](https://marketplace.visualstudio.com/items?itemName=warpnet.salt-lint)
Sublime Text | [warpnet/SublimeLinter-salt-lint](https://github.com/warpnet/SublimeLinter-salt-lint) | [Package Control](https://packagecontrol.io/packages/SublimeLinter-contrib-salt-lint)

Wish to create a `salt-lint` extension for your favourite editor? We're always looking for [contributions](CONTRIBUTING.md)!

# Fix common issues

`sed` might be one of the better tools to fix common issues, as shown in commands below.

**Note**: these commands assume your current working directory is the salt (states) directory/repository.

Fix spacing arround `{{ var_name }}`, eg. `{{env}}` --> `{{ env }}`:\
`sed -i -E "s/\{\{\s?([^}]*[^} ])\s?\}\}/\{\{ \1 \}\}/g" $(find . -name '*.sls')`

Make the `dir_mode`, `file_mode` and `mode` arguments in the desired syntax:\
`sed -i -E "s/\b(dir_|file_|)mode: 0?([0-7]{3})/\1mode: '0\2'/" $(find . -name '*.sls')`

Add quotes arround numeric values that start with a `0`:\
`sed -i -E "s/\b(minute|hour): (0[0-7]?)\$/\1: '\2'/" $(find . -name '*.sls')`

# Authors

The project is heavily based on [ansible-lint](https://github.com/ansible/ansible-lint), with the modified work by [Warpnet B.V.](https://github.com/warpnet). [ansible-lint](https://github.com/ansible/ansible-lint) was created by [Will Thames](https://github.com/willthames) and is now maintained as part of the [Ansible](https://www.ansible.com/) by [Red Hat](https://www.redhat.com) project.
2 changes: 1 addition & 1 deletion docker/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ LABEL maintainer="info@warpnet.nl"
RUN apk add --no-cache gcc g++ build-base libzmq musl-dev zeromq-dev

# Install the salt-lint package
RUN pip install --no-cache salt-lint==v0.1.0
RUN pip install --no-cache salt-lint==v0.2.0

# Remove development utilities
RUN apk del --no-cache gcc g++ build-base libzmq musl-dev zeromq-dev \
Expand Down
2 changes: 1 addition & 1 deletion saltlint/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""

NAME = 'salt-lint'
VERSION = '0.1.0'
VERSION = '0.2.0'
DESCRIPTION = __doc__

__author__ = 'Warpnet B.V.'
Expand Down
2 changes: 1 addition & 1 deletion saltlint/__main__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2013-2014 Will Thames <will@thames.id.au>
# Modified work Copyright (c) 2019 Roald Nefs
# Modified work Copyright (c) 2019 Warpnet B.V.

import sys
import errno
Expand Down
10 changes: 7 additions & 3 deletions saltlint/cli.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2013-2014 Will Thames <will@thames.id.au>
# Modified work Copyright (c) 2019 Roald Nefs
# Modified work Copyright (c) 2019 Warpnet B.V.

from __future__ import print_function

Expand Down Expand Up @@ -52,11 +52,11 @@ def run(args=None):
parser.add_option('-x', dest='skip_list', default=[], action='append',
help="only check rules whose id/tags do not " +
"match these values")
parser.add_option('--nocolor', dest='colored',
parser.add_option('--nocolor', '--nocolour', dest='colored',
default=hasattr(sys.stdout, 'isatty') and sys.stdout.isatty(),
action='store_false',
help="disable colored output")
parser.add_option('--force-color', dest='colored',
parser.add_option('--force-color', '--force-colour', dest='colored',
action='store_true',
help="Try force colored output (relying on salt's code)")
parser.add_option('--exclude', dest='exclude_paths', action='append',
Expand All @@ -65,6 +65,8 @@ def run(args=None):
default=[])
parser.add_option('--json', dest='json', action='store_true', default=False,
help='parse the output as JSON')
parser.add_option('--severity', dest='severity', action='store_true', default=False,
help='add the severity to the standard output')
parser.add_option('-c', help='Specify configuration file to use. Defaults to ".salt-lint"')
(options, parsed_args) = parser.parse_args(args if args is not None else sys.argv[1:])

Expand Down Expand Up @@ -111,6 +113,8 @@ def run(args=None):
# Define the formatter
if config.json:
formatter = formatters.JsonFormatter()
elif config.severity:
formatter = formatters.SeverityFormatter()
else:
formatter = formatters.Formatter()

Expand Down
9 changes: 8 additions & 1 deletion saltlint/config.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2019 Roald Nefs
# Copyright (c) 2019 Warpnet B.V.

import yaml
import os
Expand Down Expand Up @@ -97,6 +97,13 @@ def _parse(self, content):

# Parse json
self.json = self._options.get('json', False)
if 'json' in config:
self.json = config['json']

# Parse add severity
self.severity = self._options.get('severity', False)
if 'severity' in config:
self.severity = config['severity']

# Parse rule specific configuration, the configration can be listed by
# the rule ID and/or tag.
Expand Down
35 changes: 34 additions & 1 deletion saltlint/formatters/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2013-2018 Will Thames <will@thames.id.au>
# Copyright (c) 2018 Ansible by Red Hat
# Modified work Copyright (c) 2019 Roald Nefs
# Modified work Copyright (c) 2019 Warpnet B.V.

import json

Expand Down Expand Up @@ -42,6 +42,39 @@ def format(self, match, colored=False):
match.line)


class SeverityFormatter(object):
def process(self, matches, colored=False):
for match in matches:
print(self.format(match, colored))

def format(self, match, colored=False):
formatstr = u"{0} {sev} {1}\n{2}:{3}\n{4}\n"

if colored:
color = saltcolor.get_colors()
return formatstr.format(
u'{0}[{1}]{2}'.format(color['RED'], match.rule.id,
color['ENDC']),
u'{0}{1}{2}'.format(color['LIGHT_RED'], match.message,
color['ENDC']),
u'{0}{1}{2}'.format(color['BLUE'], match.filename,
color['ENDC']),
u'{0}{1}{2}'.format(color['CYAN'], str(match.linenumber),
color['ENDC']),
u'{0}{1}{2}'.format(color['MAGENTA'], match.line, color['ENDC']),
sev=u'{0}[{1}]{2}'.format(color['RED'], match.rule.severity,
color['ENDC'])
)
else:
return formatstr.format(
u'[{0}]'.format(match.rule.id),
match.message,
match.filename,
match.linenumber,
match.line,
sev=u'[{0}]'.format(match.rule.severity))


class JsonFormatter(object):

def process(self, matches, *args, **kwargs):
Expand Down
6 changes: 3 additions & 3 deletions saltlint/linter.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2013-2014 Will Thames <will@thames.id.au>
# Modified work Copyright (c) 2019 Roald Nefs
# Modified work Copyright (c) 2019 Warpnet B.V.

from __future__ import print_function

Expand Down Expand Up @@ -100,7 +100,7 @@ def run(self, statefile, tags=set(), skip_list=frozenset()):
with codecs.open(statefile['path'], mode='rb', encoding='utf-8') as f:
text = f.read()
except IOError as e:
print("WARNING: Coudn't open %s - %s" %
print("WARNING: Couldn't open %s - %s" %
(statefile['path'], e.strerror),
file=sys.stderr)
return matches
Expand All @@ -111,7 +111,7 @@ def run(self, statefile, tags=set(), skip_list=frozenset()):
rule_definition = set(rule.tags)
rule_definition.add(rule.id)

# Check if the the file is in the rule specific ignore list.
# Check if the file is in the rule specific ignore list.
for definition in rule_definition:
if self.config.is_file_ignored(statefile['path'], definition):
skip = True
Expand Down
6 changes: 3 additions & 3 deletions saltlint/rules/FileExtensionRule.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2016, Tsukinowa Inc. <info@tsukinowa.jp>
# Copyright (c) 2018, Ansible Project
# Modified work Copyright (c) 2019 Roald Nefs
# Copyright (c) 2016 Tsukinowa Inc. <info@tsukinowa.jp>
# Copyright (c) 2018 Ansible Project
# Modified work Copyright (c) 2019 Warpnet B.V.

from saltlint.linter import SaltLintRule

Expand Down
Loading