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

SwissDataScienceCenter / renku-python / 7242391285

18 Dec 2023 01:23AM UTC coverage: 61.432% (-21.3%) from 82.732%
7242391285

Pull #3671

github

RenkuBot
chore: release v2.8.1
Pull Request #3671: chore: release v2.8.1

104 of 137 new or added lines in 31 files covered. (75.91%)

6464 existing lines in 180 files now uncovered.

18537 of 30175 relevant lines covered (61.43%)

1.25 hits per line

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

69.86
/renku/command/command_builder/database.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
"""Command builder for local object database."""
3✔
17

18

19
import json
3✔
20
import os
3✔
21
from typing import Optional
3✔
22

23
from packaging.version import Version
3✔
24

25
from renku.command.command_builder.command import Command, CommandResult, check_finalized
3✔
26
from renku.core import errors
3✔
27
from renku.core.interface.activity_gateway import IActivityGateway
3✔
28
from renku.core.interface.database_gateway import IDatabaseGateway
3✔
29
from renku.core.interface.dataset_gateway import IDatasetGateway
3✔
30
from renku.core.interface.plan_gateway import IPlanGateway
3✔
31
from renku.core.interface.project_gateway import IProjectGateway
3✔
32
from renku.core.interface.storage import IStorageFactory
3✔
33
from renku.domain_model.project_context import project_context
3✔
34
from renku.infrastructure.gateway.activity_gateway import ActivityGateway
3✔
35
from renku.infrastructure.gateway.database_gateway import DatabaseGateway
3✔
36
from renku.infrastructure.gateway.dataset_gateway import DatasetGateway
3✔
37
from renku.infrastructure.gateway.plan_gateway import PlanGateway
3✔
38
from renku.infrastructure.gateway.project_gateway import ProjectGateway
3✔
39
from renku.infrastructure.storage.factory import StorageFactory
3✔
40

41

42
class DatabaseCommand(Command):
3✔
43
    """Builder to get a database connection."""
44

45
    PRE_ORDER = 4
3✔
46
    POST_ORDER = 5
3✔
47

48
    def __init__(self, builder: Command, write: bool = False, path: Optional[str] = None, create: bool = False) -> None:
3✔
49
        self._builder = builder
3✔
50
        self._write = write
3✔
51
        self._path = path
3✔
52
        self._create = create
3✔
53
        self.project_found: bool = False
3✔
54

55
    def _injection_pre_hook(self, builder: Command, context: dict, *args, **kwargs) -> None:
3✔
56
        """Create a Database singleton."""
57
        from renku.version import __version__
3✔
58

59
        if not project_context.has_context():
3✔
60
            raise ValueError("Database builder needs a ProjectContext to be set.")
×
61

62
        project_context.push_path(path=self._path or project_context.path, save_changes=self._write)
3✔
63

64
        project_gateway = ProjectGateway()
3✔
65

66
        context["constructor_bindings"][IPlanGateway] = lambda: PlanGateway()
3✔
67
        context["constructor_bindings"][IActivityGateway] = lambda: ActivityGateway()
3✔
68
        context["constructor_bindings"][IDatabaseGateway] = lambda: DatabaseGateway()
3✔
69
        context["constructor_bindings"][IDatasetGateway] = lambda: DatasetGateway()
3✔
70
        context["constructor_bindings"][IProjectGateway] = lambda: project_gateway
3✔
71
        context["constructor_bindings"][IStorageFactory] = lambda: StorageFactory
3✔
72

73
        if int(os.environ.get("RENKU_SKIP_MIN_VERSION_CHECK", "0")) == 1:
3✔
74
            # NOTE: Used for unit tests
75
            return
3✔
76

UNCOV
77
        try:
×
UNCOV
78
            project = project_gateway.get_project()
×
UNCOV
79
            minimum_renku_version = Version(project.minimum_renku_version)
×
UNCOV
80
            self.project_found = True
×
81
        except (KeyError, ImportError, ValueError):
×
82
            try:
×
83
                with open(project_context.database_path / "project") as f:
×
84
                    project = json.load(f)
×
85
                    min_version = project.get("minimum_renku_version")
×
86
                    if min_version is None:
×
87
                        return
×
88
                    minimum_renku_version = Version(min_version)
×
89
            except (KeyError, OSError, json.JSONDecodeError):
×
90
                # NOTE: We don't check minimum version if there's no project metadata available
91
                return
×
92

UNCOV
93
        current_version = Version(__version__)
×
94

UNCOV
95
        if Version(current_version.base_version) < minimum_renku_version:
×
UNCOV
96
            raise errors.MinimumVersionError(current_version, minimum_renku_version)
×
97

98
    def _post_hook(self, builder: Command, context: dict, result: CommandResult, *args, **kwargs) -> None:
3✔
99
        from renku.domain_model.project import Project
3✔
100

101
        if self._write and self.project_found:
3✔
102
            # NOTE: Fetch project again in case it was updated (the current reference would be put of date)
UNCOV
103
            project_gateway = ProjectGateway()
×
UNCOV
104
            project = project_gateway.get_project()
×
105

UNCOV
106
            if Version(project.minimum_renku_version) < Version(Project.minimum_renku_version):
×
107
                # NOTE: update minimum renku version on write as migrations might happen on the fly
UNCOV
108
                project.minimum_renku_version = Project.minimum_renku_version
×
109

110
        project_context.pop_context()
3✔
111

112
    @check_finalized
3✔
113
    def build(self) -> Command:
3✔
114
        """Build the command."""
115
        self._builder.add_injection_pre_hook(self.PRE_ORDER, self._injection_pre_hook)
3✔
116
        self._builder.add_post_hook(self.POST_ORDER, self._post_hook)
3✔
117

118
        return self._builder.build()
3✔
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