Coverage for python/lsst/ctrl/mpexec/cli/cmd/commands.py: 83%
69 statements
« prev ^ index » next coverage.py v6.4, created at 2022-05-26 09:46 +0000
« prev ^ index » next coverage.py v6.4, created at 2022-05-26 09:46 +0000
1# This file is part of ctrl_mpexec.
2#
3# Developed for the LSST Data Management System.
4# This product includes software developed by the LSST Project
5# (http://www.lsst.org).
6# See the COPYRIGHT file at the top-level directory of this distribution
7# for details of code ownership.
8#
9# This program is free software: you can redistribute it and/or modify
10# it under the terms of the GNU General Public License as published by
11# the Free Software Foundation, either version 3 of the License, or
12# (at your option) any later version.
13#
14# This program is distributed in the hope that it will be useful,
15# but WITHOUT ANY WARRANTY; without even the implied warranty of
16# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17# GNU General Public License for more details.
18#
19# You should have received a copy of the GNU General Public License
20# along with this program. If not, see <http://www.gnu.org/licenses/>.
22from functools import partial
24import click
25import lsst.pipe.base.cli.opt as pipeBaseOpts
26from lsst.daf.butler.cli.opt import config_file_option, config_option, confirm_option, options_file_option
27from lsst.daf.butler.cli.utils import MWCtxObj, catch_and_exit, option_section, unwrap
29from .. import opt as ctrlMpExecOpts
30from .. import script
31from ..script import confirmable
32from ..utils import _ACTION_CONFIG, _ACTION_CONFIG_FILE, PipetaskCommand, makePipelineActions
34epilog = unwrap(
35 """Notes:
37--task, --delete, --config, --config-file, and --instrument action options can
38appear multiple times; all values are used, in order left to right.
40FILE reads command-line options from the specified file. Data may be
41distributed among multiple lines (e.g. one option per line). Data after # is
42treated as a comment and ignored. Blank lines and lines starting with # are
43ignored.)
44"""
45)
48def _collectActions(ctx, **kwargs):
49 """Extract pipeline building options, replace them with PipelineActions,
50 return updated `kwargs`.
52 Notes
53 -----
54 The pipeline actions (task, delete, config, config_file, and instrument)
55 must be handled in the order they appear on the command line, but the CLI
56 specification gives them all different option names. So, instead of using
57 the individual action options as they appear in kwargs (because
58 invocation order can't be known), we capture the CLI arguments by
59 overriding `click.Command.parse_args` and save them in the Context's
60 `obj` parameter. We use `makePipelineActions` to create a list of
61 pipeline actions from the CLI arguments and pass that list to the script
62 function using the `pipeline_actions` kwarg name, and remove the action
63 options from kwargs.
64 """
65 for pipelineAction in (
66 ctrlMpExecOpts.task_option.name(),
67 ctrlMpExecOpts.delete_option.name(),
68 config_option.name(),
69 config_file_option.name(),
70 pipeBaseOpts.instrument_option.name(),
71 ):
72 kwargs.pop(pipelineAction)
74 actions = makePipelineActions(MWCtxObj.getFrom(ctx).args)
75 mock_configs = []
76 pipeline_actions = []
77 for action in actions:
78 if action.label and action.label.endswith("-mock"): 78 ↛ 79line 78 didn't jump to line 79, because the condition on line 78 was never true
79 if action.action not in (_ACTION_CONFIG.action, _ACTION_CONFIG_FILE.action):
80 raise ValueError(f"Unexpected option for mock task config overrides: {action}")
81 mock_configs.append(action)
82 else:
83 pipeline_actions.append(action)
85 kwargs["mock_configs"] = mock_configs
86 kwargs["pipeline_actions"] = pipeline_actions
87 return kwargs
90@click.command(cls=PipetaskCommand, epilog=epilog, short_help="Build pipeline definition.")
91@click.pass_context
92@ctrlMpExecOpts.show_option()
93@ctrlMpExecOpts.pipeline_build_options()
94@option_section(sectionText="")
95@options_file_option()
96@catch_and_exit
97def build(ctx, **kwargs):
98 """Build and optionally save pipeline definition.
100 This does not require input data to be specified.
101 """
102 kwargs = _collectActions(ctx, **kwargs)
103 script.build(**kwargs)
106@click.command(cls=PipetaskCommand, epilog=epilog)
107@click.pass_context
108@ctrlMpExecOpts.show_option()
109@ctrlMpExecOpts.pipeline_build_options()
110@ctrlMpExecOpts.qgraph_options()
111@ctrlMpExecOpts.butler_options()
112@option_section(sectionText="")
113@options_file_option()
114@catch_and_exit
115def qgraph(ctx, **kwargs):
116 """Build and optionally save quantum graph."""
117 kwargs = _collectActions(ctx, **kwargs)
118 pipeline = script.build(**kwargs)
119 script.qgraph(pipelineObj=pipeline, **kwargs)
122@click.command(cls=PipetaskCommand, epilog=epilog)
123@ctrlMpExecOpts.run_options()
124@catch_and_exit
125def run(ctx, **kwargs):
126 """Build and execute pipeline and quantum graph."""
127 kwargs = _collectActions(ctx, **kwargs)
128 pipeline = script.build(**kwargs)
129 qgraph = script.qgraph(pipelineObj=pipeline, **kwargs)
130 script.run(qgraphObj=qgraph, **kwargs)
133@click.command(cls=PipetaskCommand)
134@ctrlMpExecOpts.butler_config_option()
135@ctrlMpExecOpts.collection_argument()
136@confirm_option()
137@ctrlMpExecOpts.recursive_option(
138 help="""If the parent CHAINED collection has child CHAINED collections,
139 search the children until nested chains that start with the parent's name
140 are removed."""
141)
142def purge(confirm, **kwargs):
143 """Remove a CHAINED collection and its contained collections.
145 COLLECTION is the name of the chained collection to purge. it must not be a
146 child of any other CHAINED collections
148 Child collections must be members of exactly one collection.
150 The collections that will be removed will be printed, there will be an
151 option to continue or abort (unless using --no-confirm).
152 """
153 confirmable.confirm(partial(script.purge, **kwargs), confirm)
156@click.command(cls=PipetaskCommand)
157@ctrlMpExecOpts.butler_config_option()
158@ctrlMpExecOpts.collection_argument()
159@confirm_option()
160def cleanup(confirm, **kwargs):
161 """Remove non-members of CHAINED collections.
163 Removes collections that start with the same name as a CHAINED
164 collection but are not members of that collection.
165 """
166 confirmable.confirm(partial(script.cleanup, **kwargs), confirm)