Merge pull request #27 from jsok/strict-mode

Strict mode
pull/31/head
Adrien Vergé 8 years ago committed by GitHub
commit 2428f6eeaf

@ -102,8 +102,15 @@ Errors and warnings
------------------- -------------------
Problems detected by yamllint can be raised either as errors or as warnings. Problems detected by yamllint can be raised either as errors or as warnings.
The CLI will output them (with different colors when using the ``standard``
output format).
In both cases, the script will output them (with different colors when using the By default the script will exit will a return code ``1`` *only when* there is one or
``standard`` output format), but the exit code can be different. More precisely, more error(s).
the script will exit will a failure code *only when* there is one or more
error(s). However if strict mode is enabled with the ``-s`` (or ``--strict``) option, the
return code will be:
* ``0`` if no errors or warnings occur
* ``1`` if one or more errors occur
* ``2`` if no errors occur, but one or more warnings occur

@ -40,6 +40,10 @@ class CommandLineTestCase(unittest.TestCase):
'- 1 \n' '- 1 \n'
'- 2') '- 2')
# file with only one warning
with open(os.path.join(self.wd, 'warn.yaml'), 'w') as f:
f.write('key: value\n')
# .yml file at root # .yml file at root
open(os.path.join(self.wd, 'empty.yml'), 'w').close() open(os.path.join(self.wd, 'empty.yml'), 'w').close()
@ -85,7 +89,8 @@ class CommandLineTestCase(unittest.TestCase):
[os.path.join(self.wd, 'a.yaml'), [os.path.join(self.wd, 'a.yaml'),
os.path.join(self.wd, 'empty.yml'), os.path.join(self.wd, 'empty.yml'),
os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'), os.path.join(self.wd, 's/s/s/s/s/s/s/s/s/s/s/s/s/s/s/file.yaml'),
os.path.join(self.wd, 'sub/ok.yaml')], os.path.join(self.wd, 'sub/ok.yaml'),
os.path.join(self.wd, 'warn.yaml')],
) )
items = [os.path.join(self.wd, 'sub/ok.yaml'), items = [os.path.join(self.wd, 'sub/ok.yaml'),
@ -247,6 +252,24 @@ class CommandLineTestCase(unittest.TestCase):
'(new-line-at-end-of-file)\n') % (file, file)) '(new-line-at-end-of-file)\n') % (file, file))
self.assertEqual(err, '') self.assertEqual(err, '')
def test_run_one_warning(self):
file = os.path.join(self.wd, 'warn.yaml')
sys.stdout, sys.stderr = StringIO(), StringIO()
with self.assertRaises(SystemExit) as ctx:
cli.run(('-f', 'parsable', file))
self.assertEqual(ctx.exception.code, 0)
def test_run_warning_in_strict_mode(self):
file = os.path.join(self.wd, 'warn.yaml')
sys.stdout, sys.stderr = StringIO(), StringIO()
with self.assertRaises(SystemExit) as ctx:
cli.run(('-f', 'parsable', '--strict', file))
self.assertEqual(ctx.exception.code, 2)
def test_run_one_ok_file(self): def test_run_one_ok_file(self):
file = os.path.join(self.wd, 'sub', 'ok.yaml') file = os.path.join(self.wd, 'sub', 'ok.yaml')

@ -22,6 +22,7 @@ import argparse
from yamllint import APP_DESCRIPTION, APP_NAME, APP_VERSION from yamllint import APP_DESCRIPTION, APP_NAME, APP_VERSION
from yamllint.config import YamlLintConfig, YamlLintConfigError from yamllint.config import YamlLintConfig, YamlLintConfigError
from yamllint.linter import PROBLEM_LEVELS
from yamllint import linter from yamllint import linter
@ -85,6 +86,10 @@ def run(argv=None):
parser.add_argument('-f', '--format', parser.add_argument('-f', '--format',
choices=('parsable', 'standard'), default='standard', choices=('parsable', 'standard'), default='standard',
help='format for parsing output') help='format for parsing output')
parser.add_argument('-s', '--strict',
action='store_true',
help='return non-zero exit code on warnings '
'as well as errors')
parser.add_argument('-v', '--version', action='version', parser.add_argument('-v', '--version', action='version',
version='%s %s' % (APP_NAME, APP_VERSION)) version='%s %s' % (APP_NAME, APP_VERSION))
@ -121,7 +126,7 @@ def run(argv=None):
print(e, file=sys.stderr) print(e, file=sys.stderr)
sys.exit(-1) sys.exit(-1)
return_code = 0 max_level = 0
for file in find_files_recursively(args.files): for file in find_files_recursively(args.files):
try: try:
@ -143,13 +148,19 @@ def run(argv=None):
print(Format.standard(problem, file)) print(Format.standard(problem, file))
if return_code == 0 and problem.level == 'error': max_level = max(max_level, PROBLEM_LEVELS[problem.level])
return_code = 1
if not first and args.format != 'parsable': if not first and args.format != 'parsable':
print('') print('')
except EnvironmentError as e: except EnvironmentError as e:
print(e, file=sys.stderr) print(e, file=sys.stderr)
return_code = -1 sys.exit(-1)
if max_level == PROBLEM_LEVELS['error']:
return_code = 1
elif max_level == PROBLEM_LEVELS['warning']:
return_code = 2 if args.strict else 0
else:
return_code = 0
sys.exit(return_code) sys.exit(return_code)

@ -21,6 +21,16 @@ import yaml
from yamllint import parser from yamllint import parser
PROBLEM_LEVELS = {
0: None,
1: 'warning',
2: 'error',
None: 0,
'warning': 1,
'error': 2,
}
class LintProblem(object): class LintProblem(object):
"""Represents a linting problem found by yamllint.""" """Represents a linting problem found by yamllint."""
def __init__(self, line, column, desc='<no description>', rule=None): def __init__(self, line, column, desc='<no description>', rule=None):

Loading…
Cancel
Save