releases/openstack_releases/cmds/check_schema.py
Doug Hellmann f446ef37f4 generate the series status table from data
Move the information about the series status into a data file and use
that to generate the table on the main page. This is the first step
toward adding deliverable-specific series status information to the
output, since we need a place to put the default values.

Because we're adding a yaml file under the deliverables directory that
is not actually a deliverable file, we have to update the validation
tool to ignore it.

Story: #2001852
Task: #14347
Change-Id: I99bd94a323b53c0dfc2cb648268e51a30321cd46
Signed-off-by: Doug Hellmann <doug@doughellmann.com>
2018-04-20 14:05:04 -04:00

121 lines
3.3 KiB
Python

# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
"""Verify that all deliverable files match the schema.
"""
from __future__ import print_function
import argparse
import datetime
import glob
import logging
import os
import os.path
import pkgutil
import sys
import jsonschema
import jsonschema.validators
from openstack_releases import yamlutils
LOG = logging.getLogger('')
_SERIES_SCHEMA = yamlutils.loads(
pkgutil.get_data('openstack_releases',
'series_status_schema.yaml').decode('utf-8')
)
_DELIVERABLE_SCHEMA = yamlutils.loads(
pkgutil.get_data('openstack_releases', 'schema.yaml').decode('utf-8')
)
def is_date(validator, value, instance, schema):
if not isinstance(instance, str):
return
try:
return datetime.datetime.strptime(instance, "%Y-%m-%d")
except Exception:
yield jsonschema.ValidationError('Invalid date {!r}'.format(instance))
def make_validator_with_date(schema_data):
return jsonschema.validators.extend(
validator=jsonschema.Draft4Validator(schema_data),
validators={'date': is_date},
)(schema_data, types={'date': datetime.date})
def validate_one_file(filename, schema_data, debug):
LOG.info('Checking %s', filename)
validator = make_validator_with_date(schema_data)
with open(filename, 'r', encoding='utf-8') as f:
info = yamlutils.loads(f.read())
for error in validator.iter_errors(info):
LOG.error(error)
yield '{}: {}'.format(filename, error)
if debug:
raise RuntimeError(error)
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
'--debug',
default=False,
action='store_true',
help='throw exception on error',
)
parser.add_argument(
'input',
nargs='*',
help=('YAML files to validate, defaults to '
'files changed in the latest commit'),
)
args = parser.parse_args()
# Set up logging, including making some loggers quiet.
logging.basicConfig(
format='%(levelname)7s: %(message)s',
stream=sys.stdout,
level=logging.DEBUG,
)
logging.getLogger('urllib3.connectionpool').setLevel(logging.WARNING)
errors = []
errors.extend(
validate_one_file('deliverables/series_status.yaml',
_SERIES_SCHEMA, args.debug)
)
filenames = args.input or sorted(glob.glob('deliverables/*/*.yaml'))
for filename in filenames:
if not os.path.isfile(filename):
LOG.info("%s was deleted, skipping.", filename)
continue
errors.extend(
validate_one_file(filename, _DELIVERABLE_SCHEMA, args.debug)
)
print('\n\n%s errors found' % len(errors))
for e in errors:
print(e)
return 1 if errors else 0