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

SwissDataScienceCenter / renku-python / 6875247711

15 Nov 2023 09:16AM UTC coverage: 82.786% (-0.05%) from 82.831%
6875247711

Pull #3300

github

web-flow
Merge e2d3269e8 into 4726f660e
Pull Request #3300: chore: do not always retry load tests requests

25441 of 30731 relevant lines covered (82.79%)

3.12 hits per line

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

96.9
/renku/ui/cli/__init__.py
1
# Copyright Swiss Data Science Center (SDSC). A partnership between
2
# École Polytechnique Fédérale de Lausanne (EPFL) and
3
# Eidgenössische Technische Hochschule Zürich (ETHZ).
4
#
5
# Licensed under the Apache License, Version 2.0 (the "License");
6
# you may not use this file except in compliance with the License.
7
# You may obtain a copy of the License at
8
#
9
#     http://www.apache.org/licenses/LICENSE-2.0
10
#
11
# Unless required by applicable law or agreed to in writing, software
12
# distributed under the License is distributed on an "AS IS" BASIS,
13
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
# See the License for the specific language governing permissions and
15
# limitations under the License.
16
r"""The base command for interacting with the Renku platform.
7✔
17

18
renku (base command)
19
********************
20

21
To list the available commands, either run ``renku`` with no parameters or
22
execute ``renku help``:
23

24
.. code-block:: console
25

26
    $ renku help
27
    Usage: renku [OPTIONS] COMMAND [ARGS]...
28

29
    Check common Renku commands used in various situations.
30

31

32
    Options:
33
      --version                       Print version number.
34
      --global-config-path            Print global application's config path.
35
      --path <path>                   Location of a Renku repository.
36
                                      [default: (dynamic)]
37
      --external-storage / -S, --no-external-storage
38
                                      Use an external file storage service.
39
      -h, --help                      Show this message and exit.
40

41
    Commands:
42
      # [...]
43

44
Configuration files
45
~~~~~~~~~~~~~~~~~~~
46

47
Depending on your system, you may find the configuration files used by Renku
48
command line in a different folder. By default, the following rules are used:
49

50
MacOS:
51
  ``~/Library/Application Support/Renku``
52
Unix:
53
  ``~/.config/renku``
54
Windows:
55
  ``C:\Users\<user>\AppData\Roaming\Renku``
56

57
If in doubt where to look for the configuration file, you can display its path
58
by running ``renku --global-config-path``.
59

60
.. cheatsheet::
61
   :group: Typical Workflow
62
   :command: $ git status
63
   :description: Take a look at what you have done since the last save.
64
   :target: ui,rp
65

66
.. cheatsheet::
67
   :group: Typical Workflow
68
   :command: $ renku save -m <msg>
69
   :description: Save your latest work, providing a message explaining what you have done.
70
   :target: ui,rp
71

72
.. cheatsheet::
73
   :group: Typical Workflow
74
   :command: $ renku run …
75
   :description: Run your code, capturing lineage of the inputs and outputs using Renku.
76
   :target: ui,rp
77

78
"""
79
import os
7✔
80
import sys
7✔
81
import uuid
7✔
82
from pathlib import Path
7✔
83

84
import click
7✔
85
import yaml
7✔
86
from click_plugins import with_plugins
7✔
87

88
from renku.command.options import option_external_storage_requested
7✔
89
from renku.command.util import WARNING
7✔
90
from renku.command.version import print_version
7✔
91
from renku.core import errors
7✔
92
from renku.core.constant import DATABASE_PATH
7✔
93
from renku.core.util.git import get_git_path
7✔
94
from renku.domain_model.project_context import project_context
7✔
95
from renku.ui.cli.clone import clone
7✔
96
from renku.ui.cli.config import config
7✔
97
from renku.ui.cli.dataset import dataset
7✔
98
from renku.ui.cli.doctor import doctor
7✔
99
from renku.ui.cli.env import env
7✔
100
from renku.ui.cli.exception_handler import IssueFromTraceback
7✔
101
from renku.ui.cli.gc import gc
7✔
102
from renku.ui.cli.githooks import githooks as githooks_command
7✔
103
from renku.ui.cli.graph import graph
7✔
104
from renku.ui.cli.init import init
7✔
105
from renku.ui.cli.log import log
7✔
106
from renku.ui.cli.login import credentials, login, logout
7✔
107
from renku.ui.cli.mergetool import mergetool
7✔
108
from renku.ui.cli.migrate import check_immutable_template_files, migrate, migrationscheck
7✔
109
from renku.ui.cli.move import move
7✔
110
from renku.ui.cli.project import project
7✔
111
from renku.ui.cli.remove import remove
7✔
112
from renku.ui.cli.rerun import rerun
7✔
113
from renku.ui.cli.rollback import rollback
7✔
114
from renku.ui.cli.run import run
7✔
115
from renku.ui.cli.save import save
7✔
116
from renku.ui.cli.service import service
7✔
117
from renku.ui.cli.session import session
7✔
118
from renku.ui.cli.status import status
7✔
119
from renku.ui.cli.storage import storage
7✔
120
from renku.ui.cli.template import template
7✔
121
from renku.ui.cli.update import update
7✔
122
from renku.ui.cli.workflow import workflow
7✔
123

124
try:
7✔
125
    from importlib.metadata import entry_points
7✔
126
except ImportError:
×
127
    from importlib_metadata import entry_points  # type: ignore
×
128

129

130
def get_entry_points(name: str):
7✔
131
    """Get entry points from importlib."""
132
    all_entry_points = entry_points()
7✔
133

134
    if hasattr(all_entry_points, "select"):
7✔
135
        return all_entry_points.select(group=name)  # type: ignore
7✔
136
    else:
137
        # Prior to Python 3.10, this returns a dict instead of the selection interface, which is slightly slower
138
        return all_entry_points.get(name, [])
×
139

140

141
WARNING_UNPROTECTED_COMMANDS = ["clone", "credentials", "env", "help", "init", "login", "logout", "service", "template"]
7✔
142

143
WARNING_UNPROTECTED_SUBCOMMANDS = {"template": ["ls", "show", "validate"]}
7✔
144

145

146
def _uuid_representer(dumper, data):
7✔
147
    """Add UUID serializer for YAML."""
148
    return dumper.represent_str(str(data))
×
149

150

151
def _is_renku_project(path: Path) -> bool:
7✔
152
    """Check if a path is a renku project."""
153
    from renku.core.constant import RENKU_HOME
6✔
154
    from renku.core.migration.utils import OLD_METADATA_PATH
6✔
155
    from renku.infrastructure.database import Database
6✔
156

157
    metadata_path = Path(path) / RENKU_HOME
6✔
158
    old_metadata = metadata_path / OLD_METADATA_PATH
6✔
159
    new_metadata = metadata_path / DATABASE_PATH / Database.ROOT_OID
6✔
160

161
    return old_metadata.exists() or new_metadata.exists()
6✔
162

163

164
yaml.add_representer(uuid.UUID, _uuid_representer)
7✔
165

166

167
def print_global_config_path(ctx, _, value):
7✔
168
    """Print global application's config path."""
169
    if not value or ctx.resilient_parsing:
6✔
170
        return
6✔
171

172
    click.echo(project_context.global_config_path)
1✔
173
    ctx.exit()
1✔
174

175

176
def is_allowed_subcommand(ctx):
7✔
177
    """Called from subcommands to check if their sub-subcommand is allowed.
178

179
    Subcommands where some sub-subcommands are allowed should be added to ``WARNING_UNPROTECTED_COMMANDS`` so they pass
180
    through the parent check and then added to ``WARNING_UNPROTECTED_SUBCOMMANDS`` so they get checked here.
181
    """
182
    from renku.domain_model.project_context import project_context
2✔
183

184
    if not _is_renku_project(project_context.path) and (
2✔
185
        not WARNING_UNPROTECTED_SUBCOMMANDS.get(ctx.command.name, False)
186
        or ctx.invoked_subcommand not in WARNING_UNPROTECTED_SUBCOMMANDS[ctx.command.name]
187
    ):
188
        raise errors.UsageError(
1✔
189
            f"{project_context.path} is not a renku repository.\n"
190
            "To initialize this as a renku repository use: 'renku init'"
191
        )
192

193

194
def is_allowed_command(ctx):
7✔
195
    """Check if invoked command contains help command."""
196

197
    return ctx.invoked_subcommand in WARNING_UNPROTECTED_COMMANDS or "-h" in sys.argv or "--help" in sys.argv
6✔
198

199

200
@with_plugins(get_entry_points("renku.cli_plugins"))
7✔
201
@click.group(
7✔
202
    cls=IssueFromTraceback, context_settings={"auto_envvar_prefix": "RENKU", "help_option_names": ["-h", "--help"]}
203
)
204
@click.option(
7✔
205
    "--version", is_flag=True, callback=print_version, expose_value=False, is_eager=True, help=print_version.__doc__
206
)
207
@click.option(
7✔
208
    "--global-config-path",
209
    is_flag=True,
210
    callback=print_global_config_path,
211
    expose_value=False,
212
    is_eager=True,
213
    help=print_global_config_path.__doc__,
214
)
215
@click.option(
7✔
216
    "--path", show_default=True, metavar="<path>", default=get_git_path, help="Location of a Renku repository."
217
)
218
@option_external_storage_requested
7✔
219
@click.pass_context
7✔
220
def cli(ctx, path, external_storage_requested):
7✔
221
    """Check common Renku commands used in various situations."""
222
    from renku.domain_model.project_context import project_context
6✔
223

224
    path = Path(path)
6✔
225

226
    is_command_allowed = is_allowed_command(ctx)
6✔
227
    is_renku_project = _is_renku_project(path)
6✔
228

229
    if not is_renku_project and not is_command_allowed:
6✔
230
        raise errors.UsageError(
1✔
231
            f"{path} is not a renku repository.\n" "To initialize this as a renku repository use: 'renku init'"
232
        )
233

234
    project_context.push_path(path)
6✔
235
    project_context.external_storage_requested = external_storage_requested
6✔
236

237
    if is_renku_project and path != Path(os.getcwd()) and not is_command_allowed:
6✔
238
        click.secho(WARNING + "Run CLI commands only from project's root directory.\n", err=True)
2✔
239

240

241
@cli.command()
7✔
242
@click.pass_context
7✔
243
def help(ctx):
7✔
244
    """Show help message and exit."""
245
    click.echo(ctx.parent.get_help())
2✔
246

247

248
# Register subcommands:
249
cli.add_command(check_immutable_template_files)
7✔
250
cli.add_command(clone)
7✔
251
cli.add_command(config)
7✔
252
cli.add_command(credentials)
7✔
253
cli.add_command(dataset)
7✔
254
cli.add_command(doctor)
7✔
255
cli.add_command(env)
7✔
256
cli.add_command(gc)
7✔
257
cli.add_command(githooks_command)
7✔
258
cli.add_command(graph)
7✔
259
cli.add_command(init)
7✔
260
cli.add_command(log)
7✔
261
cli.add_command(login)
7✔
262
cli.add_command(logout)
7✔
263
cli.add_command(mergetool)
7✔
264
cli.add_command(migrate)
7✔
265
cli.add_command(migrationscheck)
7✔
266
cli.add_command(move)
7✔
267
cli.add_command(project)
7✔
268
cli.add_command(remove)
7✔
269
cli.add_command(rerun)
7✔
270
cli.add_command(rollback)
7✔
271
cli.add_command(run)
7✔
272
cli.add_command(save)
7✔
273
cli.add_command(service)
7✔
274
cli.add_command(session)
7✔
275
cli.add_command(status)
7✔
276
cli.add_command(storage)
7✔
277
cli.add_command(template)
7✔
278
cli.add_command(update)
7✔
279
cli.add_command(workflow)
7✔
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

© 2025 Coveralls, Inc