Support sectioned views

Change-Id: Iaf352e8cc62644fb05afaae21630b9bec2cd30c0
This commit is contained in:
Jan Zerebecki 2019-10-28 15:22:17 +01:00
parent 587740ec75
commit 35d4da29d3
7 changed files with 191 additions and 14 deletions

View File

@ -310,18 +310,27 @@ DEFAULT_COLUMNS = [
class List(jenkins_jobs.modules.base.Base):
sequence = 0
def root_xml(self, data):
root = XML.Element("hudson.model.ListView")
def root_xml(self, data, sectioned=False):
name = "hudson.model.ListView"
if sectioned:
name = "hudson.plugins.sectioned__view.ListViewSection"
root = XML.Element(name)
mapping = [
("name", "name", None),
("description", "description", ""),
("filter-executors", "filterExecutors", False),
("filter-queue", "filterQueue", False),
]
mapping = [("name", "name", None)]
if not sectioned:
mapping.extend(
[
("description", "description", ""),
("filter-executors", "filterExecutors", False),
("filter-queue", "filterQueue", False),
]
)
helpers.convert_mapping_to_xml(root, data, mapping, fail_required=True)
XML.SubElement(root, "properties", {"class": "hudson.model.View$PropertyList"})
if not sectioned:
XML.SubElement(
root, "properties", {"class": "hudson.model.View$PropertyList"}
)
jn_xml = XML.SubElement(root, "jobNames")
jobnames = data.get("job-name", None)
@ -341,6 +350,13 @@ class List(jenkins_jobs.modules.base.Base):
filter = getattr(view_jobfilters, jobfilter.replace("-", "_"))
filter(job_filter_xml, jobfilters.get(jobfilter))
if sectioned:
mapping = [
("width", "width", "FULL", ["FULL", "HALF", "THIRD", "TWO_THIRDS"]),
("alignment", "alignment", "CENTER", ["CENTER", "LEFT", "RIGHT"]),
]
helpers.convert_mapping_to_xml(root, data, mapping, fail_required=True)
c_xml = XML.SubElement(root, "columns")
columns = data.get("columns", DEFAULT_COLUMNS)
@ -369,11 +385,11 @@ class List(jenkins_jobs.modules.base.Base):
x.append(XML.fromstring(tag))
else:
XML.SubElement(c_xml, COLUMN_DICT[column])
mapping = [
("regex", "includeRegex", None),
("recurse", "recurse", False),
("status-filter", "statusFilter", None),
]
mapping = [("regex", "includeRegex", None)]
if not sectioned:
mapping.extend(
[("recurse", "recurse", False), ("status-filter", "statusFilter", None)]
)
helpers.convert_mapping_to_xml(root, data, mapping, fail_required=False)
return root

View File

@ -0,0 +1,102 @@
# Copyright 2019 Openstack Foundation
# 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.
"""
The view sectioned module handles creating Jenkins Sectioned views.
To create a sectioned view specify ``sectioned`` in the ``view-type`` attribute
to the :ref:`view_sectioned` definition.
:View Parameters:
* **name** (`str`): The name of the view.
* **view-type** (`str`): The type of view.
* **description** (`str`): A description of the view. (default '')
* **filter-executors** (`bool`): Show only executors that can
execute the included views. (default false)
* **filter-queue** (`bool`): Show only included jobs in builder
queue. (default false)
* **sections** (`list`): The views to show in sections.
Example:
.. literalinclude::
/../../tests/views/fixtures/view_sectioned.yaml
"""
import xml.etree.ElementTree as XML
import jenkins_jobs.modules.base
import jenkins_jobs.modules.helpers as helpers
from jenkins_jobs.modules import view_list
class Sectioned(jenkins_jobs.modules.base.Base):
def root_xml(self, data):
root = XML.Element("hudson.plugins.sectioned__view.SectionedView")
mapping = [
("name", "name", None),
("description", "description", ""),
("filter-executors", "filterExecutors", False),
("filter-queue", "filterQueue", False),
]
helpers.convert_mapping_to_xml(root, data, mapping, fail_required=True)
XML.SubElement(root, "properties", {"class": "hudson.model.View$PropertyList"})
s_xml = XML.SubElement(root, "sections")
sections = data.get("sections", [])
for section in sections:
if "view-type" not in section:
raise KeyError("This sectioned view is missing a view-type.", section)
if section["view-type"] == "list":
project = view_list.List(self.registry)
elif section["view-type"] == "text":
project = SectionedText(self.registry)
else:
raise ValueError(
"Nested view-type %s is not known. Supported types: list, text."
% section["view-type"]
)
xml_project = project.root_xml(section, sectioned=True)
s_xml.append(xml_project)
return root
class SectionedText(jenkins_jobs.modules.base.Base):
def root_xml(self, data, sectioned=False):
assert sectioned
root = XML.Element("hudson.plugins.sectioned__view.TextSection")
# these are in the XML and look like from view_list,
# but the UI has no controls for them
jn_xml = XML.SubElement(root, "jobNames")
XML.SubElement(
jn_xml, "comparator", {"class": "hudson.util.CaseInsensitiveComparator"}
)
XML.SubElement(root, "jobFilters")
mapping = [
("name", "name", ""),
("width", "width", "FULL", ["FULL", "HALF", "THIRD", "TWO_THIRDS"]),
("alignment", "alignment", "CENTER", ["CENTER", "LEFT", "RIGHT"]),
("text", "text", None),
("style", "style", "NONE", ["NONE", "NOTE", "INFO", "WARNING", "TIP"]),
]
helpers.convert_mapping_to_xml(root, data, mapping, fail_required=True)
return root

View File

@ -66,6 +66,7 @@ jenkins_jobs.views =
list=jenkins_jobs.modules.view_list:List
nested=jenkins_jobs.modules.view_nested:Nested
pipeline=jenkins_jobs.modules.view_pipeline:Pipeline
sectioned=jenkins_jobs.modules.view_sectioned:Sectioned
jenkins_jobs.builders =
raw=jenkins_jobs.modules.general:raw
jenkins_jobs.reporters =

View File

@ -49,6 +49,7 @@ from jenkins_jobs.modules import view_all
from jenkins_jobs.modules import view_list
from jenkins_jobs.modules import view_nested
from jenkins_jobs.modules import view_pipeline
from jenkins_jobs.modules import view_sectioned
from jenkins_jobs.parser import YamlParser
from jenkins_jobs.registry import ModuleRegistry
from jenkins_jobs.xml_config import XmlJob
@ -242,6 +243,8 @@ class BaseScenariosTestCase(testscenarios.TestWithScenarios, BaseTestCase):
project = view_nested.Nested(registry)
elif yaml_content["view-type"] == "pipeline":
project = view_pipeline.Pipeline(registry)
elif yaml_content["view-type"] == "sectioned":
project = view_sectioned.Sectioned(registry)
else:
raise InvalidAttributeError("view-type", yaml_content["view-type"])

View File

@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<hudson.plugins.sectioned__view.SectionedView>
<name>SectionedViewTest</name>
<description/>
<filterExecutors>false</filterExecutors>
<filterQueue>false</filterQueue>
<properties class="hudson.model.View$PropertyList"/>
<sections>
<hudson.plugins.sectioned__view.ListViewSection>
<name>testName</name>
<jobNames>
<comparator class="hudson.util.CaseInsensitiveComparator"/>
<string>testJobName</string>
</jobNames>
<jobFilters/>
<width>HALF</width>
<alignment>LEFT</alignment>
<columns>
<hudson.views.JobColumn/>
</columns>
</hudson.plugins.sectioned__view.ListViewSection>
<hudson.plugins.sectioned__view.TextSection>
<jobNames>
<comparator class="hudson.util.CaseInsensitiveComparator"/>
</jobNames>
<jobFilters/>
<name/>
<width>FULL</width>
<alignment>CENTER</alignment>
<text>test text</text>
<style>INFO</style>
</hudson.plugins.sectioned__view.TextSection>
</sections>
</hudson.plugins.sectioned__view.SectionedView>

View File

@ -0,0 +1,14 @@
name: SectionedViewTest
view-type: sectioned
sections:
- name: testName
job-name:
- testJobName
columns:
- job
view-type: list
width: HALF
alignment: LEFT
- text: test text
style: INFO
view-type: text

View File

@ -17,6 +17,7 @@ from jenkins_jobs.modules import view_all
from jenkins_jobs.modules import view_list
from jenkins_jobs.modules import view_nested
from jenkins_jobs.modules import view_pipeline
from jenkins_jobs.modules import view_sectioned
from tests import base
@ -42,3 +43,9 @@ class TestCaseModuleViewPipeline(base.BaseScenariosTestCase):
fixtures_path = os.path.join(os.path.dirname(__file__), "fixtures")
scenarios = base.get_scenarios(fixtures_path)
klass = view_pipeline.Pipeline
class TestCaseModuleViewSectioned(base.BaseScenariosTestCase):
fixtures_path = os.path.join(os.path.dirname(__file__), "fixtures")
scenarios = base.get_scenarios(fixtures_path)
klass = view_sectioned.Sectioned