• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

nbiotcloud / ucdp / 19150419591

06 Nov 2025 09:27PM UTC coverage: 90.58% (+0.02%) from 90.564%
19150419591

push

github

web-flow
Merge pull request #133 from nbiotcloud/fix/traceback

fix traceback

10 of 14 new or added lines in 2 files covered. (71.43%)

4683 of 5170 relevant lines covered (90.58%)

10.86 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

78.0
/src/ucdp/cliutil.py
1
#
2
# MIT License
3
#
4
# Copyright (c) 2024-2025 nbiotcloud
5
#
6
# Permission is hereby granted, free of charge, to any person obtaining a copy
7
# of this software and associated documentation files (the "Software"), to deal
8
# in the Software without restriction, including without limitation the rights
9
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
# copies of the Software, and to permit persons to whom the Software is
11
# furnished to do so, subject to the following conditions:
12
#
13
# The above copyright notice and this permission notice shall be included in all
14
# copies or substantial portions of the Software.
15
#
16
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
# SOFTWARE.
23
#
24

25
"""Command Line Interface - Utilities."""
26

27
from collections.abc import Iterator
12✔
28
from logging import FATAL, getLogger
12✔
29
from pathlib import Path
12✔
30
from typing import IO, Any
12✔
31

32
import click
12✔
33
from rich.console import Console
12✔
34

35
from ucdp.finder import find
12✔
36
from ucdp.pathutil import improved_glob
12✔
37

38
PathType = click.Path(path_type=Path)
12✔
39

40

41
def auto_top(ctx, param, incomplete):
12✔
42
    """Autocompletion for TOP."""
43
    getLogger().setLevel(FATAL)
12✔
44
    infos = find(patterns=[f"{incomplete}*"], glob=True)
12✔
45
    return [str(info.topmodref) for info in infos]
12✔
46

47

48
def auto_path(ctr, param, incomplete):
12✔
49
    """Autocompletion for Paths."""
50
    return [str(path) for path in improved_glob(Path(f"{incomplete}*"))]
12✔
51

52

53
arg_top = click.argument("top", envvar="UCDP_TOP", shell_complete=auto_top)
12✔
54
arg_tops = click.argument("tops", nargs=-1, envvar="UCDP_TOP", shell_complete=auto_top)
12✔
55
opt_topsfile = click.option(
12✔
56
    "--tops-file",
57
    type=click.Path(path_type=Path),
58
    default=[],
59
    multiple=True,
60
    help="File with Top Module References",
61
)
62

63
opt_path = click.option(
12✔
64
    "--path",
65
    "-p",
66
    default=[],
67
    multiple=True,
68
    envvar="UCDP_PATH",
69
    type=click.Path(path_type=Path),
70
    shell_complete=auto_path,
71
    help="""
72
Search Path For Data Model And Template Files.
73
This option can be specified multiple times.
74
Environment Variable 'UCDP_PATH'.
75
""",
76
)
77
opt_filelist = click.option(
12✔
78
    "--filelist",
79
    "-f",
80
    multiple=True,
81
    help="Filelist Names. Environment Variable 'UCDP_FILELIST'.",
82
    envvar="UCDP_FILELIST",
83
)
84
opt_target = click.option(
12✔
85
    "--target",
86
    "-t",
87
    help="Filter File List for Target. Environment Variable 'UCDP_TARGET'.",
88
    envvar="UCDP_TARGET",
89
)
90
opt_show_diff = click.option(
12✔
91
    "--show-diff",
92
    "-s",
93
    default=False,
94
    is_flag=True,
95
    help="Show What Changed. Environment Variable 'UCDP_SHOW_DIFF'.",
96
    envvar="UCDP_SHOW_DIFF",
97
)
98
opt_maxlevel = click.option("--maxlevel", "-L", type=int, help="Limit to maximum number of hierarchy levels.")
12✔
99
opt_dry_run = click.option("--dry-run", default=False, is_flag=True, help="Do nothing.")
12✔
100
opt_maxworkers = click.option(
12✔
101
    "--maxworkers",
102
    "-J",
103
    type=int,
104
    help="Maximum Number of Processes.",
105
    envvar="UCDP_MAXWORKERS",
106
)
107
opt_defines = click.option(
12✔
108
    "--define",
109
    "-D",
110
    multiple=True,
111
    type=str,
112
    help="Defines set on the datamodel. Environment Variable 'UCDP_DEFINES'",
113
    envvar="UCDP_DEFINES",
114
)
115
opt_file = click.option(
12✔
116
    "--file",
117
    "-o",
118
    type=click.File("w"),
119
    shell_complete=auto_path,
120
    help="Output to file instead of STDOUT",
121
)
122
opt_filepath = click.option(
12✔
123
    "--file",
124
    "-o",
125
    type=click.Path(path_type=Path),
126
    shell_complete=auto_path,
127
    help="Output to file instead of STDOUT",
128
)
129
opt_tag = click.option(
12✔
130
    "--tag",
131
    "-G",
132
    default=[],
133
    multiple=True,
134
    help="Filter Modules by Tag Name or Wildcard.",
135
)
136
arg_template_filepaths = click.argument(
12✔
137
    "template_filepaths",
138
    type=PathType,
139
    shell_complete=auto_path,
140
    nargs=-1,
141
    envvar="UCDP_TEMPLATE_FILEPATHS",
142
)
143
opt_local = click.option(
12✔
144
    "--local/--no-local",
145
    "-l/-L",
146
    default=True,
147
    is_flag=True,
148
    help="List local/non-local modules only. Selected by default.",
149
)
150
opt_check = click.option(
12✔
151
    "--check",
152
    default=False,
153
    is_flag=True,
154
    help="Report an error if any file changes.",
155
)
156
opt_create = click.option(
12✔
157
    "--create",
158
    "-c",
159
    default=False,
160
    is_flag=True,
161
    help="Create missing inplace files.",
162
)
163
opt_clean = click.option(
12✔
164
    "--clean",
165
    "-n",
166
    default=False,
167
    is_flag=True,
168
    help="Remove obsolete fully-generated files.",
169
)
170

171

172
def defines2data(defines: list[str]) -> dict[str, str]:
12✔
173
    """Convert defines to data."""
174
    return dict(define.split("=", 1) if "=" in define else (define, None) for define in defines)
×
175

176

177
def read_file(filepath: Path) -> Iterator[str]:
12✔
178
    """Read File."""
179
    with filepath.open() as file:
×
180
        for line in file:
×
181
            line = line.strip()  # noqa: PLW2901
×
182
            if line.startswith("#"):
×
183
                continue
×
184
            if line:
×
185
                yield line
×
186

187

188
class Exit(click.ClickException):
12✔
189
    """Graceful Exit."""
190

191
    def __init__(self, console: Console, message: str) -> None:
12✔
NEW
192
        super().__init__(message)
×
NEW
193
        self.console = console
×
194

195
    def show(self, file: IO[Any] | None = None) -> None:
12✔
196
        """Show."""
NEW
197
        self.console.print(f"[red][bold]{self.message}.")
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc