Add list-views command line tool

Change-Id: I3c2e5790d4c01d72992d3cf1643d1dfb207fa2aa
Signed-off-by: Tyler Yankee <tyler.yankee@kitware.com>
This commit is contained in:
Tyler Yankee committed 2026-05-26 16:09:12 -04:00
1 parent 69287fa168
commit a0fa62d91b
4 files changed
+179

No files matched your search

+67
View File
@@ -0,0 +1,67 @@
#!/usr/bin/env python
# Copyright (C) 2018 Sorin Sbarnea
#
# 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 logging
import sys
from jenkins_jobs.builder import JenkinsManager
import jenkins_jobs.cli.subcommand.base as base
import jenkins_jobs.utils as utils
def list_duplicates(seq):
seen = set()
return set(x for x in seq if x in seen or seen.add(x))
class ListViewsSubCommand(base.JobsSubCommand):
def parse_args(self, subparser):
list = subparser.add_parser("list-views", help="List views")
self.parse_option_recursive_exclude(list)
list.add_argument("names", help="name(s) of view(s)", nargs="*", default=None)
list.add_argument(
"-p", "--path", default=None, help="path to YAML file or directory"
)
def execute(self, options, jjb_config):
views = self.get_views(jjb_config, options.path, options.names)
logging.info("Matching views: %d", len(views))
stdout = utils.wrap_stream(sys.stdout)
for view in views:
stdout.write((view + "\n").encode("utf-8"))
def get_views(self, jjb_config, path_list, glob_list):
if path_list:
roots = self.load_roots(jjb_config, path_list)
views = base.filter_matching(roots.generate_views(), glob_list)
view_names = [v.name for v in views]
else:
jenkins = JenkinsManager(jjb_config)
view_names = [
v["name"]
for v in jenkins.get_views()
if not glob_list or base.matches(v["name"], glob_list)
]
view_names = sorted(view_names)
for duplicate in list_duplicates(view_names):
logging.warning("Found duplicate view name '%s', likely bug.", duplicate)
logging.debug("Builder.get_views: returning %r", view_names)
return view_names
+1
View File
@@ -48,6 +48,7 @@ jjb.cli.subcommands =
delete-all=jenkins_jobs.cli.subcommand.delete_all:DeleteAllSubCommand
get-plugins-info=jenkins_jobs.cli.subcommand.get_plugins_info:GetPluginsInfoSubCommand
list=jenkins_jobs.cli.subcommand.list:ListSubCommand
list-views=jenkins_jobs.cli.subcommand.list_views:ListViewsSubCommand
jenkins_jobs.projects =
externaljob=jenkins_jobs.modules.project_externaljob:ExternalJob
flow=jenkins_jobs.modules.project_flow:Flow
+15
View File
@@ -0,0 +1,15 @@
- view:
name: 'bar001'
description: 'My first view'
- view:
name: 'bar002'
description: 'My second view'
- view:
name: 'baz001'
description: 'My third view'
- view:
name: 'bam001'
description: 'My fourth view'
+96
View File
@@ -0,0 +1,96 @@
#!/usr/bin/env python
# Copyright (C) 2018 Sorin Sbarnea
#
# 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.
from collections import namedtuple
import pytest
ViewsScenario = namedtuple("ViewsScenario", "name views globs found")
views_scenarios = [
ViewsScenario("single", views=["view1"], globs=[], found=["view1"]),
ViewsScenario(
"multiple", views=["view1", "view2"], globs=[], found=["view1", "view2"]
),
ViewsScenario(
"multiple_with_folder",
views=["folder1", "folder1/view1", "folder1/view2"],
globs=[],
found=["folder1", "folder1/view1", "folder1/view2"],
),
ViewsScenario(
"multiple_with_glob",
views=["view1", "view2", "view3"],
globs=["view[1-2]"],
found=["view1", "view2"],
),
ViewsScenario(
"multiple_with_multi_glob",
views=["view1", "view2", "view3", "view4"],
globs=["view1", "view[24]"],
found=["view1", "view2", "view4"],
),
]
@pytest.mark.parametrize(
"scenario",
[pytest.param(s, id=s.name) for s in views_scenarios],
)
def test_from_jenkins_tests(
capsys, mocker, default_config_file, execute_jenkins_jobs, scenario
):
def get_views():
return [{"name": name} for name in scenario.views]
mocker.patch("jenkins_jobs.builder.JenkinsManager.get_views", side_effect=get_views)
args = ["--conf", default_config_file, "list-views"] + scenario.globs
execute_jenkins_jobs(args)
expected_out = "\n".join(scenario.found)
captured = capsys.readouterr()
assert captured.out.rstrip() == expected_out
YamlScenario = namedtuple("YamlScnenario", "name globs found")
yaml_scenarios = [
YamlScenario("all", globs=[], found=["bam001", "bar001", "bar002", "baz001"]),
YamlScenario(
"some",
globs=["*am*", "*002", "bar001"],
found=["bam001", "bar001", "bar002"],
),
]
@pytest.mark.parametrize(
"scenario",
[pytest.param(s, id=s.name) for s in yaml_scenarios],
)
def test_from_yaml_tests(
capsys, fixtures_dir, default_config_file, execute_jenkins_jobs, scenario
):
path = fixtures_dir / "cmd-003.yaml"
execute_jenkins_jobs(
["--conf", default_config_file, "list-views", "-p", str(path)] + scenario.globs
)
expected_out = "\n".join(scenario.found)
captured = capsys.readouterr()
assert captured.out.rstrip() == expected_out