stoobly-agent 1.10.1__py3-none-any.whl → 1.10.2__py3-none-any.whl

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 (155) hide show
  1. stoobly_agent/__init__.py +1 -1
  2. stoobly_agent/__main__.py +10 -0
  3. stoobly_agent/app/cli/ca_cert_cli.py +9 -5
  4. stoobly_agent/app/cli/helpers/replay_facade.py +2 -2
  5. stoobly_agent/app/cli/intercept_cli.py +5 -5
  6. stoobly_agent/app/cli/request_cli.py +2 -2
  7. stoobly_agent/app/cli/scaffold/app.py +14 -5
  8. stoobly_agent/app/cli/scaffold/app_command.py +0 -4
  9. stoobly_agent/app/cli/scaffold/app_config.py +49 -2
  10. stoobly_agent/app/cli/scaffold/app_create_command.py +145 -76
  11. stoobly_agent/app/cli/scaffold/constants.py +8 -1
  12. stoobly_agent/app/cli/scaffold/docker/constants.py +3 -1
  13. stoobly_agent/app/cli/scaffold/docker/service/build_decorator.py +2 -2
  14. stoobly_agent/app/cli/scaffold/docker/service/builder.py +15 -49
  15. stoobly_agent/app/cli/scaffold/docker/service/configure_gateway.py +3 -0
  16. stoobly_agent/app/cli/scaffold/docker/template_files.py +112 -0
  17. stoobly_agent/app/cli/scaffold/docker/workflow/build_decorator.py +1 -1
  18. stoobly_agent/app/cli/scaffold/docker/workflow/builder.py +31 -39
  19. stoobly_agent/app/cli/scaffold/docker/workflow/command_decorator.py +1 -1
  20. stoobly_agent/app/cli/scaffold/docker/workflow/detached_decorator.py +1 -1
  21. stoobly_agent/app/cli/scaffold/docker/workflow/dns_decorator.py +2 -3
  22. stoobly_agent/app/cli/scaffold/docker/workflow/local_decorator.py +1 -1
  23. stoobly_agent/app/cli/scaffold/docker/workflow/mock_decorator.py +1 -1
  24. stoobly_agent/app/cli/scaffold/docker/workflow/reverse_proxy_decorator.py +1 -1
  25. stoobly_agent/app/cli/scaffold/docker/workflow/run_command.py +423 -0
  26. stoobly_agent/app/cli/scaffold/local/__init__.py +0 -0
  27. stoobly_agent/app/cli/scaffold/local/service/__init__.py +0 -0
  28. stoobly_agent/app/cli/scaffold/local/service/builder.py +72 -0
  29. stoobly_agent/app/cli/scaffold/local/workflow/__init__.py +0 -0
  30. stoobly_agent/app/cli/scaffold/local/workflow/builder.py +35 -0
  31. stoobly_agent/app/cli/scaffold/local/workflow/run_command.py +339 -0
  32. stoobly_agent/app/cli/scaffold/service_command.py +9 -1
  33. stoobly_agent/app/cli/scaffold/service_config.py +8 -0
  34. stoobly_agent/app/cli/scaffold/service_create_command.py +18 -6
  35. stoobly_agent/app/cli/scaffold/service_docker_compose.py +1 -1
  36. stoobly_agent/app/cli/scaffold/templates/app/.Makefile +2 -2
  37. stoobly_agent/app/cli/scaffold/templates/app/build/.docker-compose.base.yml +2 -2
  38. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/.docker-compose.base.yml +2 -2
  39. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/mock/run +3 -0
  40. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/record/run +3 -0
  41. stoobly_agent/app/cli/scaffold/templates/app/entrypoint/test/run +3 -0
  42. stoobly_agent/app/cli/scaffold/templates/build/services/build/mock/.configure +5 -1
  43. stoobly_agent/app/cli/scaffold/templates/build/services/build/mock/.init +5 -1
  44. stoobly_agent/app/cli/scaffold/templates/build/services/build/mock/.run +14 -0
  45. stoobly_agent/app/cli/scaffold/templates/build/services/build/record/.configure +5 -1
  46. stoobly_agent/app/cli/scaffold/templates/build/services/build/record/.init +5 -1
  47. stoobly_agent/app/cli/scaffold/templates/build/services/build/record/.run +14 -0
  48. stoobly_agent/app/cli/scaffold/templates/build/services/build/test/.configure +5 -1
  49. stoobly_agent/app/cli/scaffold/templates/build/services/build/test/.init +5 -1
  50. stoobly_agent/app/cli/scaffold/templates/build/services/build/test/.run +14 -0
  51. stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/mock/.configure +5 -1
  52. stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/mock/.init +5 -1
  53. stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/mock/.run +19 -0
  54. stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/record/.configure +5 -1
  55. stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/record/.init +5 -1
  56. stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/record/.run +19 -0
  57. stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/test/.configure +5 -1
  58. stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/test/.init +5 -1
  59. stoobly_agent/app/cli/scaffold/templates/build/services/entrypoint/test/.run +19 -0
  60. stoobly_agent/app/cli/scaffold/templates/build/workflows/exec/scaffold/.up +0 -1
  61. stoobly_agent/app/cli/scaffold/templates/build/workflows/mock/.configure +5 -1
  62. stoobly_agent/app/cli/scaffold/templates/build/workflows/mock/.init +5 -1
  63. stoobly_agent/app/cli/scaffold/templates/build/workflows/mock/.run +14 -0
  64. stoobly_agent/app/cli/scaffold/templates/build/workflows/record/.configure +5 -1
  65. stoobly_agent/app/cli/scaffold/templates/build/workflows/record/.init +5 -1
  66. stoobly_agent/app/cli/scaffold/templates/build/workflows/record/.run +14 -0
  67. stoobly_agent/app/cli/scaffold/templates/build/workflows/test/.configure +5 -1
  68. stoobly_agent/app/cli/scaffold/templates/build/workflows/test/.init +5 -1
  69. stoobly_agent/app/cli/scaffold/templates/build/workflows/test/.run +14 -0
  70. stoobly_agent/app/cli/scaffold/templates/constants.py +35 -19
  71. stoobly_agent/app/cli/scaffold/templates/factory.py +34 -18
  72. stoobly_agent/app/cli/scaffold/templates/plugins/cypress/test/.run +21 -0
  73. stoobly_agent/app/cli/scaffold/templates/plugins/playwright/test/.run +21 -0
  74. stoobly_agent/app/cli/scaffold/templates/workflow/mock/run +3 -0
  75. stoobly_agent/app/cli/scaffold/templates/workflow/record/run +3 -0
  76. stoobly_agent/app/cli/scaffold/templates/workflow/test/run +3 -0
  77. stoobly_agent/app/cli/scaffold/workflow_command.py +18 -4
  78. stoobly_agent/app/cli/scaffold/workflow_copy_command.py +5 -4
  79. stoobly_agent/app/cli/scaffold/workflow_create_command.py +31 -29
  80. stoobly_agent/app/cli/scaffold/workflow_run_command.py +18 -151
  81. stoobly_agent/app/cli/scaffold_cli.py +115 -161
  82. stoobly_agent/app/cli/scenario_cli.py +2 -2
  83. stoobly_agent/app/cli/types/test.py +2 -2
  84. stoobly_agent/app/cli/types/workflow_run_command.py +52 -3
  85. stoobly_agent/app/proxy/handle_mock_service.py +1 -1
  86. stoobly_agent/app/proxy/intercept_settings.py +5 -25
  87. stoobly_agent/app/proxy/mock/eval_fixtures_service.py +177 -27
  88. stoobly_agent/app/proxy/mock/types/__init__.py +22 -1
  89. stoobly_agent/app/proxy/replay/body_parser_service.py +8 -5
  90. stoobly_agent/app/proxy/replay/multipart.py +15 -13
  91. stoobly_agent/app/proxy/replay/replay_request_service.py +2 -2
  92. stoobly_agent/app/proxy/run.py +3 -0
  93. stoobly_agent/app/proxy/test/context.py +0 -4
  94. stoobly_agent/app/proxy/test/context_abc.py +0 -5
  95. stoobly_agent/cli.py +61 -16
  96. stoobly_agent/config/data_dir.py +0 -8
  97. stoobly_agent/public/12-es2015.618ecfd5f735b801b50f.js +1 -0
  98. stoobly_agent/public/12-es5.618ecfd5f735b801b50f.js +1 -0
  99. stoobly_agent/public/index.html +1 -1
  100. stoobly_agent/public/runtime-es2015.77bcd31efed9e5d5d431.js +1 -0
  101. stoobly_agent/public/runtime-es5.77bcd31efed9e5d5d431.js +1 -0
  102. stoobly_agent/test/app/cli/intercept/intercept_configure_test.py +17 -6
  103. stoobly_agent/test/app/cli/scaffold/docker/cli_invoker.py +177 -0
  104. stoobly_agent/test/app/cli/scaffold/{cli_test.py → docker/cli_test.py} +1 -8
  105. stoobly_agent/test/app/cli/scaffold/{e2e_test.py → docker/e2e_test.py} +31 -16
  106. stoobly_agent/test/app/cli/scaffold/local/__init__.py +0 -0
  107. stoobly_agent/test/app/cli/scaffold/{cli_invoker.py → local/cli_invoker.py} +38 -32
  108. stoobly_agent/test/app/cli/scaffold/local/e2e_test.py +342 -0
  109. stoobly_agent/test/app/models/schemas/.stoobly/db/VERSION +1 -1
  110. stoobly_agent/test/app/proxy/mock/eval_fixtures_service_test.py +903 -2
  111. stoobly_agent/test/app/proxy/replay/body_parser_service_test.py +95 -3
  112. stoobly_agent/test/config/data_dir_test.py +2 -7
  113. stoobly_agent/test/test_helper.py +16 -5
  114. {stoobly_agent-1.10.1.dist-info → stoobly_agent-1.10.2.dist-info}/METADATA +4 -2
  115. {stoobly_agent-1.10.1.dist-info → stoobly_agent-1.10.2.dist-info}/RECORD +150 -122
  116. {stoobly_agent-1.10.1.dist-info → stoobly_agent-1.10.2.dist-info}/WHEEL +1 -1
  117. stoobly_agent/app/cli/helpers/shell.py +0 -26
  118. stoobly_agent/public/12-es2015.be58ed0ef449008b932e.js +0 -1
  119. stoobly_agent/public/12-es5.be58ed0ef449008b932e.js +0 -1
  120. stoobly_agent/public/runtime-es2015.f8c814b38b27708e91c1.js +0 -1
  121. stoobly_agent/public/runtime-es5.f8c814b38b27708e91c1.js +0 -1
  122. /stoobly_agent/app/cli/scaffold/templates/app/build/mock/{.docker-compose.mock.yml → .docker-compose.yml} +0 -0
  123. /stoobly_agent/app/cli/scaffold/templates/app/build/mock/{bin/configure → configure} +0 -0
  124. /stoobly_agent/app/cli/scaffold/templates/app/build/mock/{bin/init → init} +0 -0
  125. /stoobly_agent/app/cli/scaffold/templates/app/build/record/{.docker-compose.record.yml → .docker-compose.yml} +0 -0
  126. /stoobly_agent/app/cli/scaffold/templates/app/build/record/{bin/configure → configure} +0 -0
  127. /stoobly_agent/app/cli/scaffold/templates/app/build/record/{bin/init → init} +0 -0
  128. /stoobly_agent/app/cli/scaffold/templates/app/build/test/{.docker-compose.test.yml → .docker-compose.yml} +0 -0
  129. /stoobly_agent/app/cli/scaffold/templates/app/build/test/{bin/configure → configure} +0 -0
  130. /stoobly_agent/app/cli/scaffold/templates/app/build/test/{bin/init → init} +0 -0
  131. /stoobly_agent/app/cli/scaffold/templates/app/entrypoint/mock/{.docker-compose.mock.yml → .docker-compose.yml} +0 -0
  132. /stoobly_agent/app/cli/scaffold/templates/app/entrypoint/mock/{bin/configure → configure} +0 -0
  133. /stoobly_agent/app/cli/scaffold/templates/app/entrypoint/mock/{bin/init → init} +0 -0
  134. /stoobly_agent/app/cli/scaffold/templates/app/entrypoint/record/{.docker-compose.record.yml → .docker-compose.yml} +0 -0
  135. /stoobly_agent/app/cli/scaffold/templates/app/entrypoint/record/{bin/configure → configure} +0 -0
  136. /stoobly_agent/app/cli/scaffold/templates/app/entrypoint/record/{bin/init → init} +0 -0
  137. /stoobly_agent/app/cli/scaffold/templates/app/entrypoint/test/{.docker-compose.test.yml → .docker-compose.yml} +0 -0
  138. /stoobly_agent/app/cli/scaffold/templates/app/entrypoint/test/{bin/configure → configure} +0 -0
  139. /stoobly_agent/app/cli/scaffold/templates/app/entrypoint/test/{bin/init → init} +0 -0
  140. /stoobly_agent/app/cli/scaffold/templates/app/gateway/mock/{.docker-compose.mock.yml → .docker-compose.yml} +0 -0
  141. /stoobly_agent/app/cli/scaffold/templates/app/gateway/record/{.docker-compose.record.yml → .docker-compose.yml} +0 -0
  142. /stoobly_agent/app/cli/scaffold/templates/app/gateway/test/{.docker-compose.test.yml → .docker-compose.yml} +0 -0
  143. /stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/exec/{.docker-compose.exec.yml → .docker-compose.yml} +0 -0
  144. /stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/mock/{.docker-compose.mock.yml → .docker-compose.yml} +0 -0
  145. /stoobly_agent/app/cli/scaffold/templates/app/stoobly-ui/record/{.docker-compose.record.yml → .docker-compose.yml} +0 -0
  146. /stoobly_agent/app/cli/scaffold/templates/plugins/cypress/test/{.docker-compose.test.yml → .docker-compose.yml} +0 -0
  147. /stoobly_agent/app/cli/scaffold/templates/plugins/playwright/test/{.docker-compose.test.yml → .docker-compose.yml} +0 -0
  148. /stoobly_agent/app/cli/scaffold/templates/workflow/mock/{bin/configure → configure} +0 -0
  149. /stoobly_agent/app/cli/scaffold/templates/workflow/mock/{bin/init → init} +0 -0
  150. /stoobly_agent/app/cli/scaffold/templates/workflow/record/{bin/configure → configure} +0 -0
  151. /stoobly_agent/app/cli/scaffold/templates/workflow/record/{bin/init → init} +0 -0
  152. /stoobly_agent/app/cli/scaffold/templates/workflow/test/{bin/configure → configure} +0 -0
  153. /stoobly_agent/app/cli/scaffold/templates/workflow/test/{bin/init → init} +0 -0
  154. {stoobly_agent-1.10.1.dist-info → stoobly_agent-1.10.2.dist-info}/entry_points.txt +0 -0
  155. {stoobly_agent-1.10.1.dist-info → stoobly_agent-1.10.2.dist-info/licenses}/LICENSE +0 -0
@@ -14,41 +14,33 @@ from ...constants import (
14
14
  SERVICE_PORT, SERVICE_PORT_ENV,
15
15
  SERVICE_SCHEME, SERVICE_SCHEME_ENV,
16
16
  SERVICE_UPSTREAM_HOSTNAME, SERVICE_UPSTREAM_HOSTNAME_ENV, SERVICE_UPSTREAM_PORT, SERVICE_UPSTREAM_PORT_ENV, SERVICE_UPSTREAM_SCHEME, SERVICE_UPSTREAM_SCHEME_ENV,
17
- STOOBLY_HOME_DIR, STOOBLY_HOME_DIR,
17
+ STOOBLY_HOME_DIR,
18
18
  WORKFLOW_NAME, WORKFLOW_NAME_ENV, WORKFLOW_SCRIPTS, WORKFLOW_TEMPLATE
19
19
  )
20
20
  from ...service_config import ServiceConfig
21
+ from ...local.service.builder import ServiceBuilder
21
22
  from ..app_builder import AppBuilder
22
23
  from ..builder import Builder
23
24
  from ..constants import DOCKER_COMPOSE_BASE
24
25
 
25
- class ServiceBuilder(Builder):
26
+ class DockerServiceBuilder(ServiceBuilder, Builder):
26
27
 
27
28
  def __init__(self, config: ServiceConfig, app_builder: AppBuilder = None):
28
29
  service_path = config.dir
29
- super().__init__(service_path, DOCKER_COMPOSE_BASE)
30
+
31
+ # Initialize both parent classes
32
+ ServiceBuilder.__init__(self, config)
33
+ Builder.__init__(self, service_path, DOCKER_COMPOSE_BASE)
30
34
 
31
35
  if not app_builder:
32
- app_dir = os.path.dirname(service_path)
33
- app_builder = AppBuilder(AppConfig(app_dir))
36
+ app_config = AppConfig(config.app_config_dir_path)
37
+ app_builder = AppBuilder(app_config)
34
38
  self.app_builder = app_builder
35
39
 
36
- self.__config = config
37
- self.__upstream_port = None
38
- self.__env = [SERVICE_NAME_ENV, WORKFLOW_NAME_ENV]
39
- self.__service_name = os.path.basename(service_path)
40
- self.__working_dir = os.path.join(
41
- STOOBLY_HOME_DIR, DATA_DIR_NAME, SERVICES_NAMESPACE, SERVICE_NAME, WORKFLOW_NAME
42
- )
43
-
44
40
  @property
45
41
  def app_base(self):
46
42
  return f"{self.service_name}.app_base"
47
43
 
48
- @property
49
- def config(self):
50
- return self.__config
51
-
52
44
  @property
53
45
  def configure_base(self):
54
46
  return f"{self.service_name}.configure_base"
@@ -57,10 +49,6 @@ class ServiceBuilder(Builder):
57
49
  def configure_base_service(self):
58
50
  return self.services.get(self.configure_base)
59
51
 
60
- @property
61
- def upstream_port(self) -> int:
62
- return self.__upstream_port
63
-
64
52
  @property
65
53
  def extends_service(self):
66
54
  if self.config.detached:
@@ -84,10 +72,6 @@ class ServiceBuilder(Builder):
84
72
  def proxy_base_service(self):
85
73
  return self.services.get(self.proxy_base)
86
74
 
87
- @property
88
- def service_name(self):
89
- return self.__service_name
90
-
91
75
  def build_extends_init_base(self, source_dir: str):
92
76
  return self.build_extends(self.init_base, source_dir)
93
77
 
@@ -128,7 +112,7 @@ class ServiceBuilder(Builder):
128
112
  'service': self.extends_service
129
113
  },
130
114
  'labels': labels,
131
- 'working_dir': self.__working_dir,
115
+ 'working_dir': self.working_dir,
132
116
  }
133
117
 
134
118
  if len(volumes):
@@ -147,14 +131,14 @@ class ServiceBuilder(Builder):
147
131
  self.__with_detached_volumes(volumes)
148
132
 
149
133
  self.with_service(self.init_base, {
150
- 'command': [f"{WORKFLOW_SCRIPTS}/{WORKFLOW_TEMPLATE}/.init", 'bin/init'],
134
+ 'command': [f"{WORKFLOW_SCRIPTS}/{WORKFLOW_TEMPLATE}/.init", 'init'],
151
135
  'environment': environment,
152
136
  'extends': {
153
137
  'file': os.path.relpath(self.app_builder.compose_file_path, self.dir_path),
154
138
  'service': self.extends_service
155
139
  },
156
140
  'volumes': volumes,
157
- 'working_dir': self.__working_dir,
141
+ 'working_dir': self.working_dir,
158
142
  })
159
143
 
160
144
  def build_configure_base(self):
@@ -168,13 +152,13 @@ class ServiceBuilder(Builder):
168
152
  self.__with_detached_volumes(volumes)
169
153
 
170
154
  base = {
171
- 'command': [f"{WORKFLOW_SCRIPTS}/{WORKFLOW_TEMPLATE}/.configure", 'bin/configure'],
155
+ 'command': [f"{WORKFLOW_SCRIPTS}/{WORKFLOW_TEMPLATE}/.configure", 'configure'],
172
156
  'environment': environment,
173
157
  'extends': {
174
158
  'file': os.path.relpath(self.app_builder.compose_file_path, self.dir_path),
175
159
  'service': self.extends_service
176
160
  },
177
- 'working_dir': self.__working_dir,
161
+ 'working_dir': self.working_dir,
178
162
  }
179
163
 
180
164
  if len(volumes):
@@ -182,24 +166,6 @@ class ServiceBuilder(Builder):
182
166
 
183
167
  self.with_service(self.configure_base, base)
184
168
 
185
- def env_dict(self):
186
- env = {}
187
- for e in self.__env:
188
- env[e] = '${' + e + '}'
189
- return env
190
-
191
- def with_upstream_port(self, v: int):
192
- if not isinstance(v, int):
193
- return self
194
- self.__upstream_port = v
195
- return self
196
-
197
- def with_env(self, v: List[str]):
198
- if not isinstance(v, list):
199
- return self
200
- self.__env += v
201
- return self
202
-
203
169
  def write(self):
204
170
  self.build_init_base()
205
171
  self.build_configure_base()
@@ -214,7 +180,7 @@ class ServiceBuilder(Builder):
214
180
  if self.networks:
215
181
  compose['networks'] = self.networks
216
182
 
217
- super().write(compose)
183
+ Builder.write(self, compose)
218
184
 
219
185
  def __with_detached_volumes(self, volumes: list):
220
186
  # Mount named volume
@@ -21,6 +21,9 @@ def configure_gateway(workflow_namespace: WorkflowNamespace, service_paths: List
21
21
  docker_compose_src_path = os.path.join(gateway_service_path, DOCKER_COMPOSE_BASE_TEMPLATE)
22
22
  docker_compose_dest_path = os.path.join(gateway_service_path, DOCKER_COMPOSE_BASE)
23
23
 
24
+ if not os.path.exists(docker_compose_src_path):
25
+ return
26
+
24
27
  compose = {}
25
28
  with open(docker_compose_src_path, 'r') as fp:
26
29
  compose = yaml.safe_load(fp)
@@ -0,0 +1,112 @@
1
+ import os
2
+ import shutil
3
+ import yaml
4
+
5
+ from mergedeep import merge
6
+
7
+ from ..constants import PLUGINS_FOLDER, WORKFLOW_TEST_TYPE
8
+ from ..templates.constants import CORE_ENTRYPOINT_SERVICE_NAME
9
+ from .constants import (
10
+ DOCKER_COMPOSE_BASE_TEMPLATE,
11
+ DOCKER_COMPOSE_CUSTOM,
12
+ DOCKER_COMPOSE_WORKFLOW,
13
+ DOCKER_MAKEFILE,
14
+ DOCKER_MAKEFILE_DOT,
15
+ DOCKERFILE_CONTEXT,
16
+ DOCKER_COMPOSE_BASE,
17
+ DOCKER_COMPOSE_NETWORKS,
18
+ PLUGIN_CONTAINER_SERVICE_TEMPLATE,
19
+ PLUGIN_DOCKER_ENTRYPOINT,
20
+ PLUGIN_DOCKERFILE_TEMPLATE,
21
+ )
22
+
23
+ DOCKER_APP_TEMPLATE_FILES = [
24
+ DOCKER_MAKEFILE,
25
+ DOCKER_MAKEFILE_DOT,
26
+ DOCKERFILE_CONTEXT,
27
+ DOCKER_COMPOSE_BASE,
28
+ DOCKER_COMPOSE_NETWORKS,
29
+ ]
30
+
31
+ def __merge_compose_plugin(dest_path: str, template_path: str, plugin: str):
32
+ if not os.path.exists(dest_path):
33
+ open(dest_path, 'a').close()
34
+
35
+ def load_yaml(path):
36
+ with open(path, 'r') as f:
37
+ return yaml.safe_load(f) or {}
38
+
39
+ data1 = load_yaml(dest_path)
40
+ data2 = load_yaml(template_path)
41
+
42
+ services = data1.get('services') or {}
43
+ if services.get(PLUGIN_CONTAINER_SERVICE_TEMPLATE.format(plugin=plugin, service=CORE_ENTRYPOINT_SERVICE_NAME)):
44
+ return
45
+
46
+ with open(dest_path, 'w') as out:
47
+ merged = merge(data1, data2)
48
+ yaml.dump(merged, out, default_flow_style=False)
49
+
50
+ def remove_app_docker_files(dest_path: str):
51
+ for file_name in DOCKER_APP_TEMPLATE_FILES:
52
+ file_path = os.path.join(dest_path, file_name)
53
+ if os.path.exists(file_path):
54
+ os.remove(file_path)
55
+
56
+ def remove_service_docker_files(service_path: str):
57
+ compose_files = [DOCKER_COMPOSE_BASE, DOCKER_COMPOSE_CUSTOM, DOCKER_COMPOSE_BASE_TEMPLATE]
58
+
59
+ # For each file in dest_path recursively, check whether it is DOCKER_COMPOSE_BASE or DOCKER_COMPOSE_BASE_TEMPLATE, if so remove it
60
+ for root, _, files in os.walk(service_path):
61
+ for file in files:
62
+ if file in compose_files or file == DOCKER_COMPOSE_WORKFLOW:
63
+ os.remove(os.path.join(root, file))
64
+
65
+ def plugin_docker_cypress(templates_root_dir: str, plugin: str, dest: str):
66
+ dockerfile_name = PLUGIN_DOCKERFILE_TEMPLATE.format(plugin=plugin)
67
+ dockerfile_dest_path = os.path.join(dest, CORE_ENTRYPOINT_SERVICE_NAME, WORKFLOW_TEST_TYPE, dockerfile_name)
68
+
69
+ # Copy Dockerfile to workflow
70
+ dockerfile_src_path = os.path.join(templates_root_dir, PLUGINS_FOLDER, plugin, WORKFLOW_TEST_TYPE, dockerfile_name)
71
+ shutil.copyfile(dockerfile_src_path, dockerfile_dest_path)
72
+
73
+ # Merge template into dest compose yml
74
+ compose_dest_path = os.path.join(
75
+ dest, CORE_ENTRYPOINT_SERVICE_NAME, WORKFLOW_TEST_TYPE, DOCKER_COMPOSE_WORKFLOW
76
+ )
77
+ template_path = os.path.join(
78
+ templates_root_dir, PLUGINS_FOLDER, plugin, WORKFLOW_TEST_TYPE, DOCKER_COMPOSE_WORKFLOW
79
+ )
80
+ __merge_compose_plugin(compose_dest_path, template_path, plugin)
81
+
82
+ def plugin_docker_playwright(templates_root_dir: str, plugin: str, dest: str):
83
+ dockerfile_name = PLUGIN_DOCKERFILE_TEMPLATE.format(plugin=plugin)
84
+ dockerfile_src_path = os.path.join(templates_root_dir, PLUGINS_FOLDER, plugin, WORKFLOW_TEST_TYPE, dockerfile_name)
85
+ dockerfile_dest_path = os.path.join(dest, CORE_ENTRYPOINT_SERVICE_NAME, WORKFLOW_TEST_TYPE, dockerfile_name)
86
+ shutil.copyfile(dockerfile_src_path, dockerfile_dest_path)
87
+
88
+ entrypoint_src_path = os.path.join(templates_root_dir, PLUGINS_FOLDER, plugin, WORKFLOW_TEST_TYPE, PLUGIN_DOCKER_ENTRYPOINT)
89
+ entrypoint_dest_path = os.path.join(dest, CORE_ENTRYPOINT_SERVICE_NAME, WORKFLOW_TEST_TYPE, PLUGIN_DOCKER_ENTRYPOINT)
90
+ shutil.copyfile(entrypoint_src_path, entrypoint_dest_path)
91
+
92
+ # Merge template into dest compose yml
93
+ compose_dest_path = os.path.join(
94
+ dest, CORE_ENTRYPOINT_SERVICE_NAME, WORKFLOW_TEST_TYPE, DOCKER_COMPOSE_WORKFLOW
95
+ )
96
+ template_path = os.path.join(
97
+ templates_root_dir, PLUGINS_FOLDER, plugin, WORKFLOW_TEST_TYPE, DOCKER_COMPOSE_WORKFLOW
98
+ )
99
+ __merge_compose_plugin(compose_dest_path, template_path, plugin)
100
+
101
+ def plugin_local_cypress(templates_root_dir: str, plugin: str, dest: str):
102
+ # Copy run script
103
+ run_script_src_path = os.path.join(templates_root_dir, PLUGINS_FOLDER, plugin, WORKFLOW_TEST_TYPE, '.run')
104
+ run_script_dest_path = os.path.join(dest, CORE_ENTRYPOINT_SERVICE_NAME, WORKFLOW_TEST_TYPE, '.run')
105
+ # Use shutil.copy instead of shutil.copyfile to preserve permissions
106
+ shutil.copy(run_script_src_path, run_script_dest_path)
107
+
108
+ def plugin_local_playwright(templates_root_dir: str, plugin: str, dest: str):
109
+ # Copy run script
110
+ run_script_src_path = os.path.join(templates_root_dir, PLUGINS_FOLDER, plugin, WORKFLOW_TEST_TYPE, '.run')
111
+ run_script_dest_path = os.path.join(dest, CORE_ENTRYPOINT_SERVICE_NAME, WORKFLOW_TEST_TYPE, '.run')
112
+ shutil.copy(run_script_src_path, run_script_dest_path)
@@ -1,6 +1,6 @@
1
1
  import pdb
2
2
 
3
- from .builder import WorkflowBuilder
3
+ from ...local.workflow.builder import WorkflowBuilder
4
4
 
5
5
  class BuildDecorator():
6
6
 
@@ -1,29 +1,26 @@
1
1
  import os
2
2
  import pdb
3
3
 
4
+ from typing import List, Union
5
+
4
6
  from ...constants import (
5
- COMPOSE_TEMPLATE, SERVICE_HOSTNAME,
6
- SERVICE_HOSTNAME_ENV, SERVICE_NAME_ENV, SERVICE_PORT, SERVICE_PORT_ENV, SERVICE_SCHEME, SERVICE_SCHEME_ENV,
7
7
  WORKFLOW_CONTAINER_CONFIGURE_TEMPLATE, WORKFLOW_CONTAINER_INIT_TEMPLATE, WORKFLOW_CONTAINER_PROXY_TEMPLATE, WORKFLOW_NAME, WORKFLOW_NAME_ENV
8
8
  )
9
+ from ...local.workflow.builder import WorkflowBuilder
9
10
  from ..builder import Builder
10
- from ..service.builder import ServiceBuilder
11
-
12
- class WorkflowBuilder(Builder):
11
+ from ..constants import DOCKER_COMPOSE_WORKFLOW
12
+ from ..service.builder import DockerServiceBuilder
13
+ from .mock_decorator import MockDecorator
14
+ from .reverse_proxy_decorator import ReverseProxyDecorator
13
15
 
14
- def __init__(self, workflow_path: str, service_builder: ServiceBuilder):
15
- self._env = [SERVICE_NAME_ENV, WORKFLOW_NAME_ENV]
16
- self.__workflow_name = os.path.basename(workflow_path)
17
- super().__init__(workflow_path, COMPOSE_TEMPLATE.format(workflow=self.__workflow_name))
16
+ class DockerWorkflowBuilder(Builder, WorkflowBuilder):
18
17
 
19
- self.__context = '../'
20
- self.__profiles = [WORKFLOW_NAME]
18
+ def __init__(self, workflow_path: str, service_builder: DockerServiceBuilder):
19
+ WorkflowBuilder.__init__(self, workflow_path, service_builder)
20
+ Builder.__init__(self, workflow_path, DOCKER_COMPOSE_WORKFLOW)
21
21
 
22
- if not service_builder:
23
- service_path = os.path.dirname(workflow_path)
24
- service_builder = ServiceBuilder(service_path)
25
-
26
- self.__service_builder = service_builder
22
+ self._context = '../'
23
+ self._profiles = [WORKFLOW_NAME]
27
24
 
28
25
  @property
29
26
  def app(self):
@@ -33,17 +30,13 @@ class WorkflowBuilder(Builder):
33
30
  def base_compose_file_path(self):
34
31
  return os.path.relpath(self.service_builder.compose_file_path, self.dir_path)
35
32
 
36
- @property
37
- def config(self):
38
- return self.service_builder.config
39
-
40
33
  @property
41
34
  def configure(self):
42
35
  return WORKFLOW_CONTAINER_CONFIGURE_TEMPLATE.format(service_name=self.namespace)
43
36
 
44
37
  @property
45
38
  def context(self):
46
- return self.__context
39
+ return self._context
47
40
 
48
41
  @property
49
42
  def context_docker_file_path(self):
@@ -59,24 +52,12 @@ class WorkflowBuilder(Builder):
59
52
 
60
53
  @property
61
54
  def profiles(self):
62
- return self.__profiles
55
+ return self._profiles
63
56
 
64
57
  @property
65
58
  def proxy(self):
66
59
  return WORKFLOW_CONTAINER_PROXY_TEMPLATE.format(service_name=self.namespace)
67
60
 
68
- @property
69
- def service_builder(self):
70
- return self.__service_builder
71
-
72
- @property
73
- def service_path(self):
74
- return self.__service_builder.dir_path
75
-
76
- @property
77
- def workflow_name(self):
78
- return self.__workflow_name
79
-
80
61
  def build_all(self):
81
62
  # Resources
82
63
  if self.config.detached:
@@ -147,11 +128,21 @@ class WorkflowBuilder(Builder):
147
128
 
148
129
  self.with_service(self.proxy, service)
149
130
 
150
- def env_dict(self):
151
- env = {}
152
- for e in self._env:
153
- env[e] = '${' + e + '}'
154
- return env
131
+ def build(self, workflow_decorators: List[Union[MockDecorator, ReverseProxyDecorator]] = None):
132
+ """Build the Docker workflow with all components and decorators."""
133
+
134
+ # Build all workflow components
135
+ self.build_all()
136
+
137
+ # Apply workflow decorators if provided
138
+ if isinstance(workflow_decorators, list):
139
+ for workflow_decorator in workflow_decorators:
140
+ workflow_decorator(self).decorate()
141
+
142
+ # Write the compose file
143
+ self.write()
144
+
145
+ return self
155
146
 
156
147
  def write(self):
157
148
  compose = {
@@ -165,3 +156,4 @@ class WorkflowBuilder(Builder):
165
156
  compose['volumes'] = self.volumes
166
157
 
167
158
  super().write(compose)
159
+
@@ -1,7 +1,7 @@
1
1
  from ...constants import (
2
2
  SERVICE_UPSTREAM_HOSTNAME, SERVICE_UPSTREAM_PORT, SERVICE_UPSTREAM_SCHEME,
3
3
  )
4
- from .builder import WorkflowBuilder
4
+ from ...local.workflow.builder import WorkflowBuilder
5
5
 
6
6
  class CommandDecorator():
7
7
 
@@ -2,7 +2,7 @@ import os
2
2
  import pdb
3
3
 
4
4
  from ...constants import SERVICE_HOSTNAME, SERVICE_PORT, STOOBLY_CERTS_DIR
5
- from .builder import WorkflowBuilder
5
+ from ...local.workflow.builder import WorkflowBuilder
6
6
  from .command_decorator import CommandDecorator
7
7
 
8
8
  class DetachedDecorator(CommandDecorator):
@@ -1,8 +1,7 @@
1
1
  from ...constants import SERVICE_DNS
2
+ from ...local.workflow.builder import WorkflowBuilder
2
3
 
3
- from .builder import WorkflowBuilder
4
-
5
- class DnsDecorator():
4
+ class DnsDecorator:
6
5
 
7
6
  def __init__(self, workflow_builder: WorkflowBuilder):
8
7
  self.__workflow_builder = workflow_builder
@@ -1,4 +1,4 @@
1
- from .builder import WorkflowBuilder
1
+ from ...local.workflow.builder import WorkflowBuilder
2
2
 
3
3
  class LocalDecorator():
4
4
 
@@ -4,7 +4,7 @@ import pdb
4
4
  from ...constants import (
5
5
  SERVICE_HOSTNAME, SERVICE_PORT, STOOBLY_CERTS_DIR,
6
6
  )
7
- from .builder import WorkflowBuilder
7
+ from ...local.workflow.builder import WorkflowBuilder
8
8
  from .command_decorator import CommandDecorator
9
9
 
10
10
  class MockDecorator(CommandDecorator):
@@ -4,7 +4,7 @@ import pdb
4
4
  from urllib.parse import urlparse
5
5
 
6
6
  from ...constants import SERVICE_HOSTNAME, SERVICE_PORT, STOOBLY_CERTS_DIR
7
- from .builder import WorkflowBuilder
7
+ from ...local.workflow.builder import WorkflowBuilder
8
8
  from .command_decorator import CommandDecorator
9
9
 
10
10
  class ReverseProxyDecorator(CommandDecorator):