iris-pex-embedded-python 4.0.0b8__tar.gz → 4.0.0b10__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.
- {iris_pex_embedded_python-4.0.0b8/src/iris_pex_embedded_python.egg-info → iris_pex_embedded_python-4.0.0b10}/PKG-INFO +1 -1
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/pyproject.toml +4 -1
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/__init__.py +10 -2
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cli/main.py +140 -1
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cli/parser.py +33 -1
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cli/types.py +15 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/Utils.cls +403 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/components/business_host.py +29 -24
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/components/business_process.py +2 -2
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/migration/utils.py +21 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/production/__init__.py +10 -2
- iris_pex_embedded_python-4.0.0b10/src/iop/production/actions.py +525 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/production/component.py +29 -29
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/production/declarations.py +22 -17
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/production/declarative.py +88 -25
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/production/diff.py +5 -5
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/production/import_.py +29 -8
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/production/inspection.py +1 -1
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/production/model.py +229 -87
- iris_pex_embedded_python-4.0.0b10/src/iop/production/planning.py +678 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/production/reconstruction.py +139 -8
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/production/rendering.py +27 -18
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/production/runtime.py +22 -7
- iris_pex_embedded_python-4.0.0b10/src/iop/production/source_inference.py +681 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/production/types.py +225 -11
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/runtime/local.py +10 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/runtime/protocol.py +5 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/runtime/remote/director.py +10 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10/src/iris_pex_embedded_python.egg-info}/PKG-INFO +1 -1
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iris_pex_embedded_python.egg-info/SOURCES.txt +2 -0
- iris_pex_embedded_python-4.0.0b8/src/iop/production/actions.py +0 -228
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/LICENSE +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/README.md +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/setup.cfg +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/__main__.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cli/__init__.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cli/formatting.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/BusinessOperation.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/BusinessProcess.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/BusinessService.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/Common.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/Director.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/Duplex/Operation.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/Duplex/Process.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/Duplex/Service.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/Generator/Message/Ack.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/Generator/Message/Poll.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/Generator/Message/Start.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/Generator/Message/StartPickle.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/Generator/Message/Stop.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/InboundAdapter.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/Message/JSONSchema.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/Message.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/OutboundAdapter.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/PickleMessage.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/PrivateSession/Duplex.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/PrivateSession/Message/Ack.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/PrivateSession/Message/Poll.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/PrivateSession/Message/Start.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/PrivateSession/Message/Stop.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/Projection.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/Service/Remote/Handler.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/Service/Remote/Rest/v1.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/Test.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cls/IOP/Wrapper.cls +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/components/__init__.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/components/async_request.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/components/business_operation.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/components/business_service.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/components/common.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/components/debugpy.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/components/generator_request.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/components/inbound_adapter.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/components/log_manager.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/components/outbound_adapter.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/components/polling_business_service.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/components/private_session_duplex.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/components/private_session_process.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/components/settings.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/messages/__init__.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/messages/base.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/messages/decorators.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/messages/dispatch.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/messages/persistent.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/messages/serialization.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/messages/validation.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/migration/__init__.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/migration/io.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/migration/manifest.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/migration/plans.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/production/common.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/production/validation.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/runtime/__init__.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/runtime/director.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/runtime/environment.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/runtime/iris.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/runtime/remote/__init__.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/runtime/remote/client.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/runtime/remote/migration.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/runtime/remote/settings.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/runtime/remote/setup.py +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iris_pex_embedded_python.egg-info/dependency_links.txt +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iris_pex_embedded_python.egg-info/entry_points.txt +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iris_pex_embedded_python.egg-info/requires.txt +0 -0
- {iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iris_pex_embedded_python.egg-info/top_level.txt +0 -0
|
@@ -3,7 +3,7 @@ requires = ["setuptools", "wheel"]
|
|
|
3
3
|
|
|
4
4
|
[project]
|
|
5
5
|
name = "iris_pex_embedded_python"
|
|
6
|
-
version = "4.0.
|
|
6
|
+
version = "4.0.0b10"
|
|
7
7
|
description = "Iris Interoperability based on Embedded Python"
|
|
8
8
|
readme = "README.md"
|
|
9
9
|
requires-python = ">=3.10"
|
|
@@ -63,6 +63,9 @@ markers = [
|
|
|
63
63
|
"e2e_remote: end-to-end test requiring a remote IRIS instance via REST API",
|
|
64
64
|
]
|
|
65
65
|
|
|
66
|
+
[tool.pyright]
|
|
67
|
+
pythonVersion = "3.10"
|
|
68
|
+
|
|
66
69
|
[tool.ruff]
|
|
67
70
|
target-version = "py310"
|
|
68
71
|
line-length = 88
|
|
@@ -29,19 +29,23 @@ from iop.migration.utils import unregister_component as unregister_component
|
|
|
29
29
|
from iop.production import ComponentItem as ComponentItem
|
|
30
30
|
from iop.production import ComponentRef as ComponentRef
|
|
31
31
|
from iop.production import OperationItem as OperationItem
|
|
32
|
-
from iop.production import Port as Port
|
|
33
32
|
from iop.production import ProcessItem as ProcessItem
|
|
34
33
|
from iop.production import Production as Production
|
|
34
|
+
from iop.production import ProductionApplyResult as ProductionApplyResult
|
|
35
|
+
from iop.production import ProductionChangePlan as ProductionChangePlan
|
|
35
36
|
from iop.production import ProductionDiff as ProductionDiff
|
|
36
37
|
from iop.production import ProductionDiffEntry as ProductionDiffEntry
|
|
37
38
|
from iop.production import ProductionGraph as ProductionGraph
|
|
39
|
+
from iop.production import ProductionPlanOperation as ProductionPlanOperation
|
|
38
40
|
from iop.production import ProductionValidationError as ProductionValidationError
|
|
39
41
|
from iop.production import ProductionValidationIssue as ProductionValidationIssue
|
|
40
42
|
from iop.production import ProductionValidationReport as ProductionValidationReport
|
|
41
43
|
from iop.production import ProductionValidationWarning as ProductionValidationWarning
|
|
44
|
+
from iop.production import ProductionVerifyResult as ProductionVerifyResult
|
|
42
45
|
from iop.production import Route as Route
|
|
43
46
|
from iop.production import ServiceItem as ServiceItem
|
|
44
47
|
from iop.production import TargetSetting as TargetSetting
|
|
48
|
+
from iop.production import TargetSettingRef as TargetSettingRef
|
|
45
49
|
from iop.production import target as target
|
|
46
50
|
from iop.runtime.director import _Director
|
|
47
51
|
from iop.runtime.protocol import DirectorProtocol as DirectorProtocol
|
|
@@ -67,12 +71,15 @@ __all__ = [
|
|
|
67
71
|
"PersistentMessage",
|
|
68
72
|
"PickleMessage",
|
|
69
73
|
"PollingBusinessService",
|
|
70
|
-
"Port",
|
|
71
74
|
"ProcessItem",
|
|
72
75
|
"Production",
|
|
76
|
+
"ProductionApplyResult",
|
|
77
|
+
"ProductionChangePlan",
|
|
73
78
|
"ProductionDiff",
|
|
74
79
|
"ProductionDiffEntry",
|
|
75
80
|
"ProductionGraph",
|
|
81
|
+
"ProductionPlanOperation",
|
|
82
|
+
"ProductionVerifyResult",
|
|
76
83
|
"ProductionValidationError",
|
|
77
84
|
"ProductionValidationIssue",
|
|
78
85
|
"ProductionValidationReport",
|
|
@@ -83,6 +90,7 @@ __all__ = [
|
|
|
83
90
|
"ServiceItem",
|
|
84
91
|
"Setting",
|
|
85
92
|
"TargetSetting",
|
|
93
|
+
"TargetSettingRef",
|
|
86
94
|
"Utils",
|
|
87
95
|
"bind_component",
|
|
88
96
|
"controls",
|
|
@@ -9,7 +9,7 @@ from importlib.metadata import version
|
|
|
9
9
|
import requests
|
|
10
10
|
|
|
11
11
|
from ..migration import utils as migration_utils
|
|
12
|
-
from ..production import Production
|
|
12
|
+
from ..production import Production, ProductionChangePlan
|
|
13
13
|
from ..runtime.local import _LocalDirector
|
|
14
14
|
from ..runtime.protocol import DirectorProtocol
|
|
15
15
|
from ..runtime.remote import _RemoteDirector, get_remote_settings
|
|
@@ -78,6 +78,11 @@ class Command:
|
|
|
78
78
|
self.args.bindings,
|
|
79
79
|
self.args.unbind is not None,
|
|
80
80
|
self.args.update,
|
|
81
|
+
self.args.plan,
|
|
82
|
+
self.args.review_plan,
|
|
83
|
+
self.args.apply_plan,
|
|
84
|
+
self.args.verify_plan,
|
|
85
|
+
self.args.rollback_backup,
|
|
81
86
|
]
|
|
82
87
|
)
|
|
83
88
|
|
|
@@ -109,6 +114,11 @@ class Command:
|
|
|
109
114
|
CommandType.UNBIND: self._handle_unbind,
|
|
110
115
|
CommandType.HELP: self._handle_help,
|
|
111
116
|
CommandType.UPDATE: self._handle_update,
|
|
117
|
+
CommandType.PLAN: self._handle_plan,
|
|
118
|
+
CommandType.REVIEW_PLAN: self._handle_review_plan,
|
|
119
|
+
CommandType.APPLY_PLAN: self._handle_apply_plan,
|
|
120
|
+
CommandType.VERIFY_PLAN: self._handle_verify_plan,
|
|
121
|
+
CommandType.ROLLBACK_BACKUP: self._handle_rollback_backup,
|
|
112
122
|
}
|
|
113
123
|
handler = command_handlers.get(command_type)
|
|
114
124
|
if handler:
|
|
@@ -149,6 +159,16 @@ class Command:
|
|
|
149
159
|
return CommandType.UNBIND
|
|
150
160
|
if self.args.update:
|
|
151
161
|
return CommandType.UPDATE
|
|
162
|
+
if self.args.plan:
|
|
163
|
+
return CommandType.PLAN
|
|
164
|
+
if self.args.review_plan:
|
|
165
|
+
return CommandType.REVIEW_PLAN
|
|
166
|
+
if self.args.apply_plan:
|
|
167
|
+
return CommandType.APPLY_PLAN
|
|
168
|
+
if self.args.verify_plan:
|
|
169
|
+
return CommandType.VERIFY_PLAN
|
|
170
|
+
if self.args.rollback_backup:
|
|
171
|
+
return CommandType.ROLLBACK_BACKUP
|
|
152
172
|
return CommandType.HELP
|
|
153
173
|
|
|
154
174
|
def _handle_default(self) -> None:
|
|
@@ -236,6 +256,9 @@ class Command:
|
|
|
236
256
|
if export_format == "graph":
|
|
237
257
|
print(production.graph())
|
|
238
258
|
return
|
|
259
|
+
if export_format == "mermaid":
|
|
260
|
+
print(production.to_mermaid(), end="")
|
|
261
|
+
return
|
|
239
262
|
raise ValueError(f"Unsupported export format: {export_format}")
|
|
240
263
|
|
|
241
264
|
def _handle_migrate(self) -> None:
|
|
@@ -324,6 +347,55 @@ class Command:
|
|
|
324
347
|
self.director.unbind_component(self.args.unbind)
|
|
325
348
|
print(f"Removed binding {self.args.unbind}.")
|
|
326
349
|
|
|
350
|
+
def _handle_plan(self) -> None:
|
|
351
|
+
production = self._load_production_from_settings(
|
|
352
|
+
self.args.plan,
|
|
353
|
+
self.args.production,
|
|
354
|
+
)
|
|
355
|
+
plan = production.plan()
|
|
356
|
+
if self.args.out:
|
|
357
|
+
plan.save(self._absolute_path(self.args.out))
|
|
358
|
+
print(f"Production change plan written to {self.args.out}")
|
|
359
|
+
else:
|
|
360
|
+
print(plan)
|
|
361
|
+
|
|
362
|
+
def _handle_review_plan(self) -> None:
|
|
363
|
+
plan = ProductionChangePlan.load(self._absolute_path(self.args.review_plan))
|
|
364
|
+
print(plan)
|
|
365
|
+
|
|
366
|
+
def _handle_apply_plan(self) -> None:
|
|
367
|
+
if not self.args.settings:
|
|
368
|
+
raise ValueError("--apply-plan requires --settings.")
|
|
369
|
+
plan = ProductionChangePlan.load(self._absolute_path(self.args.apply_plan))
|
|
370
|
+
production = self._load_production_from_settings(
|
|
371
|
+
self.args.settings,
|
|
372
|
+
self.args.production or plan.production_name,
|
|
373
|
+
)
|
|
374
|
+
result = production.apply(
|
|
375
|
+
plan,
|
|
376
|
+
allow_destructive=self.args.allow_destructive,
|
|
377
|
+
backup_dir=self.args.backup_dir,
|
|
378
|
+
)
|
|
379
|
+
print(result)
|
|
380
|
+
|
|
381
|
+
def _handle_verify_plan(self) -> None:
|
|
382
|
+
plan = ProductionChangePlan.load(self._absolute_path(self.args.verify_plan))
|
|
383
|
+
production = Production(
|
|
384
|
+
self.args.production or plan.production_name,
|
|
385
|
+
namespace=self.director.namespace,
|
|
386
|
+
director=self.director,
|
|
387
|
+
)
|
|
388
|
+
print(production.verify(plan))
|
|
389
|
+
|
|
390
|
+
def _handle_rollback_backup(self) -> None:
|
|
391
|
+
result = Production.rollback_backup(
|
|
392
|
+
self._absolute_path(self.args.rollback_backup),
|
|
393
|
+
director=self.director,
|
|
394
|
+
namespace=self.director.namespace,
|
|
395
|
+
allow_destructive=self.args.allow_destructive,
|
|
396
|
+
)
|
|
397
|
+
print(result)
|
|
398
|
+
|
|
327
399
|
def _handle_help(self) -> None:
|
|
328
400
|
create_parser().print_help()
|
|
329
401
|
if self._is_remote:
|
|
@@ -334,6 +406,73 @@ class Command:
|
|
|
334
406
|
except Exception:
|
|
335
407
|
logging.warning("Could not retrieve default production.")
|
|
336
408
|
|
|
409
|
+
def _load_production_from_settings(
|
|
410
|
+
self,
|
|
411
|
+
settings_file: str | None,
|
|
412
|
+
production_name: str | None,
|
|
413
|
+
) -> Production:
|
|
414
|
+
if not settings_file:
|
|
415
|
+
raise ValueError("A settings.py file is required.")
|
|
416
|
+
settings_path = self._absolute_path(settings_file)
|
|
417
|
+
settings, path_added = migration_utils._load_settings(settings_path)
|
|
418
|
+
try:
|
|
419
|
+
production = _select_production(
|
|
420
|
+
getattr(settings, "PRODUCTIONS", None),
|
|
421
|
+
production_name,
|
|
422
|
+
director=self.director,
|
|
423
|
+
namespace=self.director.namespace,
|
|
424
|
+
)
|
|
425
|
+
production.with_director(self.director)
|
|
426
|
+
if not production.namespace:
|
|
427
|
+
production.in_namespace(self.director.namespace)
|
|
428
|
+
return production
|
|
429
|
+
finally:
|
|
430
|
+
migration_utils._cleanup_sys_path(path_added)
|
|
431
|
+
|
|
432
|
+
@staticmethod
|
|
433
|
+
def _absolute_path(path: str | None) -> str:
|
|
434
|
+
if not path:
|
|
435
|
+
raise ValueError("Path is required.")
|
|
436
|
+
if os.path.isabs(path):
|
|
437
|
+
return path
|
|
438
|
+
return os.path.join(os.getcwd(), path)
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
def _select_production(
|
|
442
|
+
productions,
|
|
443
|
+
production_name: str | None,
|
|
444
|
+
*,
|
|
445
|
+
director: DirectorProtocol,
|
|
446
|
+
namespace: str | None,
|
|
447
|
+
) -> Production:
|
|
448
|
+
if not isinstance(productions, list):
|
|
449
|
+
raise ValueError("settings.py must define PRODUCTIONS as a list.")
|
|
450
|
+
candidates: list[Production] = []
|
|
451
|
+
for entry in productions:
|
|
452
|
+
if isinstance(entry, Production):
|
|
453
|
+
candidate = entry
|
|
454
|
+
elif isinstance(entry, dict):
|
|
455
|
+
candidate = Production.from_dict(
|
|
456
|
+
entry,
|
|
457
|
+
director=director,
|
|
458
|
+
namespace=namespace,
|
|
459
|
+
)
|
|
460
|
+
else:
|
|
461
|
+
continue
|
|
462
|
+
candidates.append(candidate)
|
|
463
|
+
if production_name:
|
|
464
|
+
for candidate in candidates:
|
|
465
|
+
if candidate.name == production_name:
|
|
466
|
+
return candidate
|
|
467
|
+
raise ValueError(f"Production {production_name!r} not found in settings.")
|
|
468
|
+
if len(candidates) == 1:
|
|
469
|
+
return candidates[0]
|
|
470
|
+
names = ", ".join(candidate.name for candidate in candidates) or "none"
|
|
471
|
+
raise ValueError(
|
|
472
|
+
"Production name is required when settings.py contains multiple "
|
|
473
|
+
f"productions ({names})."
|
|
474
|
+
)
|
|
475
|
+
|
|
337
476
|
|
|
338
477
|
def main(argv=None) -> None:
|
|
339
478
|
parser = create_parser()
|
{iris_pex_embedded_python-4.0.0b8 → iris_pex_embedded_python-4.0.0b10}/src/iop/cli/parser.py
RENAMED
|
@@ -64,6 +64,17 @@ def create_parser() -> argparse.ArgumentParser:
|
|
|
64
64
|
"-t", "--test", help="test the iop module in iris", nargs="?", const="not_set"
|
|
65
65
|
)
|
|
66
66
|
parser.add_argument("-u", "--update", help="update a production", action="store_true")
|
|
67
|
+
parser.add_argument(
|
|
68
|
+
"--plan",
|
|
69
|
+
help="build a conservative production change plan from a Python settings file",
|
|
70
|
+
)
|
|
71
|
+
parser.add_argument("--review-plan", help="print a saved production change plan")
|
|
72
|
+
parser.add_argument("--apply-plan", help="apply a saved production change plan")
|
|
73
|
+
parser.add_argument("--verify-plan", help="verify a saved production change plan")
|
|
74
|
+
parser.add_argument(
|
|
75
|
+
"--rollback-backup",
|
|
76
|
+
help="restore a production from a plan/apply backup directory",
|
|
77
|
+
)
|
|
67
78
|
|
|
68
79
|
start = main_parser.add_argument_group("start arguments")
|
|
69
80
|
start.add_argument(
|
|
@@ -105,7 +116,7 @@ def create_parser() -> argparse.ArgumentParser:
|
|
|
105
116
|
export.add_argument(
|
|
106
117
|
"--format",
|
|
107
118
|
dest="export_format",
|
|
108
|
-
choices=("json", "python", "class", "graph"),
|
|
119
|
+
choices=("json", "python", "class", "graph", "mermaid"),
|
|
109
120
|
default="json",
|
|
110
121
|
help="export format for -e/--export",
|
|
111
122
|
)
|
|
@@ -117,6 +128,27 @@ def create_parser() -> argparse.ArgumentParser:
|
|
|
117
128
|
action="store_true",
|
|
118
129
|
)
|
|
119
130
|
|
|
131
|
+
plan = main_parser.add_argument_group("production plan arguments")
|
|
132
|
+
plan.add_argument(
|
|
133
|
+
"--production",
|
|
134
|
+
help="target production name for --plan, or override the plan production",
|
|
135
|
+
)
|
|
136
|
+
plan.add_argument("--out", help="write --plan JSON to this path")
|
|
137
|
+
plan.add_argument(
|
|
138
|
+
"--settings",
|
|
139
|
+
help="settings.py file containing the desired Production for --apply-plan",
|
|
140
|
+
)
|
|
141
|
+
plan.add_argument(
|
|
142
|
+
"--backup-dir",
|
|
143
|
+
default=".iop/backups",
|
|
144
|
+
help="directory for apply backup artifacts",
|
|
145
|
+
)
|
|
146
|
+
plan.add_argument(
|
|
147
|
+
"--allow-destructive",
|
|
148
|
+
help="allow destructive plan operations or rollback",
|
|
149
|
+
action="store_true",
|
|
150
|
+
)
|
|
151
|
+
|
|
120
152
|
remote = main_parser.add_argument_group("remote arguments")
|
|
121
153
|
remote.add_argument(
|
|
122
154
|
"-R",
|
|
@@ -23,6 +23,11 @@ class CommandType(Enum):
|
|
|
23
23
|
UNBIND = auto()
|
|
24
24
|
HELP = auto()
|
|
25
25
|
UPDATE = auto()
|
|
26
|
+
PLAN = auto()
|
|
27
|
+
REVIEW_PLAN = auto()
|
|
28
|
+
APPLY_PLAN = auto()
|
|
29
|
+
VERIFY_PLAN = auto()
|
|
30
|
+
ROLLBACK_BACKUP = auto()
|
|
26
31
|
|
|
27
32
|
|
|
28
33
|
@dataclass
|
|
@@ -56,3 +61,13 @@ class CommandArgs:
|
|
|
56
61
|
update: bool = False
|
|
57
62
|
migration_plan: bool = False
|
|
58
63
|
strict_production_validation: bool = False
|
|
64
|
+
plan: str | None = None
|
|
65
|
+
production: str | None = None
|
|
66
|
+
out: str | None = None
|
|
67
|
+
review_plan: str | None = None
|
|
68
|
+
apply_plan: str | None = None
|
|
69
|
+
verify_plan: str | None = None
|
|
70
|
+
rollback_backup: str | None = None
|
|
71
|
+
settings: str | None = None
|
|
72
|
+
backup_dir: str = ".iop/backups"
|
|
73
|
+
allow_destructive: bool = False
|