Merge "Report yaml parsing errors instead of ignoring"
This commit is contained in:
commit
39b396be63
|
@ -57,9 +57,9 @@ class Manager(object):
|
|||
errors = []
|
||||
while True:
|
||||
try:
|
||||
e = next(error_chain, None)
|
||||
if e is None:
|
||||
break
|
||||
e = next(error_chain)
|
||||
except StopIteration:
|
||||
break
|
||||
except Exception:
|
||||
LOG.exception('Checker failed')
|
||||
e = error.report.E000(
|
||||
|
|
|
@ -14,8 +14,10 @@
|
|||
|
||||
|
||||
import abc
|
||||
import io
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import zipfile
|
||||
|
||||
import six
|
||||
|
@ -34,17 +36,19 @@ class FileWrapper(object):
|
|||
self._path = path
|
||||
with pkg.open_file(path) as file_:
|
||||
self._raw = file_.read()
|
||||
|
||||
with pkg.open_file(path) as file_:
|
||||
try:
|
||||
self._yaml = list(yaml.load_all(file_, yaml_loader.YamlLoader))
|
||||
except yaml.YAMLError:
|
||||
self._yaml = None
|
||||
self._name = file_.name
|
||||
self._yaml = None
|
||||
self._pkg = pkg
|
||||
|
||||
def raw(self):
|
||||
return self._raw
|
||||
|
||||
def yaml(self):
|
||||
if self._yaml is None:
|
||||
sio = io.StringIO(six.text_type(self.raw()))
|
||||
setattr(sio, 'name', self._name)
|
||||
self._yaml = list(yaml.load_all(sio,
|
||||
yaml_loader.YamlLoader))
|
||||
return self._yaml
|
||||
|
||||
|
||||
|
@ -92,14 +96,19 @@ class BaseLoader(object):
|
|||
|
||||
def try_set_format(self):
|
||||
if self.exists(consts.MANIFEST_PATH):
|
||||
manifest = self.read(consts.MANIFEST_PATH).yaml()
|
||||
if manifest and 'Format' in manifest:
|
||||
if '/' in str(manifest['Format']):
|
||||
fmt, version = manifest['Format'].split('/', 1)
|
||||
self.format = fmt
|
||||
self.format_version = version
|
||||
else:
|
||||
self.format_version = str(manifest['Format'])
|
||||
try:
|
||||
manifest = self.read(consts.MANIFEST_PATH).yaml()
|
||||
except yaml.YAMLError:
|
||||
LOG.warning('Unable to parse Manifest yaml',
|
||||
exc_info=sys.exc_info())
|
||||
else:
|
||||
if manifest and 'Format' in manifest:
|
||||
if '/' in str(manifest['Format']):
|
||||
fmt, version = manifest['Format'].split('/', 1)
|
||||
self.format = fmt
|
||||
self.format_version = version
|
||||
else:
|
||||
self.format_version = str(manifest['Format'])
|
||||
|
||||
|
||||
class DirectoryLoader(BaseLoader):
|
||||
|
|
|
@ -14,6 +14,8 @@
|
|||
|
||||
import mock
|
||||
|
||||
import yaml.error
|
||||
|
||||
from muranopkgcheck import consts
|
||||
from muranopkgcheck import pkg_loader
|
||||
from muranopkgcheck.tests import base
|
||||
|
@ -33,7 +35,7 @@ class FileWrapperTest(base.TestCase):
|
|||
lambda f: mock.mock_open(read_data='!@#$%')()
|
||||
f = pkg_loader.FileWrapper(fake_pkg, 'fake_path')
|
||||
self.assertEqual('!@#$%', f.raw())
|
||||
self.assertEqual(None, f.yaml())
|
||||
self.assertRaises(yaml.error.YAMLError, f.yaml)
|
||||
|
||||
|
||||
class FakeLoader(pkg_loader.BaseLoader):
|
||||
|
|
|
@ -105,9 +105,6 @@ class YamlValidator(BaseValidator):
|
|||
|
||||
def _run_single(self, file_):
|
||||
reports_chain = []
|
||||
multi_documents = file_.yaml()
|
||||
if multi_documents is None:
|
||||
multi_documents = [{}]
|
||||
|
||||
def run_helper(name, checkers, data):
|
||||
for checker in checkers:
|
||||
|
@ -115,26 +112,37 @@ class YamlValidator(BaseValidator):
|
|||
if result:
|
||||
reports_chain.append(result)
|
||||
|
||||
if len(multi_documents) > 1 and not self._allows_multi:
|
||||
reports_chain.append(
|
||||
error.report.E005('Multi document is not allowed in {0}'
|
||||
.format(file_._path)))
|
||||
try:
|
||||
multi_documents = file_.yaml()
|
||||
except Exception as e:
|
||||
reports_chain.append([
|
||||
error.report.E002('Yaml Error: {0}'.format(e), e)])
|
||||
else:
|
||||
if multi_documents is None:
|
||||
multi_documents = [{}]
|
||||
|
||||
for ast in multi_documents:
|
||||
file_check = self._checkers.get(None)
|
||||
if file_check:
|
||||
run_helper(None, file_check['checkers'], ast)
|
||||
for key, value in six.iteritems(ast):
|
||||
checkers = self._checkers.get(key)
|
||||
if checkers:
|
||||
run_helper(key, checkers['checkers'], ast[key])
|
||||
else:
|
||||
reports_chain.append(self._unknown_keyword(key, value))
|
||||
missing = set(key for key, value in six.iteritems(self._checkers)
|
||||
if value['required']) - set(ast.keys())
|
||||
for m in missing:
|
||||
reports_chain.append([error.report.E020('Missing required key '
|
||||
'"{0}"'.format(m), m)])
|
||||
if len(multi_documents) > 1 and not self._allows_multi:
|
||||
reports_chain.append([
|
||||
error.report.E005('Multi document is not allowed in {0}'
|
||||
.format(file_._path))])
|
||||
|
||||
for ast in multi_documents:
|
||||
file_check = self._checkers.get(None)
|
||||
if file_check:
|
||||
run_helper(None, file_check['checkers'], ast)
|
||||
for key, value in six.iteritems(ast):
|
||||
checkers = self._checkers.get(key)
|
||||
if checkers:
|
||||
run_helper(key, checkers['checkers'], ast[key])
|
||||
else:
|
||||
reports_chain.append(self._unknown_keyword(key, value))
|
||||
missing = set(key for key, value in
|
||||
six.iteritems(self._checkers)
|
||||
if value['required']) - set(ast.keys())
|
||||
for m in missing:
|
||||
reports_chain.append([
|
||||
error.report.E020('Missing required key "{0}"'
|
||||
.format(m), m)])
|
||||
return itertools.chain(*reports_chain)
|
||||
|
||||
def _valid_keywords(self, present, known):
|
||||
|
|
Loading…
Reference in New Issue