devservices 1.0.13__tar.gz → 1.0.15__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {devservices-1.0.13 → devservices-1.0.15}/PKG-INFO +1 -1
- {devservices-1.0.13 → devservices-1.0.15}/README.md +1 -1
- {devservices-1.0.13 → devservices-1.0.15}/devservices/commands/update.py +1 -1
- {devservices-1.0.13 → devservices-1.0.15}/devservices/exceptions.py +9 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/main.py +15 -2
- {devservices-1.0.13 → devservices-1.0.15}/devservices/utils/dependencies.py +30 -2
- {devservices-1.0.13 → devservices-1.0.15}/devservices/utils/docker_compose.py +4 -1
- devservices-1.0.15/devservices/utils/git.py +21 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices.egg-info/PKG-INFO +1 -1
- {devservices-1.0.13 → devservices-1.0.15}/devservices.egg-info/SOURCES.txt +2 -0
- {devservices-1.0.13 → devservices-1.0.15}/pyproject.toml +1 -1
- {devservices-1.0.13 → devservices-1.0.15}/tests/utils/test_dependencies.py +42 -2
- {devservices-1.0.13 → devservices-1.0.15}/tests/utils/test_docker_compose.py +8 -2
- devservices-1.0.15/tests/utils/test_git.py +33 -0
- {devservices-1.0.13 → devservices-1.0.15}/LICENSE.md +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/__init__.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/commands/__init__.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/commands/down.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/commands/list_dependencies.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/commands/list_services.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/commands/logs.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/commands/purge.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/commands/status.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/commands/up.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/configs/service_config.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/constants.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/utils/__init__.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/utils/check_for_update.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/utils/console.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/utils/devenv.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/utils/docker.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/utils/file_lock.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/utils/install_binary.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/utils/services.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices/utils/state.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices.egg-info/dependency_links.txt +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices.egg-info/entry_points.txt +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices.egg-info/requires.txt +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/devservices.egg-info/top_level.txt +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/setup.cfg +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/testing/__init__.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/testing/utils.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/tests/__init__.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/tests/commands/test_down.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/tests/commands/test_list_dependencies.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/tests/commands/test_list_services.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/tests/commands/test_logs.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/tests/commands/test_purge.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/tests/commands/test_status.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/tests/commands/test_up.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/tests/commands/test_update.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/tests/configs/test_service_config.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/tests/conftest.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/tests/utils/test_check_for_update.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/tests/utils/test_docker.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/tests/utils/test_install_binary.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/tests/utils/test_services.py +0 -0
- {devservices-1.0.13 → devservices-1.0.15}/tests/utils/test_state.py +0 -0
|
@@ -36,7 +36,7 @@ def update_version(exec_path: str, latest_version: str) -> None:
|
|
|
36
36
|
|
|
37
37
|
def add_parser(subparsers: _SubParsersAction[ArgumentParser]) -> None:
|
|
38
38
|
parser = subparsers.add_parser(
|
|
39
|
-
"update", help="
|
|
39
|
+
"update", help="Update devservices to the latest version"
|
|
40
40
|
)
|
|
41
41
|
parser.set_defaults(func=update)
|
|
42
42
|
|
|
@@ -123,6 +123,15 @@ class DependencyNotInstalledError(DependencyError):
|
|
|
123
123
|
return f"Dependency not installed correctly: {self.repo_name} ({self.repo_link}) on {self.branch}"
|
|
124
124
|
|
|
125
125
|
|
|
126
|
+
class GitError(Exception):
|
|
127
|
+
"""Base class for git related errors."""
|
|
128
|
+
|
|
129
|
+
def __init__(self, command: str, returncode: int, stderr: str):
|
|
130
|
+
self.command = command
|
|
131
|
+
self.returncode = returncode
|
|
132
|
+
self.stderr = stderr
|
|
133
|
+
|
|
134
|
+
|
|
126
135
|
class GitConfigError(Exception):
|
|
127
136
|
"""Base class for git config related errors."""
|
|
128
137
|
|
|
@@ -5,6 +5,7 @@ import atexit
|
|
|
5
5
|
import getpass
|
|
6
6
|
import logging
|
|
7
7
|
import os
|
|
8
|
+
import platform
|
|
8
9
|
from importlib import metadata
|
|
9
10
|
|
|
10
11
|
from sentry_sdk import capture_exception
|
|
@@ -26,14 +27,18 @@ from devservices.commands import update
|
|
|
26
27
|
from devservices.constants import LOGGER_NAME
|
|
27
28
|
from devservices.exceptions import DockerComposeInstallationError
|
|
28
29
|
from devservices.exceptions import DockerDaemonNotRunningError
|
|
30
|
+
from devservices.exceptions import GitError
|
|
29
31
|
from devservices.utils.console import Console
|
|
30
32
|
from devservices.utils.docker_compose import check_docker_compose_version
|
|
33
|
+
from devservices.utils.git import get_git_version
|
|
31
34
|
|
|
32
35
|
sentry_environment = (
|
|
33
|
-
"development" if os.environ.get("IS_DEV", default=
|
|
36
|
+
"development" if os.environ.get("IS_DEV", default="0") == "1" else "production"
|
|
34
37
|
)
|
|
38
|
+
if os.environ.get("CI", default="false") == "true":
|
|
39
|
+
sentry_environment = "CI"
|
|
35
40
|
|
|
36
|
-
disable_sentry = os.environ.get("DEVSERVICES_DISABLE_SENTRY", default=
|
|
41
|
+
disable_sentry = os.environ.get("DEVSERVICES_DISABLE_SENTRY", default="0") == "1"
|
|
37
42
|
logging.basicConfig(level=logging.INFO)
|
|
38
43
|
current_version = metadata.version("devservices")
|
|
39
44
|
|
|
@@ -49,6 +54,14 @@ if not disable_sentry:
|
|
|
49
54
|
)
|
|
50
55
|
username = getpass.getuser()
|
|
51
56
|
set_user({"username": username})
|
|
57
|
+
set_tag("platform", platform.platform())
|
|
58
|
+
try:
|
|
59
|
+
git_version = get_git_version()
|
|
60
|
+
set_tag("git_version", git_version)
|
|
61
|
+
except GitError as e:
|
|
62
|
+
capture_exception(e)
|
|
63
|
+
logging.debug("Failed to get git version: %s", e)
|
|
64
|
+
set_tag("git_version", "unknown")
|
|
52
65
|
|
|
53
66
|
|
|
54
67
|
@atexit.register
|
|
@@ -272,6 +272,17 @@ def get_non_shared_remote_dependencies(
|
|
|
272
272
|
active_services = starting_services.union(started_services)
|
|
273
273
|
# We don't care about the remote dependencies of the service we are stopping
|
|
274
274
|
active_services.remove(service_to_stop.name)
|
|
275
|
+
|
|
276
|
+
active_modes: dict[str, list[str]] = dict()
|
|
277
|
+
for active_service in active_services:
|
|
278
|
+
starting_modes = state.get_active_modes_for_service(
|
|
279
|
+
active_service, StateTables.STARTING_SERVICES
|
|
280
|
+
)
|
|
281
|
+
started_modes = state.get_active_modes_for_service(
|
|
282
|
+
active_service, StateTables.STARTED_SERVICES
|
|
283
|
+
)
|
|
284
|
+
active_modes[active_service] = starting_modes or started_modes
|
|
285
|
+
|
|
275
286
|
other_running_remote_dependencies: set[InstalledRemoteDependency] = set()
|
|
276
287
|
base_running_service_names: set[str] = set()
|
|
277
288
|
for started_service_name in active_services:
|
|
@@ -279,8 +290,18 @@ def get_non_shared_remote_dependencies(
|
|
|
279
290
|
for dependency_name in service_to_stop.config.dependencies.keys():
|
|
280
291
|
if dependency_name == started_service.config.service_name:
|
|
281
292
|
base_running_service_names.add(started_service_name)
|
|
293
|
+
|
|
294
|
+
started_service_modes = active_modes[started_service_name]
|
|
295
|
+
# Only consider the dependencies of the modes that are running
|
|
296
|
+
started_service_dependencies: dict[str, Dependency] = dict()
|
|
297
|
+
for started_service_mode in started_service_modes:
|
|
298
|
+
for dependency_name in started_service.config.modes[started_service_mode]:
|
|
299
|
+
started_service_dependencies[
|
|
300
|
+
dependency_name
|
|
301
|
+
] = started_service.config.dependencies[dependency_name]
|
|
302
|
+
|
|
282
303
|
installed_remote_dependencies = get_installed_remote_dependencies(
|
|
283
|
-
list(
|
|
304
|
+
list(started_service_dependencies.values())
|
|
284
305
|
)
|
|
285
306
|
# TODO: There is an edge case here where there is a shared remote dependency with different modes
|
|
286
307
|
other_running_remote_dependencies = other_running_remote_dependencies.union(
|
|
@@ -472,7 +493,14 @@ def _update_dependency(
|
|
|
472
493
|
|
|
473
494
|
try:
|
|
474
495
|
_run_command_with_retries(
|
|
475
|
-
[
|
|
496
|
+
[
|
|
497
|
+
"git",
|
|
498
|
+
"fetch",
|
|
499
|
+
"origin",
|
|
500
|
+
dependency.branch,
|
|
501
|
+
"--filter=blob:none",
|
|
502
|
+
"--no-recurse-submodules", # Avoid fetching submodules
|
|
503
|
+
],
|
|
476
504
|
cwd=dependency_repo_dir,
|
|
477
505
|
)
|
|
478
506
|
except subprocess.CalledProcessError as e:
|
|
@@ -84,7 +84,10 @@ def install_docker_compose() -> None:
|
|
|
84
84
|
# Verify the installation
|
|
85
85
|
try:
|
|
86
86
|
version = subprocess.run(
|
|
87
|
-
["docker", "compose", "version", "--short"],
|
|
87
|
+
["docker", "compose", "version", "--short"],
|
|
88
|
+
capture_output=True,
|
|
89
|
+
check=True,
|
|
90
|
+
text=True,
|
|
88
91
|
).stdout
|
|
89
92
|
except Exception as e:
|
|
90
93
|
raise DockerComposeInstallationError(
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import subprocess
|
|
4
|
+
|
|
5
|
+
from devservices.exceptions import GitError
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def get_git_version() -> str:
|
|
9
|
+
"""Get the git version"""
|
|
10
|
+
try:
|
|
11
|
+
return subprocess.check_output(
|
|
12
|
+
["git", "version"],
|
|
13
|
+
text=True,
|
|
14
|
+
stderr=subprocess.PIPE,
|
|
15
|
+
).strip()
|
|
16
|
+
except subprocess.CalledProcessError as e:
|
|
17
|
+
raise GitError(
|
|
18
|
+
command="git --version",
|
|
19
|
+
returncode=e.returncode,
|
|
20
|
+
stderr=e.stderr,
|
|
21
|
+
) from e
|
|
@@ -30,6 +30,7 @@ devservices/utils/devenv.py
|
|
|
30
30
|
devservices/utils/docker.py
|
|
31
31
|
devservices/utils/docker_compose.py
|
|
32
32
|
devservices/utils/file_lock.py
|
|
33
|
+
devservices/utils/git.py
|
|
33
34
|
devservices/utils/install_binary.py
|
|
34
35
|
devservices/utils/services.py
|
|
35
36
|
devservices/utils/state.py
|
|
@@ -50,6 +51,7 @@ tests/utils/test_check_for_update.py
|
|
|
50
51
|
tests/utils/test_dependencies.py
|
|
51
52
|
tests/utils/test_docker.py
|
|
52
53
|
tests/utils/test_docker_compose.py
|
|
54
|
+
tests/utils/test_git.py
|
|
53
55
|
tests/utils/test_install_binary.py
|
|
54
56
|
tests/utils/test_services.py
|
|
55
57
|
tests/utils/test_state.py
|
|
@@ -681,6 +681,7 @@ def test_install_dependency_git_fetch_transient_failure(tmp_path: Path) -> None:
|
|
|
681
681
|
"origin",
|
|
682
682
|
"main",
|
|
683
683
|
"--filter=blob:none",
|
|
684
|
+
"--no-recurse-submodules",
|
|
684
685
|
],
|
|
685
686
|
cwd=str(
|
|
686
687
|
tmp_path
|
|
@@ -697,6 +698,7 @@ def test_install_dependency_git_fetch_transient_failure(tmp_path: Path) -> None:
|
|
|
697
698
|
"origin",
|
|
698
699
|
"main",
|
|
699
700
|
"--filter=blob:none",
|
|
701
|
+
"--no-recurse-submodules",
|
|
700
702
|
],
|
|
701
703
|
cwd=str(
|
|
702
704
|
tmp_path
|
|
@@ -713,6 +715,7 @@ def test_install_dependency_git_fetch_transient_failure(tmp_path: Path) -> None:
|
|
|
713
715
|
"origin",
|
|
714
716
|
"main",
|
|
715
717
|
"--filter=blob:none",
|
|
718
|
+
"--no-recurse-submodules",
|
|
716
719
|
],
|
|
717
720
|
cwd=str(
|
|
718
721
|
tmp_path
|
|
@@ -800,6 +803,7 @@ def test_install_dependency_git_fetch_failure_with_retries(tmp_path: Path) -> No
|
|
|
800
803
|
"origin",
|
|
801
804
|
"main",
|
|
802
805
|
"--filter=blob:none",
|
|
806
|
+
"--no-recurse-submodules",
|
|
803
807
|
],
|
|
804
808
|
cwd=str(
|
|
805
809
|
tmp_path
|
|
@@ -816,6 +820,7 @@ def test_install_dependency_git_fetch_failure_with_retries(tmp_path: Path) -> No
|
|
|
816
820
|
"origin",
|
|
817
821
|
"main",
|
|
818
822
|
"--filter=blob:none",
|
|
823
|
+
"--no-recurse-submodules",
|
|
819
824
|
],
|
|
820
825
|
cwd=str(
|
|
821
826
|
tmp_path
|
|
@@ -832,6 +837,7 @@ def test_install_dependency_git_fetch_failure_with_retries(tmp_path: Path) -> No
|
|
|
832
837
|
"origin",
|
|
833
838
|
"main",
|
|
834
839
|
"--filter=blob:none",
|
|
840
|
+
"--no-recurse-submodules",
|
|
835
841
|
],
|
|
836
842
|
cwd=str(
|
|
837
843
|
tmp_path
|
|
@@ -919,6 +925,7 @@ def test_install_dependency_update_git_checkout_failure(tmp_path: Path) -> None:
|
|
|
919
925
|
"origin",
|
|
920
926
|
"main",
|
|
921
927
|
"--filter=blob:none",
|
|
928
|
+
"--no-recurse-submodules",
|
|
922
929
|
],
|
|
923
930
|
cwd=str(
|
|
924
931
|
tmp_path
|
|
@@ -2157,6 +2164,8 @@ def test_get_non_shared_remote_dependencies_shared_dependencies(
|
|
|
2157
2164
|
),
|
|
2158
2165
|
)
|
|
2159
2166
|
assert len(shared_remote_dependencies) == 0
|
|
2167
|
+
mock_find_matching_service.assert_called_once_with("service-2")
|
|
2168
|
+
mock_get_installed_remote_dependencies.assert_called_once_with([])
|
|
2160
2169
|
|
|
2161
2170
|
|
|
2162
2171
|
@mock.patch(
|
|
@@ -2179,8 +2188,25 @@ def test_get_non_shared_remote_dependencies_shared_dependencies(
|
|
|
2179
2188
|
config=ServiceConfig(
|
|
2180
2189
|
version=0.1,
|
|
2181
2190
|
service_name="service-2",
|
|
2182
|
-
dependencies={
|
|
2183
|
-
|
|
2191
|
+
dependencies={
|
|
2192
|
+
"dependency-3": Dependency(
|
|
2193
|
+
description="dependency-3",
|
|
2194
|
+
remote=RemoteConfig(
|
|
2195
|
+
repo_name="dependency-3",
|
|
2196
|
+
repo_link="file://path/to/dependency-3",
|
|
2197
|
+
branch="main",
|
|
2198
|
+
),
|
|
2199
|
+
),
|
|
2200
|
+
"dependency-4": Dependency(
|
|
2201
|
+
description="dependency-4",
|
|
2202
|
+
remote=RemoteConfig(
|
|
2203
|
+
repo_name="dependency-4",
|
|
2204
|
+
repo_link="file://path/to/dependency-4",
|
|
2205
|
+
branch="main",
|
|
2206
|
+
),
|
|
2207
|
+
),
|
|
2208
|
+
},
|
|
2209
|
+
modes={"default": ["dependency-3"], "other": ["dependency-4"]},
|
|
2184
2210
|
),
|
|
2185
2211
|
),
|
|
2186
2212
|
)
|
|
@@ -2245,6 +2271,20 @@ def test_get_non_shared_remote_dependencies_complex(
|
|
|
2245
2271
|
mode="default",
|
|
2246
2272
|
)
|
|
2247
2273
|
}
|
|
2274
|
+
mock_find_matching_service.assert_called_once_with("service-2")
|
|
2275
|
+
# dependency-4 is not installed, so it should not be passed to get_installed_remote_dependencies
|
|
2276
|
+
mock_get_installed_remote_dependencies.assert_called_once_with(
|
|
2277
|
+
[
|
|
2278
|
+
Dependency(
|
|
2279
|
+
description="dependency-3",
|
|
2280
|
+
remote=RemoteConfig(
|
|
2281
|
+
repo_name="dependency-3",
|
|
2282
|
+
repo_link="file://path/to/dependency-3",
|
|
2283
|
+
branch="main",
|
|
2284
|
+
),
|
|
2285
|
+
)
|
|
2286
|
+
]
|
|
2287
|
+
)
|
|
2248
2288
|
|
|
2249
2289
|
|
|
2250
2290
|
@mock.patch("devservices.utils.dependencies.install_dependencies", return_value=[])
|
|
@@ -192,7 +192,10 @@ def test_install_docker_compose_macos_arm64(
|
|
|
192
192
|
os.path.expanduser("~/.docker/cli-plugins/docker-compose"),
|
|
193
193
|
)
|
|
194
194
|
mock_subprocess_run.assert_called_once_with(
|
|
195
|
-
["docker", "compose", "version", "--short"],
|
|
195
|
+
["docker", "compose", "version", "--short"],
|
|
196
|
+
capture_output=True,
|
|
197
|
+
check=True,
|
|
198
|
+
text=True,
|
|
196
199
|
)
|
|
197
200
|
|
|
198
201
|
|
|
@@ -231,7 +234,10 @@ def test_install_docker_compose_linux_x86(
|
|
|
231
234
|
os.path.expanduser("~/.docker/cli-plugins/docker-compose"),
|
|
232
235
|
)
|
|
233
236
|
mock_subprocess_run.assert_called_once_with(
|
|
234
|
-
["docker", "compose", "version", "--short"],
|
|
237
|
+
["docker", "compose", "version", "--short"],
|
|
238
|
+
capture_output=True,
|
|
239
|
+
check=True,
|
|
240
|
+
text=True,
|
|
235
241
|
)
|
|
236
242
|
|
|
237
243
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import subprocess
|
|
4
|
+
from unittest import mock
|
|
5
|
+
|
|
6
|
+
import pytest
|
|
7
|
+
|
|
8
|
+
from devservices.exceptions import GitError
|
|
9
|
+
from devservices.utils.git import get_git_version
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@mock.patch(
|
|
13
|
+
"devservices.utils.git.subprocess.check_output", return_value="git version 2.42.0"
|
|
14
|
+
)
|
|
15
|
+
def test_get_git_version_success(mock_get_git_version: mock.Mock) -> None:
|
|
16
|
+
assert get_git_version() == "git version 2.42.0"
|
|
17
|
+
mock_get_git_version.assert_called_once_with(
|
|
18
|
+
["git", "version"], text=True, stderr=subprocess.PIPE
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@mock.patch(
|
|
23
|
+
"devservices.utils.git.subprocess.check_output",
|
|
24
|
+
side_effect=subprocess.CalledProcessError(
|
|
25
|
+
returncode=1, cmd="git version", stderr="error"
|
|
26
|
+
),
|
|
27
|
+
)
|
|
28
|
+
def test_get_git_version_error(mock_get_git_version: mock.Mock) -> None:
|
|
29
|
+
with pytest.raises(GitError):
|
|
30
|
+
get_git_version()
|
|
31
|
+
mock_get_git_version.assert_called_once_with(
|
|
32
|
+
["git", "version"], text=True, stderr=subprocess.PIPE
|
|
33
|
+
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|