Skip to content

Commit 8bef1b9

Browse files
feat(core): default sensible flags for update and export (#3342)
1 parent 57520c3 commit 8bef1b9

File tree

10 files changed

+106
-80
lines changed

10 files changed

+106
-80
lines changed

docs/_static/cheatsheet/cheatsheet.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@
212212
},
213213
{
214214
"command": "$ renku update [--all] [<path>...]",
215-
"description": "Update outdated output files created by renku run. With\n<path>'s: Only recreate these files. With --all: Update\nall outdated output files.",
215+
"description": "Update outdated output files created by renku run. With\n<path>'s: Only recreate these files. With --all (default):\nUpdate all outdated output files.",
216216
"target": [
217217
"rp"
218218
]
15 Bytes
Binary file not shown.

docs/cheatsheet_hash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
a724f061b19aaea186b057e0f630146b cheatsheet.tex
1+
ad86ac1d0614ccb692c96e893db4d20d cheatsheet.tex
22
c70c179e07f04186ec05497564165f11 sdsc_cheatsheet.cls

docs/cheatsheet_json_hash

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0a6b25f8560871427ac358cb69e9c216 cheatsheet.json
1+
1ac51267cefdf4976c29c9d7657063b8 cheatsheet.json

renku/command/update.py

Lines changed: 3 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -16,71 +16,16 @@
1616
# limitations under the License.
1717
"""Renku ``update`` command."""
1818

19-
from pathlib import Path
20-
from typing import List, Optional
21-
22-
from pydantic import validate_arguments
23-
2419
from renku.command.command_builder.command import Command
25-
from renku.core import errors
26-
from renku.core.errors import ParameterError
27-
from renku.core.util.os import get_relative_paths
28-
from renku.core.workflow.activity import (
29-
get_all_modified_and_deleted_activities_and_entities,
30-
get_downstream_generating_activities,
31-
is_activity_valid,
32-
sort_activities,
33-
)
34-
from renku.core.workflow.execute import execute_workflow_graph
35-
from renku.core.workflow.model.concrete_execution_graph import ExecutionGraph
36-
from renku.domain_model.project_context import project_context
3720

3821

3922
def update_command(skip_metadata_update: bool):
4023
"""Update existing files by rerunning their outdated workflow."""
41-
command = Command().command(_update).require_migration().require_clean()
24+
from renku.core.workflow.update import update
25+
26+
command = Command().command(update).require_migration().require_clean()
4227
if skip_metadata_update:
4328
command = command.with_database(write=False)
4429
else:
4530
command = command.with_database(write=True).with_commit()
4631
return command
47-
48-
49-
@validate_arguments(config=dict(arbitrary_types_allowed=True))
50-
def _update(
51-
update_all: bool,
52-
dry_run: bool,
53-
ignore_deleted: bool,
54-
provider: str,
55-
config: Optional[str],
56-
paths: Optional[List[str]] = None,
57-
):
58-
if not paths and not update_all and not dry_run:
59-
raise ParameterError("Either PATHS, --all/-a, or --dry-run/-n should be specified.")
60-
if paths and update_all:
61-
raise ParameterError("Cannot use PATHS and --all/-a at the same time.")
62-
63-
paths = paths or []
64-
paths = get_relative_paths(base=project_context.path, paths=[Path.cwd() / p for p in paths])
65-
66-
modified, _, _ = get_all_modified_and_deleted_activities_and_entities(project_context.repository)
67-
modified_activities = {a for a, _ in modified if not a.deleted and is_activity_valid(a)}
68-
modified_paths = {e.path for _, e in modified}
69-
70-
activities = get_downstream_generating_activities(
71-
starting_activities=modified_activities,
72-
paths=paths,
73-
ignore_deleted=ignore_deleted,
74-
project_path=project_context.path,
75-
)
76-
77-
if len(activities) == 0:
78-
raise errors.NothingToExecuteError()
79-
80-
# NOTE: When updating we only want to eliminate activities that are overridden, not their parents
81-
activities = sort_activities(activities, remove_overridden_parents=False)
82-
if dry_run:
83-
return activities, modified_paths
84-
85-
graph = ExecutionGraph([a.plan_with_values for a in activities], virtual_links=True)
86-
execute_workflow_graph(dag=graph.workflow_graph, provider=provider, config=config)

renku/core/workflow/update.py

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# -*- coding: utf-8 -*-
2+
#
3+
# Copyright 2018-2022- Swiss Data Science Center (SDSC)
4+
# A partnership between École Polytechnique Fédérale de Lausanne (EPFL) and
5+
# Eidgenössische Technische Hochschule Zürich (ETHZ).
6+
#
7+
# Licensed under the Apache License, Version 2.0 (the "License");
8+
# you may not use this file except in compliance with the License.
9+
# You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
"""Renku workflow update."""
19+
20+
from pathlib import Path
21+
from typing import List, Optional
22+
23+
from pydantic import validate_arguments
24+
25+
from renku.core import errors
26+
from renku.core.errors import ParameterError
27+
from renku.core.util.os import get_relative_paths
28+
from renku.core.workflow.activity import (
29+
get_all_modified_and_deleted_activities_and_entities,
30+
get_downstream_generating_activities,
31+
is_activity_valid,
32+
sort_activities,
33+
)
34+
from renku.core.workflow.execute import execute_workflow_graph
35+
from renku.core.workflow.model.concrete_execution_graph import ExecutionGraph
36+
from renku.domain_model.project_context import project_context
37+
38+
39+
@validate_arguments(config=dict(arbitrary_types_allowed=True))
40+
def update(
41+
update_all: bool,
42+
dry_run: bool,
43+
ignore_deleted: bool,
44+
provider: str,
45+
config: Optional[str],
46+
paths: Optional[List[str]] = None,
47+
):
48+
"""Update stale generated outputs."""
49+
if paths and update_all:
50+
raise ParameterError("Cannot use PATHS and --all/-a at the same time.")
51+
52+
paths = paths or []
53+
paths = get_relative_paths(base=project_context.path, paths=[Path.cwd() / p for p in paths])
54+
55+
modified, _, _ = get_all_modified_and_deleted_activities_and_entities(project_context.repository)
56+
modified_activities = {a for a, _ in modified if not a.deleted and is_activity_valid(a)}
57+
modified_paths = {e.path for _, e in modified}
58+
59+
activities = get_downstream_generating_activities(
60+
starting_activities=modified_activities,
61+
paths=paths,
62+
ignore_deleted=ignore_deleted,
63+
project_path=project_context.path,
64+
)
65+
66+
if len(activities) == 0:
67+
raise errors.NothingToExecuteError()
68+
69+
# NOTE: When updating we only want to eliminate activities that are overridden, not their parents
70+
activities = sort_activities(activities, remove_overridden_parents=False)
71+
if dry_run:
72+
return activities, modified_paths
73+
74+
graph = ExecutionGraph([a.plan_with_values for a in activities], virtual_links=True)
75+
execute_workflow_graph(dag=graph.workflow_graph, provider=provider, config=config)

renku/ui/cli/graph.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,10 @@
6161
]
6262
6363
If you want the Knowledge Graph data for the whole project, you can use
64-
``renku graph export --full``. Alternatively, you can get data for a single
65-
commit by using ``renku graph export --revision <git commit sha>`` or by
66-
specifying a range of commits like ``renku graph export --revision sha1..sha2``.
64+
``renku graph export --full`` (``--full`` is the default). Alternatively,
65+
you can get data for a single commit by using ``renku graph export
66+
--revision <git commit sha>`` or by specifying a range of commits like
67+
``renku graph export --revision sha1..sha2``.
6768
6869
``renku graph export`` currently supports various formats for export, such as
6970
``json-ld``, ``rdf``, ``nt`` (for triples) and ``dot`` (for GraphViz graphs),
@@ -111,10 +112,10 @@ def graph():
111112
@click.option(
112113
"--revision",
113114
type=str,
114-
default="HEAD",
115+
default=None,
115116
help="Limit graph to changes done in revision (or range of revisions like 'A..B').",
116117
)
117-
@click.option("-f", "--full", is_flag=True, help="Generate full graph for project. Overrides --revision.")
118+
@click.option("-f", "--full", is_flag=True, help="Generate full graph for project (default). Overrides --revision.")
118119
@click.option("--strict", is_flag=True, default=False, help="Validate triples before output.")
119120
@click.option(
120121
"--no-indent", is_flag=True, default=False, help="Format without indentation/pretty-printing (only for JSON-LD)."

renku/ui/cli/update.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -94,8 +94,8 @@
9494
:group: Running
9595
:command: $ renku update [--all] [<path>...]
9696
:description: Update outdated output files created by renku run. With
97-
<path>'s: Only recreate these files. With --all: Update
98-
all outdated output files.
97+
<path>'s: Only recreate these files. With --all (default):
98+
Update all outdated output files.
9999
:target: rp
100100
101101
Pre-update checks
@@ -159,13 +159,14 @@
159159
import click
160160
from lazy_object_proxy import Proxy
161161

162+
from renku.command.util import WARNING
162163
from renku.core import errors
163164
from renku.ui.cli.utils.callback import ClickCallback
164165
from renku.ui.cli.utils.plugins import available_workflow_providers
165166

166167

167168
@click.command()
168-
@click.option("--all", "-a", "update_all", is_flag=True, default=False, help="Update all outdated files.")
169+
@click.option("--all", "-a", "update_all", is_flag=True, default=False, help="Update all outdated files (default).")
169170
@click.option("--dry-run", "-n", is_flag=True, default=False, help="Show a preview of plans that will be executed.")
170171
@click.argument("paths", type=click.Path(exists=True, dir_okay=True), nargs=-1)
171172
@click.option(
@@ -189,6 +190,10 @@ def update(update_all, dry_run, paths, provider, config, ignore_deleted, skip_me
189190

190191
communicator = ClickCallback()
191192

193+
if not paths and not update_all and not dry_run:
194+
message = f"{WARNING}Updating all outputs could trigger expensive computations. Are you sure?"
195+
communicator.confirm(message, default=True, abort=True)
196+
192197
try:
193198
result = (
194199
update_command(skip_metadata_update=skip_metadata_update)

tests/cli/test_graph.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,14 +96,15 @@ def test_graph_export_strict_dataset(tmpdir, runner, project, subdirectory):
9696
result = runner.invoke(cli, ["dataset", "add", "--copy", "my-dataset"] + paths)
9797
assert 0 == result.exit_code, format_result_exception(result)
9898

99-
result = runner.invoke(cli, ["graph", "export", "--strict", "--format=json-ld"])
99+
result = runner.invoke(cli, ["graph", "export", "--strict", "--format=json-ld", "--revision", "HEAD"])
100100
assert 0 == result.exit_code, format_result_exception(result)
101101
assert all(p in result.output for p in test_paths), result.output
102102

103103
# check that only most recent dataset is exported
104104
assert 1 == result.output.count("http://schema.org/Dataset")
105105

106-
result = runner.invoke(cli, ["graph", "export", "--strict", "--format=json-ld", "--full"])
106+
# NOTE: Don't pass ``--full`` to check it's the default action.
107+
result = runner.invoke(cli, ["graph", "export", "--strict", "--format=json-ld"])
107108
assert 0 == result.exit_code, format_result_exception(result)
108109
assert all(p in result.output for p in test_paths), result.output
109110

tests/cli/test_update.py

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -344,9 +344,9 @@ def test_update_relative_path_for_directory_input(project, run, renku_cli, provi
344344

345345
@pytest.mark.parametrize("provider", available_workflow_providers())
346346
def test_update_no_args(runner, project, no_lfs_warning, provider):
347-
"""Test calling update with no args raises ParameterError."""
348-
source = os.path.join(project.path, "source.txt")
349-
output = os.path.join(project.path, "output.txt")
347+
"""Test calling update with no args defaults to update all."""
348+
source = project.path / "source.txt"
349+
output = project.path / "output.txt"
350350

351351
write_and_commit_file(project.repository, source, "content")
352352

@@ -355,14 +355,13 @@ def test_update_no_args(runner, project, no_lfs_warning, provider):
355355

356356
write_and_commit_file(project.repository, source, "changed content")
357357

358-
before_commit = project.repository.head.commit
358+
# NOTE: Don't pass ``--all`` to check it's the default action
359+
result = runner.invoke(cli, ["update", "-p", provider], input="y\n")
359360

360-
result = runner.invoke(cli, ["update", "-p", provider])
361-
362-
assert 2 == result.exit_code
363-
assert "Either PATHS, --all/-a, or --dry-run/-n should be specified." in result.output
361+
assert 0 == result.exit_code
362+
assert "Updating all outputs could trigger expensive computations" in result.output
364363

365-
assert before_commit == project.repository.head.commit
364+
assert "changed content" == source.read_text()
366365

367366

368367
@pytest.mark.parametrize("provider", available_workflow_providers())

0 commit comments

Comments
 (0)