Add support for project-templates
Change-Id: I0f86acd7fb5e049e5368249de52f9d81a99936d8
This commit is contained in:
parent
15afdbadc8
commit
4122b0b8f0
12
doc/source/example-autodoc.rst
Normal file
12
doc/source/example-autodoc.rst
Normal file
@ -0,0 +1,12 @@
|
||||
Auto Doc
|
||||
========
|
||||
|
||||
Auto Jobs
|
||||
---------
|
||||
|
||||
.. autojobs::
|
||||
|
||||
Auto Project Templates
|
||||
----------------------
|
||||
|
||||
.. autoproject_templates::
|
20
doc/source/example-templates.rst
Normal file
20
doc/source/example-templates.rst
Normal file
@ -0,0 +1,20 @@
|
||||
Example Project Templates
|
||||
=========================
|
||||
|
||||
Project Templates
|
||||
-----------------
|
||||
|
||||
.. project_template:: example
|
||||
|
||||
This is an example project template. It contains the following jobs:
|
||||
|
||||
**check**
|
||||
|
||||
* :job:`example`
|
||||
* :job:`example`
|
||||
|
||||
**gate**
|
||||
|
||||
* :job:`example`
|
||||
|
||||
This is a project_template role: :project_template:`example`
|
@ -5,7 +5,9 @@
|
||||
|
||||
examples
|
||||
example-jobs
|
||||
example-templates
|
||||
example-roles
|
||||
example-autodoc
|
||||
|
||||
Indices and tables
|
||||
==================
|
||||
|
24
doc/source/zuul.d/test.yaml
Normal file
24
doc/source/zuul.d/test.yaml
Normal file
@ -0,0 +1,24 @@
|
||||
- job:
|
||||
name: test-autodoc
|
||||
description: |
|
||||
This is a test job.
|
||||
|
||||
- job:
|
||||
name: test-autodoc
|
||||
branches: stable
|
||||
description: |
|
||||
This is a test job variant on a stable branch.
|
||||
|
||||
- project-template:
|
||||
name: test-autotemplate
|
||||
description: |
|
||||
This is a test project template.
|
||||
check:
|
||||
jobs:
|
||||
- test-autodoc
|
||||
- example
|
||||
- does-not-exist-in-this-repo
|
||||
gate:
|
||||
jobs:
|
||||
- example
|
||||
- does-not-exist-in-this-repo
|
@ -12,6 +12,9 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from collections import OrderedDict
|
||||
import os
|
||||
|
||||
from sphinx import addnodes
|
||||
from docutils.parsers.rst import Directive
|
||||
from sphinx.domains import Domain, ObjType
|
||||
@ -19,14 +22,37 @@ from sphinx.roles import XRefRole
|
||||
from sphinx.directives import ObjectDescription
|
||||
from sphinx.util.nodes import make_refnode
|
||||
from docutils import nodes
|
||||
import os
|
||||
|
||||
import yaml
|
||||
|
||||
|
||||
class ProjectTemplate(object):
|
||||
def __init__(self, conf):
|
||||
self.name = conf['name']
|
||||
self.description = conf.get('description', '')
|
||||
self.pipelines = OrderedDict()
|
||||
self.parse(conf)
|
||||
|
||||
def parse(self, conf):
|
||||
for k in sorted(conf.keys()):
|
||||
v = conf[k]
|
||||
if not isinstance(v, dict):
|
||||
continue
|
||||
if 'jobs' not in v:
|
||||
continue
|
||||
jobs = []
|
||||
for job in v['jobs']:
|
||||
if isinstance(job, dict):
|
||||
job = list(dict.keys())[0]
|
||||
jobs.append(job)
|
||||
if jobs:
|
||||
self.pipelines[k] = jobs
|
||||
|
||||
|
||||
class Layout(object):
|
||||
def __init__(self):
|
||||
self.jobs = []
|
||||
self.project_templates = []
|
||||
|
||||
|
||||
class ZuulDirective(Directive):
|
||||
@ -51,6 +77,9 @@ class ZuulDirective(Directive):
|
||||
for obj in data:
|
||||
if 'job' in obj:
|
||||
layout.jobs.append(obj['job'])
|
||||
if 'project-template' in obj:
|
||||
layout.project_templates.append(
|
||||
ProjectTemplate(obj['project-template']))
|
||||
return layout
|
||||
|
||||
def parse_zuul_d(self, path):
|
||||
@ -61,6 +90,9 @@ class ZuulDirective(Directive):
|
||||
for obj in data:
|
||||
if 'job' in obj:
|
||||
layout.jobs.append(obj['job'])
|
||||
if 'project-template' in obj:
|
||||
layout.project_templates.append(
|
||||
ProjectTemplate(obj['project-template']))
|
||||
return layout
|
||||
|
||||
def _parse_zuul_layout(self):
|
||||
@ -103,6 +135,22 @@ class ZuulDirective(Directive):
|
||||
lines.append('')
|
||||
return lines
|
||||
|
||||
def generate_zuul_project_template_content(self, name):
|
||||
lines = []
|
||||
for template in self.zuul_layout.project_templates:
|
||||
if template.name == name:
|
||||
lines.append('.. zuul:project_template:: %s' % name)
|
||||
lines.append('')
|
||||
for l in template.description.split('\n'):
|
||||
lines.append(' ' + l)
|
||||
for pipeline, jobs in template.pipelines.items():
|
||||
lines.append('')
|
||||
lines.append(' **'+pipeline+'**')
|
||||
for job in jobs:
|
||||
lines.append(' * :zuul:xjob:`' + job + '`')
|
||||
lines.append('')
|
||||
return lines
|
||||
|
||||
def find_zuul_roles(self):
|
||||
root = os.path.dirname(self.zuul_layout_path)
|
||||
roledir = os.path.join(root, 'roles')
|
||||
@ -210,6 +258,22 @@ class ZuulJobDirective(ZuulObjectDescription):
|
||||
return sig
|
||||
|
||||
|
||||
class ZuulProjectTemplateDirective(ZuulObjectDescription):
|
||||
def before_content(self):
|
||||
path = self.env.ref_context.setdefault('zuul:attr_path', [])
|
||||
element = self.names[-1]
|
||||
path.append(element)
|
||||
|
||||
def after_content(self):
|
||||
path = self.env.ref_context.get('zuul:attr_path')
|
||||
if path:
|
||||
path.pop()
|
||||
|
||||
def handle_signature(self, sig, signode):
|
||||
signode += addnodes.desc_name(sig, sig)
|
||||
return sig
|
||||
|
||||
|
||||
class ZuulRoleDirective(ZuulObjectDescription):
|
||||
def before_content(self):
|
||||
path = self.env.ref_context.setdefault('zuul:attr_path', [])
|
||||
@ -409,6 +473,29 @@ class ZuulAutoJobsDirective(ZuulDirective):
|
||||
self.state_machine.insert_input(lines, self.zuul_layout_path)
|
||||
return []
|
||||
|
||||
class ZuulAutoProjectTemplateDirective(ZuulDirective):
|
||||
def run(self):
|
||||
name = self.content[0]
|
||||
lines = self.generate_zuul_project_template_content(name)
|
||||
self.state_machine.insert_input(lines, self.zuul_layout_path)
|
||||
return []
|
||||
|
||||
|
||||
class ZuulAutoProjectTemplatesDirective(ZuulDirective):
|
||||
has_content = False
|
||||
|
||||
def run(self):
|
||||
lines = []
|
||||
names = set()
|
||||
for template in self.zuul_layout.project_templates:
|
||||
name = template.name
|
||||
if name in names:
|
||||
continue
|
||||
lines.extend(self.generate_zuul_project_template_content(name))
|
||||
names.add(name)
|
||||
self.state_machine.insert_input(lines, self.zuul_layout_path)
|
||||
return []
|
||||
|
||||
|
||||
class ZuulAutoRoleDirective(ZuulDirective):
|
||||
def run(self):
|
||||
@ -447,6 +534,7 @@ class ZuulDomain(Domain):
|
||||
directives = {
|
||||
# Object description directives
|
||||
'job': ZuulJobDirective,
|
||||
'project_template': ZuulProjectTemplateDirective,
|
||||
'role': ZuulRoleDirective,
|
||||
'attr': ZuulAttrDirective,
|
||||
'value': ZuulValueDirective,
|
||||
@ -457,6 +545,8 @@ class ZuulDomain(Domain):
|
||||
# Autodoc directives
|
||||
'autojob': ZuulAutoJobDirective,
|
||||
'autojobs': ZuulAutoJobsDirective,
|
||||
'autoproject_template': ZuulAutoProjectTemplateDirective,
|
||||
'autoproject_templates': ZuulAutoProjectTemplatesDirective,
|
||||
'autorole': ZuulAutoRoleDirective,
|
||||
'autoroles': ZuulAutoRolesDirective,
|
||||
}
|
||||
@ -464,6 +554,11 @@ class ZuulDomain(Domain):
|
||||
roles = {
|
||||
'job': XRefRole(innernodeclass=nodes.inline, # type: ignore
|
||||
warn_dangling=True),
|
||||
'xjob': XRefRole(innernodeclass=nodes.inline, # type: ignore
|
||||
warn_dangling=False),
|
||||
'project_template':
|
||||
XRefRole(innernodeclass=nodes.inline, # type: ignore
|
||||
warn_dangling=True),
|
||||
'role': XRefRole(innernodeclass=nodes.inline, # type: ignore
|
||||
warn_dangling=True),
|
||||
'attr': XRefRole(innernodeclass=nodes.inline, # type: ignore
|
||||
@ -491,6 +586,8 @@ class ZuulDomain(Domain):
|
||||
def resolve_xref(self, env, fromdocname, builder, type, target,
|
||||
node, contnode):
|
||||
objects = self.data['objects']
|
||||
if type == 'xjob':
|
||||
type = 'job'
|
||||
name = type + '-' + target
|
||||
obj = objects.get(name)
|
||||
if obj:
|
||||
|
Loading…
Reference in New Issue
Block a user