Add tool/framework to automatically validate the tag applications.
Add tools/validate_tags.py framework to automatically validate the usage of tags in reference/projects.yaml. This is only for tags that can be enforced pragmatically. This is not intended for gating purposes, rather to make the process of updating projects.yaml easier. Supports both team and repository based tags. Updated diversity.py to work with validate_tags Change-Id: Id477bfcfccb4dbf5f03f328273c9487ccc48e054
This commit is contained in:
parent
3f3e53e0bd
commit
bf8d72ea96
32
tools/base.py
Normal file
32
tools/base.py
Normal file
@ -0,0 +1,32 @@
|
||||
# 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.
|
||||
|
||||
import abc
|
||||
|
||||
|
||||
class ValidatorBase(object):
|
||||
__metaclass__ = abc.ABCMeta
|
||||
|
||||
@staticmethod
|
||||
@abc.abstractmethod
|
||||
def get_tag_name():
|
||||
"""Return tag name."""
|
||||
return
|
||||
|
||||
@staticmethod
|
||||
@abc.abstractmethod
|
||||
def validate(name):
|
||||
"""Return True if name should have the tag.
|
||||
|
||||
Where name can be a team or repo
|
||||
"""
|
||||
return
|
@ -18,6 +18,8 @@ import sys
|
||||
import requests
|
||||
import yaml
|
||||
|
||||
import base
|
||||
|
||||
s = requests.session()
|
||||
|
||||
|
||||
@ -85,6 +87,23 @@ def get_diversity(project):
|
||||
print '%-18s (%.2f%% | %.2f%% | %.2f%% | %.2f%%)' % (
|
||||
'', commits_top2, reviews_top2, core_reviews_top2,
|
||||
core_reviewers_top2)
|
||||
is_diverse = (commits_top <= 50 and reviews_top <= 50 and
|
||||
core_reviews_top <= 50 and core_reviewers_top <= 50 and
|
||||
commits_top2 <= 80 and reviews_top2 <= 80 and
|
||||
core_reviews_top2 <= 80 and core_reviewers_top2 <= 80)
|
||||
return is_diverse
|
||||
|
||||
|
||||
class ValidateDiversity(base.ValidatorBase):
|
||||
|
||||
@staticmethod
|
||||
def validate(team):
|
||||
"""Return True of team should contain the tag 'team:diverse-affiliation'"""
|
||||
return get_diversity(team)
|
||||
|
||||
@staticmethod
|
||||
def get_tag_name():
|
||||
return "team:diverse-affiliation"
|
||||
|
||||
|
||||
def main():
|
||||
|
96
tools/validate_tags.py
Executable file
96
tools/validate_tags.py
Executable file
@ -0,0 +1,96 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# 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.
|
||||
|
||||
""" validate tag applications in projects.yaml
|
||||
|
||||
Validate the application of tags that can be pragmatically applied.
|
||||
|
||||
Note: Does not automatically update projects.yaml since doing so can reformat
|
||||
and reorder projects.yaml
|
||||
|
||||
"""
|
||||
|
||||
import diversity
|
||||
|
||||
import requests
|
||||
import yaml
|
||||
|
||||
import os
|
||||
import sys
|
||||
import urllib
|
||||
|
||||
# List of modules to validate team based tags
|
||||
team_validators = [
|
||||
diversity.ValidateDiversity,
|
||||
]
|
||||
|
||||
# List of modules to validate repository based tags
|
||||
repo_validators = [
|
||||
]
|
||||
|
||||
|
||||
def main():
|
||||
filename = os.path.abspath('reference/projects.yaml')
|
||||
with open(filename, 'r') as f:
|
||||
teams = yaml.load(f.read())
|
||||
for team in teams:
|
||||
# Check team based tags
|
||||
for validator in team_validators:
|
||||
validate(team, teams[team], validator)
|
||||
# Check repo based tags
|
||||
for repo in teams[team]['projects']:
|
||||
repo_name = repo['repo']
|
||||
if not repo_exists(repo_name):
|
||||
continue
|
||||
for validator in repo_validators:
|
||||
validate(repo_name, repo, validator)
|
||||
|
||||
|
||||
def validate(name, data, validator):
|
||||
tag_name = validator.get_tag_name()
|
||||
contains_tag = any([tag_name == tag['name'] for tag in
|
||||
data.get('tags', [])])
|
||||
if validator.validate(name):
|
||||
# should contain tag
|
||||
if not contains_tag:
|
||||
print_tag_missing(name, tag_name)
|
||||
else:
|
||||
# should not contain tag
|
||||
if contains_tag:
|
||||
print_bad_tag(name, tag_name)
|
||||
|
||||
|
||||
def repo_exists(repo):
|
||||
"""Sometimes the governance docs can get out of sync with repo names."""
|
||||
response = requests.get(
|
||||
'https://review.openstack.org:443/projects/%s/' %
|
||||
urllib.quote_plus(repo))
|
||||
# strip off first few chars because 'the JSON response body starts with
|
||||
# a magic prefix line that must be stripped before feeding the rest of
|
||||
# the response body to a JSON parser'
|
||||
# https://review.openstack.org/Documentation/rest-api.html
|
||||
if response.status_code == 404:
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def print_tag_missing(name, tag):
|
||||
print ("* %s should have the tag '%s'" % (name, tag))
|
||||
|
||||
|
||||
def print_bad_tag(name, tag):
|
||||
print ("* %s should not have the tag '%s'" % (name, tag))
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(main())
|
Loading…
Reference in New Issue
Block a user