Refactor all parameters to configuration.yaml

This change moves parameter from utils.py and index.rst to the
configuration.yaml. Moreover this change does:

* Use ISO 8601 dateformat in configuration
* Change events extension to use datetime instead of calendar
* Add a configuration extension to render doc substitutions

Change-Id: Ie35cb9ae2c334814afaa36b3afd606c8bcf62616
This commit is contained in:
Tristan Cacqueray 2016-11-07 03:23:46 +00:00
parent f6507b695d
commit df232c3074
15 changed files with 91 additions and 42 deletions

View File

@ -1,4 +1,16 @@
---
release: ocata
tag: 'sept-2016-elections'
timeframe:
name: 'Mitaka-Newton'
start: '2015-09-05T00:00'
end: '2016-09-04T23:59'
email_deadline: '2016-09-18T23:59'
tc_seats: 6
timeline:
- name: 'PTL nomination'
start: '2016-09-12T00:00'
@ -12,3 +24,6 @@ timeline:
- name: 'TC elections'
start: '2016-10-03T00:00'
end: '2016-10-09T23:45'
past_elections:
- ocata

View File

@ -83,7 +83,7 @@ def build_lists(app):
" :titlesonly:",
""
]
for previous in utils.PAST_ELECTIONS:
for previous in utils.conf['past_elections']:
if build_archive(previous, "ptl"):
previous_toc.append(" %s/ptl.rst" % previous)
if build_archive(previous, "tc"):

View File

@ -0,0 +1,4 @@
.. |Timeframe| replace:: {{ timeframe['name'] }} timeframe ({{ timeframe['start_str'] }} to {{ timeframe['end_str'] }})
.. |PreferredEmailDeadLine| replace:: {{ timeframe['email_deadline_str'] }}
.. |Projects.yaml| replace:: https://git.openstack.org/cgit/openstack/governance/tree/reference/projects.yaml?id={{ tag }}
.. |TCSeats| replace:: {{ tc_seats }}

View File

@ -0,0 +1,35 @@
# 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.
"""Build configuration substitution
"""
import jinja2
import jinja2.environment
import os
from openstack_election.utils import conf
def build_configuration(app):
output_file = os.path.join(".", "doc", "source", "configuration.rst")
template_dir = os.path.join(".", "doc", "source", "_exts")
loader = jinja2.FileSystemLoader(template_dir)
env = jinja2.environment.Environment(trim_blocks=True, loader=loader)
template = env.get_template("configuration.jinja")
with open(output_file, "w") as out:
out.write(template.render(conf))
def setup(app):
app.info('loading configuration extension')
app.connect('builder-inited', build_configuration)

View File

@ -5,7 +5,7 @@
<script>
var events_timeline = [
{% for event in events %}
{ start: "{{ event['start'] }}", end: "{{ event['end'] }}", name: "{{ event['name'] }}" },
{ start: "{{ event['start_iso'] }}", end: "{{ event['end_iso'] }}", name: "{{ event['name'] }}" },
{% endfor %}
];
</script>

View File

@ -13,30 +13,23 @@
"""Add election timer data
"""
import calendar
import datetime
import jinja2
import jinja2.environment
import os
import time
import pytz
from openstack_election import utils
def build_timer(app):
app.add_javascript("event_timer.js")
now = time.time()
now = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
first_event = True
for ev in utils.conf['timeline']:
ds, hs = ev['start'].split('T')
de, he = ev['end'].split('T')
start_time = calendar.timegm(
time.strptime(ev['start'], "%Y-%m-%dT%H:%M"))
end_time = calendar.timegm(
time.strptime(ev['end'], "%Y-%m-%dT%H:%M"))
if start_time > now:
if ev['start'] > now:
ev['status'] = 'future'
elif end_time > now:
elif ev['end'] > now:
ev['status'] = 'current'
else:
ev['status'] = 'past'
@ -51,8 +44,8 @@ def build_timer(app):
elif ev['status'] == 'past':
mark = '*'
ev['start_str'] = "%s%s, %s UTC%s" % (mark, ds, hs, mark)
ev['end_str'] = "%s%s, %s UTC%s" % (mark, de, he, mark)
ev['start_iso'] = ev['start'].strftime("%Y-%m-%dT%H:%M")
ev['end_iso'] = ev['end'].strftime("%Y-%m-%dT%H:%M")
ev['name_str'] = "%s%s%s" % (mark, ev['name'], mark)
output_file = os.path.join(".", "doc", "source", "events.rst")
with open(output_file, "w") as out:

View File

@ -32,6 +32,7 @@ extensions = [
'oslosphinx',
'candidates',
'events',
'configuration',
]
todo_include_todos = True

View File

@ -1,8 +1,4 @@
.. TODO: Update below definition for new elections
.. |Timeframe| replace:: Mitaka-Newton timeframe (September 5, 2015 00:00 UTC to September 4, 2016 23:59 UTC)
.. |PreferredEmailDeadLine| replace:: September 18, 2016
.. |Projects.yaml| replace:: http://git.openstack.org/cgit/openstack/governance/tree/reference/projects.yaml?id=sept-2016-elections
.. |TCSeats| replace:: 6
.. include:: configuration.rst
==================
OpenStack Election

View File

@ -31,6 +31,7 @@ def check_candidate(project_name, email, projects, limit=1):
found = 0
branch = None
timeframe = utils.conf['timeframe']
if project_name in ['Stable branch maintenance']:
project_list = projects.values()
@ -50,8 +51,8 @@ def check_candidate(project_name, email, projects, limit=1):
for repo_name in deliverable["repos"]:
query = ('is:merged after:"%s" before:"%s" '
'owner:%s project:%s' %
(utils.gerrit_datetime(utils.PERIOD_START),
utils.gerrit_datetime(utils.PERIOD_END),
(utils.gerrit_datetime(timeframe['start']),
utils.gerrit_datetime(timeframe['end']),
email, repo_name))
if branch:
query += (' branch:%s' % (branch))
@ -70,7 +71,7 @@ def check_candidate(project_name, email, projects, limit=1):
return found
def check_candidacy_review(change_id, limit=1, tag=utils.PROJECTS_TAG,
def check_candidacy_review(change_id, limit=1, tag=utils.conf['tag'],
review=None):
projects = utils.get_projects(tag=tag)
# If there is more than one review that matches this change_id then all

View File

@ -23,7 +23,7 @@ from openstack_election import utils
def get_reviews():
return utils.get_reviews('is:open project:%s file:^%s/%s/.*' %
(utils.ELECTION_REPO, utils.CANDIDATE_PATH,
utils.SERIES_NAME))
utils.conf['release']))
def main():
@ -34,7 +34,7 @@ def main():
help=('How many validating changes to report. '
'A negative value means report many. '
'Default: %(default)s'))
parser.add_argument('--tag', dest='tag', default=utils.PROJECTS_TAG,
parser.add_argument('--tag', dest='tag', default=utils.conf['tag'],
help=('The governance tag to validate against. '
'Default: %(default)s'))

View File

@ -29,7 +29,7 @@ def main():
help=('How many validating changes to report. '
'A negative value means report many. '
'Default: %(default)s'))
parser.add_argument('--tag', dest='tag', default=utils.PROJECTS_TAG,
parser.add_argument('--tag', dest='tag', default=utils.conf['tag'],
help=('The governance tag to validate against. '
'Default: %(default)s'))

View File

@ -32,7 +32,7 @@ def main():
help=('How many validating changes to report. '
'A negative value means report many. '
'Default: %(default)s'))
parser.add_argument('--tag', dest='tag', default=utils.PROJECTS_TAG,
parser.add_argument('--tag', dest='tag', default=utils.conf['tag'],
help=('The governance tag to validate against. '
'Default: %(default)s'))

View File

@ -74,7 +74,7 @@ def main():
parser = argparse.ArgumentParser(description=desc)
parser.add_argument('-v', '--verbose', action="count", default=0,
help='Increase program verbosity')
parser.add_argument('-r', '--release', default=utils.SERIES_NAME,
parser.add_argument('-r', '--release', default=utils.conf['release'],
help='Which nominations to look at')
parser.add_argument('-b', '--basedir',
default=os.getcwd(),

View File

@ -66,7 +66,7 @@ def main():
parser = argparse.ArgumentParser(description='Investigate Nominations')
parser.add_argument('-v', '--verbose', action="count", default=0,
help='Increase program verbosity')
parser.add_argument('-r', '--release', default=utils.SERIES_NAME,
parser.add_argument('-r', '--release', default=utils.conf['release'],
help='Which nominations to look at')
parser.add_argument('-b', '--basedir',
default=os.getcwd(),

View File

@ -26,14 +26,6 @@ import time
import urllib
import yaml
# Per election constants
SERIES_NAME = 'ocata'
# 2015-09-05 00:00:00 +0000
PERIOD_START = datetime.datetime(2015, 9, 5, 0, 0, 0, tzinfo=pytz.utc)
# 2016-09-04 23:59:59 +0000
PERIOD_END = datetime.datetime(2016, 9, 4, 23, 59, 59, tzinfo=pytz.utc)
PROJECTS_TAG = 'sept-2016-elections'
# Library constants
CANDIDATE_PATH = 'candidates'
@ -42,10 +34,22 @@ ELECTION_REPO = 'openstack/election'
CGIT_URL = 'https://git.openstack.org/cgit'
PROJECTS_URL = ('%s/openstack/governance/plain/reference/projects.yaml' %
(CGIT_URL))
TIME_FMT = "%b %d, %Y %H:%M %Z"
PAST_ELECTIONS = ['ocata']
# Election configuration
conf = yaml.load(open('configuration.yaml'))
# Convert time to datetime object
strptime = lambda x: datetime.datetime.strptime(
x, "%Y-%m-%dT%H:%M").replace(tzinfo=pytz.utc)
for key in ('start', 'end', 'email_deadline'):
conf['timeframe'][key] = strptime(conf['timeframe'][key])
conf['timeframe'][key+'_str'] = conf['timeframe'][key].strftime(TIME_FMT)
for event in conf['timeline']:
for key in ('start', 'end'):
event[key] = strptime(event[key])
event[key+'_str'] = event[key].strftime(TIME_FMT)
exceptions = None
@ -133,7 +137,7 @@ def check_atc_date(atc):
return False
expires_in = datetime.datetime.strptime(atc['expires-in'], '%B %Y')
expires_in = expires_in.replace(tzinfo=pytz.utc)
return PERIOD_END < expires_in
return conf['timeframe']['end'] < expires_in
def get_projects(tag=None):
@ -172,7 +176,7 @@ def dir2name(name, projects):
raise ValueError(('%s does not match any project' % (name)))
def build_candidates_list(election=SERIES_NAME):
def build_candidates_list(election=conf['release']):
project_list = os.listdir(os.path.join(CANDIDATE_PATH, election))
project_list.sort()
candidates_lists = {}