devservices 0.0.2__tar.gz → 0.0.3__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.
Files changed (34) hide show
  1. {devservices-0.0.2 → devservices-0.0.3}/PKG-INFO +1 -1
  2. devservices-0.0.3/README.md +22 -0
  3. {devservices-0.0.2 → devservices-0.0.3}/devservices/commands/logs.py +2 -2
  4. {devservices-0.0.2 → devservices-0.0.3}/devservices/commands/start.py +2 -2
  5. {devservices-0.0.2 → devservices-0.0.3}/devservices/commands/status.py +3 -3
  6. {devservices-0.0.2 → devservices-0.0.3}/devservices/commands/stop.py +2 -2
  7. {devservices-0.0.2 → devservices-0.0.3}/devservices/configs/service_config.py +10 -5
  8. {devservices-0.0.2 → devservices-0.0.3}/devservices/constants.py +1 -1
  9. {devservices-0.0.2 → devservices-0.0.3}/devservices/main.py +8 -3
  10. {devservices-0.0.2 → devservices-0.0.3}/devservices.egg-info/PKG-INFO +1 -1
  11. {devservices-0.0.2 → devservices-0.0.3}/pyproject.toml +2 -2
  12. {devservices-0.0.2 → devservices-0.0.3}/tests/commands/test_start.py +2 -2
  13. {devservices-0.0.2 → devservices-0.0.3}/tests/commands/test_stop.py +2 -2
  14. {devservices-0.0.2 → devservices-0.0.3}/tests/configs/test_service_config.py +19 -8
  15. {devservices-0.0.2 → devservices-0.0.3}/tests/testutils.py +1 -1
  16. devservices-0.0.2/README.md +0 -1
  17. {devservices-0.0.2 → devservices-0.0.3}/devservices/__init__.py +0 -0
  18. {devservices-0.0.2 → devservices-0.0.3}/devservices/commands/__init__.py +0 -0
  19. {devservices-0.0.2 → devservices-0.0.3}/devservices/commands/list_dependencies.py +0 -0
  20. {devservices-0.0.2 → devservices-0.0.3}/devservices/commands/list_services.py +0 -0
  21. {devservices-0.0.2 → devservices-0.0.3}/devservices/exceptions.py +0 -0
  22. {devservices-0.0.2 → devservices-0.0.3}/devservices/utils/__init__.py +0 -0
  23. {devservices-0.0.2 → devservices-0.0.3}/devservices/utils/console.py +0 -0
  24. {devservices-0.0.2 → devservices-0.0.3}/devservices/utils/devenv.py +0 -0
  25. {devservices-0.0.2 → devservices-0.0.3}/devservices/utils/docker_compose.py +0 -0
  26. {devservices-0.0.2 → devservices-0.0.3}/devservices/utils/services.py +0 -0
  27. {devservices-0.0.2 → devservices-0.0.3}/devservices.egg-info/SOURCES.txt +0 -0
  28. {devservices-0.0.2 → devservices-0.0.3}/devservices.egg-info/dependency_links.txt +0 -0
  29. {devservices-0.0.2 → devservices-0.0.3}/devservices.egg-info/entry_points.txt +0 -0
  30. {devservices-0.0.2 → devservices-0.0.3}/devservices.egg-info/requires.txt +0 -0
  31. {devservices-0.0.2 → devservices-0.0.3}/devservices.egg-info/top_level.txt +0 -0
  32. {devservices-0.0.2 → devservices-0.0.3}/setup.cfg +0 -0
  33. {devservices-0.0.2 → devservices-0.0.3}/tests/__init__.py +0 -0
  34. {devservices-0.0.2 → devservices-0.0.3}/tests/conftest.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: devservices
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Requires-Python: >=3.10
5
5
  Requires-Dist: pyyaml
6
6
  Requires-Dist: sentry-devenv
@@ -0,0 +1,22 @@
1
+ # devservices
2
+
3
+ A standalone cli tool used to manage dependencies for services. It simplifies the process of starting, stopping, and managing services for development purposes.
4
+
5
+ ## Overview
6
+
7
+ `devservices` reads configuration files located in the `devservices` directory of your repository. These configurations define services, their dependencies, and various modes of operation.
8
+
9
+ ## Usage
10
+
11
+ devservices provides several commands to manage your services:
12
+
13
+ ### Commands
14
+
15
+ NOTE: service-name is an optional parameter. If not provided, devservices will attempt to automatically find a devservices configuration in the current directory in order to proceed.
16
+
17
+ - `devservices start <service-name>`: Start a service and its dependencies.
18
+ - `devservices stop <service-name>`: Stop a service including its dependencies.
19
+ - `devservices status <service-name>`: Display the current status of all services, including their dependencies and ports.
20
+ - `devservices logs <service-name>`: View logs for a specific service.
21
+ - `devservices list-services`: List all available Sentry services.
22
+ - `devservices list-dependencies <service-name>`: List all dependencies for a service and whether they are enabled/disabled.
@@ -6,8 +6,8 @@ from argparse import _SubParsersAction
6
6
  from argparse import ArgumentParser
7
7
  from argparse import Namespace
8
8
 
9
+ from devservices.constants import CONFIG_FILE_NAME
9
10
  from devservices.constants import DEVSERVICES_DIR_NAME
10
- from devservices.constants import DOCKER_COMPOSE_FILE_NAME
11
11
  from devservices.exceptions import DockerComposeError
12
12
  from devservices.utils.docker_compose import run_docker_compose_command
13
13
  from devservices.utils.services import find_matching_service
@@ -37,7 +37,7 @@ def logs(args: Namespace) -> None:
37
37
  mode_to_use = "default"
38
38
  mode_dependencies = " ".join(modes[mode_to_use])
39
39
  service_config_file_path = os.path.join(
40
- service.repo_path, DEVSERVICES_DIR_NAME, DOCKER_COMPOSE_FILE_NAME
40
+ service.repo_path, DEVSERVICES_DIR_NAME, CONFIG_FILE_NAME
41
41
  )
42
42
  try:
43
43
  logs = run_docker_compose_command(
@@ -5,8 +5,8 @@ from argparse import _SubParsersAction
5
5
  from argparse import ArgumentParser
6
6
  from argparse import Namespace
7
7
 
8
+ from devservices.constants import CONFIG_FILE_NAME
8
9
  from devservices.constants import DEVSERVICES_DIR_NAME
9
- from devservices.constants import DOCKER_COMPOSE_FILE_NAME
10
10
  from devservices.exceptions import DockerComposeError
11
11
  from devservices.utils.console import Status
12
12
  from devservices.utils.docker_compose import run_docker_compose_command
@@ -34,7 +34,7 @@ def start(args: Namespace) -> None:
34
34
  mode_to_start = "default"
35
35
  mode_dependencies = " ".join(modes[mode_to_start])
36
36
  service_config_file_path = os.path.join(
37
- service.repo_path, DEVSERVICES_DIR_NAME, DOCKER_COMPOSE_FILE_NAME
37
+ service.repo_path, DEVSERVICES_DIR_NAME, CONFIG_FILE_NAME
38
38
  )
39
39
  with Status(f"Starting {service.name}", f"{service.name} started") as status:
40
40
  try:
@@ -7,8 +7,8 @@ from argparse import _SubParsersAction
7
7
  from argparse import ArgumentParser
8
8
  from argparse import Namespace
9
9
 
10
+ from devservices.constants import CONFIG_FILE_NAME
10
11
  from devservices.constants import DEVSERVICES_DIR_NAME
11
- from devservices.constants import DOCKER_COMPOSE_FILE_NAME
12
12
  from devservices.exceptions import DockerComposeError
13
13
  from devservices.utils.docker_compose import run_docker_compose_command
14
14
  from devservices.utils.services import find_matching_service
@@ -49,7 +49,7 @@ def format_status_output(status_json: str) -> str:
49
49
  output.append("Ports:")
50
50
  for port in ports:
51
51
  output.append(
52
- f" {port['PublishedPort']} -> {port['TargetPort']}/{port['Protocol']}"
52
+ f" {port['URL']}:{port['PublishedPort']} -> {port['TargetPort']}/{port['Protocol']}"
53
53
  )
54
54
  else:
55
55
  output.append("No ports exposed")
@@ -72,7 +72,7 @@ def status(args: Namespace) -> None:
72
72
  mode_to_view = "default"
73
73
  mode_dependencies = " ".join(modes[mode_to_view])
74
74
  service_config_file_path = os.path.join(
75
- service.repo_path, DEVSERVICES_DIR_NAME, DOCKER_COMPOSE_FILE_NAME
75
+ service.repo_path, DEVSERVICES_DIR_NAME, CONFIG_FILE_NAME
76
76
  )
77
77
  try:
78
78
  status_json = run_docker_compose_command(
@@ -5,8 +5,8 @@ from argparse import _SubParsersAction
5
5
  from argparse import ArgumentParser
6
6
  from argparse import Namespace
7
7
 
8
+ from devservices.constants import CONFIG_FILE_NAME
8
9
  from devservices.constants import DEVSERVICES_DIR_NAME
9
- from devservices.constants import DOCKER_COMPOSE_FILE_NAME
10
10
  from devservices.exceptions import DockerComposeError
11
11
  from devservices.utils.console import Status
12
12
  from devservices.utils.docker_compose import run_docker_compose_command
@@ -34,7 +34,7 @@ def stop(args: Namespace) -> None:
34
34
  mode_to_stop = "default"
35
35
  mode_dependencies = " ".join(modes[mode_to_stop])
36
36
  service_config_file_path = os.path.join(
37
- service.repo_path, DEVSERVICES_DIR_NAME, DOCKER_COMPOSE_FILE_NAME
37
+ service.repo_path, DEVSERVICES_DIR_NAME, CONFIG_FILE_NAME
38
38
  )
39
39
  with Status(f"Stopping {service.name}", f"{service.name} stopped") as status:
40
40
  try:
@@ -5,8 +5,8 @@ from dataclasses import dataclass
5
5
 
6
6
  import yaml
7
7
 
8
+ from devservices.constants import CONFIG_FILE_NAME
8
9
  from devservices.constants import DEVSERVICES_DIR_NAME
9
- from devservices.constants import DOCKER_COMPOSE_FILE_NAME
10
10
  from devservices.exceptions import ConfigNotFoundError
11
11
  from devservices.exceptions import ConfigParseError
12
12
  from devservices.exceptions import ConfigValidationError
@@ -14,10 +14,17 @@ from devservices.exceptions import ConfigValidationError
14
14
  VALID_VERSIONS = [0.1]
15
15
 
16
16
 
17
+ @dataclass
18
+ class RemoteConfig:
19
+ repo_name: str
20
+ branch: str
21
+ repo_link: str
22
+
23
+
17
24
  @dataclass
18
25
  class Dependency:
19
26
  description: str
20
- link: str | None = None
27
+ remote: RemoteConfig | None = None
21
28
 
22
29
 
23
30
  @dataclass
@@ -56,9 +63,7 @@ class ServiceConfig:
56
63
 
57
64
 
58
65
  def load_service_config_from_file(repo_path: str) -> ServiceConfig:
59
- config_path = os.path.join(
60
- repo_path, DEVSERVICES_DIR_NAME, DOCKER_COMPOSE_FILE_NAME
61
- )
66
+ config_path = os.path.join(repo_path, DEVSERVICES_DIR_NAME, CONFIG_FILE_NAME)
62
67
  if not os.path.exists(config_path):
63
68
  raise ConfigNotFoundError(f"Config file not found in directory: {config_path}")
64
69
  with open(config_path, "r") as stream:
@@ -1,4 +1,4 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  DEVSERVICES_DIR_NAME = "devservices"
4
- DOCKER_COMPOSE_FILE_NAME = "docker-compose.yml"
4
+ CONFIG_FILE_NAME = "config.yml"
@@ -2,6 +2,7 @@ from __future__ import annotations
2
2
 
3
3
  import argparse
4
4
  import atexit
5
+ from importlib import metadata
5
6
 
6
7
  import sentry_sdk
7
8
  from sentry_sdk.integrations.argv import ArgvIntegration
@@ -29,11 +30,15 @@ def cleanup() -> None:
29
30
 
30
31
  def main() -> None:
31
32
  parser = argparse.ArgumentParser(
32
- description="DevServices CLI tool for managing Docker Compose services."
33
+ prog="devservices",
34
+ description="CLI tool for managing service dependencies.",
35
+ usage="devservices [-h] [--version] COMMAND ...",
36
+ )
37
+ parser.add_argument(
38
+ "--version", action="version", version=metadata.version("devservices")
33
39
  )
34
- parser.add_argument("--version", action="version", version="%(prog)s 0.0.1")
35
40
 
36
- subparsers = parser.add_subparsers(dest="command", help="Available commands")
41
+ subparsers = parser.add_subparsers(dest="command", title="commands", metavar="")
37
42
 
38
43
  # Add subparsers for each command
39
44
  start.add_parser(subparsers)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: devservices
3
- Version: 0.0.2
3
+ Version: 0.0.3
4
4
  Requires-Python: >=3.10
5
5
  Requires-Dist: pyyaml
6
6
  Requires-Dist: sentry-devenv
@@ -1,10 +1,10 @@
1
1
  [build-system]
2
- requires = ["setuptools>=45", "wheel"]
2
+ requires = ["setuptools>=70", "wheel"]
3
3
  build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "devservices"
7
- version = "0.0.2"
7
+ version = "0.0.3"
8
8
  # 3.10 is just for internal pypi compat
9
9
  requires-python = ">=3.10"
10
10
  dependencies = [
@@ -9,8 +9,8 @@ from unittest import mock
9
9
  import pytest
10
10
 
11
11
  from devservices.commands.start import start
12
+ from devservices.constants import CONFIG_FILE_NAME
12
13
  from devservices.constants import DEVSERVICES_DIR_NAME
13
- from devservices.constants import DOCKER_COMPOSE_FILE_NAME
14
14
  from tests.testutils import create_config_file
15
15
 
16
16
 
@@ -44,7 +44,7 @@ def test_start_simple(mock_run: mock.Mock, tmp_path: Path) -> None:
44
44
  "docker",
45
45
  "compose",
46
46
  "-f",
47
- f"{tmp_path}/{DEVSERVICES_DIR_NAME}/{DOCKER_COMPOSE_FILE_NAME}",
47
+ f"{tmp_path}/{DEVSERVICES_DIR_NAME}/{CONFIG_FILE_NAME}",
48
48
  "up",
49
49
  "-d",
50
50
  "redis",
@@ -9,8 +9,8 @@ from unittest import mock
9
9
  import pytest
10
10
 
11
11
  from devservices.commands.stop import stop
12
+ from devservices.constants import CONFIG_FILE_NAME
12
13
  from devservices.constants import DEVSERVICES_DIR_NAME
13
- from devservices.constants import DOCKER_COMPOSE_FILE_NAME
14
14
  from tests.testutils import create_config_file
15
15
 
16
16
 
@@ -45,7 +45,7 @@ def test_stop_simple(mock_run: mock.Mock, tmp_path: Path) -> None:
45
45
  "docker",
46
46
  "compose",
47
47
  "-f",
48
- f"{tmp_path}/{DEVSERVICES_DIR_NAME}/{DOCKER_COMPOSE_FILE_NAME}",
48
+ f"{tmp_path}/{DEVSERVICES_DIR_NAME}/{CONFIG_FILE_NAME}",
49
49
  "down",
50
50
  "redis",
51
51
  "clickhouse",
@@ -25,7 +25,11 @@ from tests.testutils import create_config_file
25
25
  {
26
26
  "example-dependency-1": {
27
27
  "description": "Example dependency 1",
28
- "link": "https://example.com",
28
+ "remote": {
29
+ "repo_name": "example-dependency-1",
30
+ "branch": "main",
31
+ "repo_link": "https://example.com",
32
+ },
29
33
  },
30
34
  "example-dependency-2": {
31
35
  "description": "Example dependency 2",
@@ -38,7 +42,11 @@ from tests.testutils import create_config_file
38
42
  {
39
43
  "example-dependency-1": {
40
44
  "description": "Example dependency 1",
41
- "link": "https://example.com",
45
+ "remote": {
46
+ "repo_name": "example-dependency-1",
47
+ "branch": "main",
48
+ "repo_link": "https://example.com",
49
+ },
42
50
  },
43
51
  "example-dependency-2": {
44
52
  "description": "Example dependency 2",
@@ -69,7 +77,10 @@ def test_load_service_config_from_file(
69
77
  "version": 0.1,
70
78
  "service_name": service_name,
71
79
  "dependencies": {
72
- key: {"description": value["description"], "link": value.get("link")}
80
+ key: {
81
+ "description": value["description"],
82
+ "remote": value.get("remote"),
83
+ }
73
84
  for key, value in dependencies.items()
74
85
  },
75
86
  "modes": modes,
@@ -100,7 +111,7 @@ def test_load_service_config_from_file_missing_config(tmp_path: Path) -> None:
100
111
  load_service_config_from_file(str(tmp_path))
101
112
  assert (
102
113
  str(e.value)
103
- == f"Config file not found in directory: {tmp_path / 'devservices' / 'docker-compose.yml'}"
114
+ == f"Config file not found in directory: {tmp_path / 'devservices' / 'config.yml'}"
104
115
  )
105
116
 
106
117
 
@@ -287,7 +298,7 @@ def test_load_service_config_from_file_invalid_yaml(tmp_path: Path) -> None:
287
298
  default: ["example-dependency"]"""
288
299
  devservices_dir = Path(tmp_path, "devservices")
289
300
  devservices_dir.mkdir(parents=True, exist_ok=True)
290
- tmp_file = Path(devservices_dir, "docker-compose.yml")
301
+ tmp_file = Path(devservices_dir, "config.yml")
291
302
  with tmp_file.open("w") as f:
292
303
  f.write(config)
293
304
 
@@ -295,7 +306,7 @@ def test_load_service_config_from_file_invalid_yaml(tmp_path: Path) -> None:
295
306
  load_service_config_from_file(str(tmp_path))
296
307
  assert (
297
308
  str(e.value)
298
- == f"Error parsing config file: mapping values are not allowed here\n in \"{tmp_path / 'devservices' / 'docker-compose.yml'}\", line 2, column 12"
309
+ == f"Error parsing config file: mapping values are not allowed here\n in \"{tmp_path / 'devservices' / 'config.yml'}\", line 2, column 12"
299
310
  )
300
311
 
301
312
 
@@ -311,7 +322,7 @@ def test_load_service_config_from_file_invalid_yaml_tag(tmp_path: Path) -> None:
311
322
  default: ["example-dependency"]"""
312
323
  devservices_dir = Path(tmp_path, "devservices")
313
324
  devservices_dir.mkdir(parents=True, exist_ok=True)
314
- tmp_file = Path(devservices_dir, "docker-compose.yml")
325
+ tmp_file = Path(devservices_dir, "config.yml")
315
326
  with tmp_file.open("w") as f:
316
327
  f.write(config)
317
328
 
@@ -319,5 +330,5 @@ def test_load_service_config_from_file_invalid_yaml_tag(tmp_path: Path) -> None:
319
330
  load_service_config_from_file(str(tmp_path))
320
331
  assert (
321
332
  str(e.value)
322
- == f"Error parsing config file: could not determine a constructor for the tag 'tag:yaml.org,2002:invalid_tag'\n in \"{tmp_path / 'devservices' / 'docker-compose.yml'}\", line 7, column 19"
333
+ == f"Error parsing config file: could not determine a constructor for the tag 'tag:yaml.org,2002:invalid_tag'\n in \"{tmp_path / 'devservices' / 'config.yml'}\", line 7, column 19"
323
334
  )
@@ -10,6 +10,6 @@ def create_config_file(
10
10
  ) -> None:
11
11
  devservices_dir = Path(tmp_path, "devservices")
12
12
  devservices_dir.mkdir(parents=True, exist_ok=True)
13
- tmp_file = Path(devservices_dir, "docker-compose.yml")
13
+ tmp_file = Path(devservices_dir, "config.yml")
14
14
  with tmp_file.open("w") as f:
15
15
  yaml.dump(config, f, sort_keys=False, default_flow_style=False)
@@ -1 +0,0 @@
1
- # devservices
File without changes