Coverage for python/lsst/ctrl/mpexec/cli/cmd/commands.py: 83%
70 statements
« prev ^ index » next coverage.py v6.4.1, created at 2022-06-29 10:41 +0000
« prev ^ index » next coverage.py v6.4.1, created at 2022-06-29 10:41 +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
23from typing import Any
25import click
26import lsst.pipe.base.cli.opt as pipeBaseOpts
27from lsst.daf.butler.cli.opt import config_file_option, config_option, confirm_option, options_file_option
28from lsst.daf.butler.cli.utils import MWCtxObj, catch_and_exit, option_section, unwrap
30from .. import opt as ctrlMpExecOpts
31from .. import script
32from ..script import confirmable
33from ..utils import _ACTION_CONFIG, _ACTION_CONFIG_FILE, PipetaskCommand, makePipelineActions
35epilog = unwrap(
36 """Notes:
38--task, --delete, --config, --config-file, and --instrument action options can
39appear multiple times; all values are used, in order left to right.
41FILE reads command-line options from the specified file. Data may be
42distributed among multiple lines (e.g. one option per line). Data after # is
43treated as a comment and ignored. Blank lines and lines starting with # are
44ignored.)
45"""
46)
49def _collectActions(ctx: click.Context, **kwargs: Any) -> dict[str, Any]:
50 """Extract pipeline building options, replace them with PipelineActions,
51 return updated `kwargs`.
53 Notes
54 -----
55 The pipeline actions (task, delete, config, config_file, and instrument)
56 must be handled in the order they appear on the command line, but the CLI
57 specification gives them all different option names. So, instead of using
58 the individual action options as they appear in kwargs (because
59 invocation order can't be known), we capture the CLI arguments by
60 overriding `click.Command.parse_args` and save them in the Context's
61 `obj` parameter. We use `makePipelineActions` to create a list of
62 pipeline actions from the CLI arguments and pass that list to the script
63 function using the `pipeline_actions` kwarg name, and remove the action
64 options from kwargs.
65 """
66 for pipelineAction in (
67 ctrlMpExecOpts.task_option.name(),
68 ctrlMpExecOpts.delete_option.name(),
69 config_option.name(),
70 config_file_option.name(),
71 pipeBaseOpts.instrument_option.name(),
72 ):
73 kwargs.pop(pipelineAction)
75 actions = makePipelineActions(MWCtxObj.getFrom(ctx).args)
76 mock_configs = []
77 pipeline_actions = []
78 for action in actions:
79 if action.label and action.label.endswith("-mock"): 79 ↛ 80line 79 didn't jump to line 80, because the condition on line 79 was never true
80 if action.action not in (_ACTION_CONFIG.action, _ACTION_CONFIG_FILE.action):
81 raise ValueError(f"Unexpected option for mock task config overrides: {action}")
82 mock_configs.append(action)
83 else:
84 pipeline_actions.append(action)
86 kwargs["mock_configs"] = mock_configs
87 kwargs["pipeline_actions"] = pipeline_actions
88 return kwargs
91@click.command(cls=PipetaskCommand, epilog=epilog, short_help="Build pipeline definition.")
92@click.pass_context
93@ctrlMpExecOpts.show_option()
94@ctrlMpExecOpts.pipeline_build_options()
95@option_section(sectionText="")
96@options_file_option()
97@catch_and_exit
98def build(ctx: click.Context, **kwargs: Any) -> None:
99 """Build and optionally save pipeline definition.
101 This does not require input data to be specified.
102 """
103 kwargs = _collectActions(ctx, **kwargs)
104 script.build(**kwargs)
107@click.command(cls=PipetaskCommand, epilog=epilog)
108@click.pass_context
109@ctrlMpExecOpts.show_option()
110@ctrlMpExecOpts.pipeline_build_options()
111@ctrlMpExecOpts.qgraph_options()
112@ctrlMpExecOpts.butler_options()
113@option_section(sectionText="")
114@options_file_option()
115@catch_and_exit
116def qgraph(ctx: click.Context, **kwargs: Any) -> None:
117 """Build and optionally save quantum graph."""
118 kwargs = _collectActions(ctx, **kwargs)
119 pipeline = script.build(**kwargs)
120 script.qgraph(pipelineObj=pipeline, **kwargs)
123@click.command(cls=PipetaskCommand, epilog=epilog)
124@ctrlMpExecOpts.run_options()
125@catch_and_exit
126def run(ctx: click.Context, **kwargs: Any) -> None:
127 """Build and execute pipeline and quantum graph."""
128 kwargs = _collectActions(ctx, **kwargs)
129 pipeline = script.build(**kwargs)
130 qgraph = script.qgraph(pipelineObj=pipeline, **kwargs)
131 script.run(qgraphObj=qgraph, **kwargs)
134@click.command(cls=PipetaskCommand)
135@ctrlMpExecOpts.butler_config_option()
136@ctrlMpExecOpts.collection_argument()
137@confirm_option()
138@ctrlMpExecOpts.recursive_option(
139 help="""If the parent CHAINED collection has child CHAINED collections,
140 search the children until nested chains that start with the parent's name
141 are removed."""
142)
143def purge(confirm: bool, **kwargs: Any) -> None:
144 """Remove a CHAINED collection and its contained collections.
146 COLLECTION is the name of the chained collection to purge. it must not be a
147 child of any other CHAINED collections
149 Child collections must be members of exactly one collection.
151 The collections that will be removed will be printed, there will be an
152 option to continue or abort (unless using --no-confirm).
153 """
154 confirmable.confirm(partial(script.purge, **kwargs), confirm)
157@click.command(cls=PipetaskCommand)
158@ctrlMpExecOpts.butler_config_option()
159@ctrlMpExecOpts.collection_argument()
160@confirm_option()
161def cleanup(confirm: bool, **kwargs: Any) -> None:
162 """Remove non-members of CHAINED collections.
164 Removes collections that start with the same name as a CHAINED
165 collection but are not members of that collection.
166 """
167 confirmable.confirm(partial(script.cleanup, **kwargs), confirm)