buildzr 0.0.18__py3-none-any.whl → 0.0.20__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.
buildzr/__about__.py CHANGED
@@ -1 +1 @@
1
- VERSION = "0.0.18"
1
+ VERSION = "0.0.20"
buildzr/dsl/dsl.py CHANGED
@@ -129,14 +129,14 @@ class Workspace(DslWorkspaceElement):
129
129
 
130
130
  _current_workspace.reset(self._token)
131
131
 
132
- def _imply_relationships(
133
- self,
132
+ def _imply_relationships( self,
134
133
  ) -> None:
135
134
 
136
135
  """
137
136
  Process implied relationships:
138
137
  If we have relationship s >> do >> a.b, then create s >> do >> a.
139
138
  If we have relationship s.ss >> do >> a.b.c, then create s.ss >> do >> a.b and s.ss >> do >> a.
139
+ If we have relationship s.ss >> do >> a, then create s >> do >> a.
140
140
  And so on...
141
141
 
142
142
  Relationships of `SoftwareSystemInstance`s and `ContainerInstance`s are
@@ -152,6 +152,7 @@ class Workspace(DslWorkspaceElement):
152
152
  from buildzr.dsl.explorer import Explorer
153
153
 
154
154
  explorer = Explorer(self)
155
+ # Take a snapshot of relationships to avoid processing newly created ones
155
156
  relationships = list(explorer.walk_relationships())
156
157
  for relationship in relationships:
157
158
  source = relationship.source
@@ -162,6 +163,11 @@ class Workspace(DslWorkspaceElement):
162
163
  isinstance(destination, (SoftwareSystemInstance, ContainerInstance)):
163
164
  continue
164
165
 
166
+ # Skip relationships that are already implied (have linkedRelationshipId)
167
+ if relationship.model.linkedRelationshipId is not None:
168
+ continue
169
+
170
+ # Handle case: s >> a.b => s >> a (destination is child)
165
171
  while destination_parent is not None and \
166
172
  isinstance(source, DslElement) and \
167
173
  not isinstance(source.model, buildzr.models.Workspace) and \
@@ -186,7 +192,38 @@ class Workspace(DslWorkspaceElement):
186
192
  technology=relationship.model.technology,
187
193
  )
188
194
  r.model.linkedRelationshipId = relationship.model.id
189
- destination_parent = destination_parent.parent
195
+ destination_parent = destination_parent.parent
196
+
197
+ # Handle inverse case: s.ss >> a => s >> a (source is child)
198
+ source_parent = source.parent
199
+ while source_parent is not None and \
200
+ isinstance(destination, DslElement) and \
201
+ not isinstance(destination.model, buildzr.models.Workspace) and \
202
+ not isinstance(source_parent.model, buildzr.models.Workspace) and \
203
+ not isinstance(source_parent, DslWorkspaceElement):
204
+
205
+ if source_parent is destination.parent:
206
+ break
207
+
208
+ rels = source_parent.model.relationships
209
+
210
+ # The parent source relationship might be empty
211
+ # (i.e., []).
212
+ if rels is not None:
213
+ already_exists = any(
214
+ r.destinationId == destination.model.id and
215
+ r.description == relationship.model.description and
216
+ r.technology == relationship.model.technology
217
+ for r in rels
218
+ )
219
+ if not already_exists:
220
+ r = source_parent.uses(
221
+ destination,
222
+ description=relationship.model.description,
223
+ technology=relationship.model.technology,
224
+ )
225
+ r.model.linkedRelationshipId = relationship.model.id
226
+ source_parent = source_parent.parent
190
227
 
191
228
  def person(self) -> TypedDynamicAttribute['Person']:
192
229
  return TypedDynamicAttribute['Person'](self._dynamic_attrs)
@@ -371,6 +408,7 @@ class SoftwareSystem(DslElementRelationOverrides[
371
408
  self.model.id = GenerateId.for_element()
372
409
  self.model.name = name
373
410
  self.model.description = description
411
+ self.model.relationships = []
374
412
  self.model.tags = ','.join(self._tags)
375
413
  self.model.properties = properties
376
414
 
@@ -804,6 +842,10 @@ class DeploymentEnvironment(DslDeploymentEnvironment):
804
842
  new relationship between those software system instances.
805
843
 
806
844
  These implied relationships are used in `DeploymentView`.
845
+
846
+ Relationships are only created between instances that share at least
847
+ one common deployment group. If no deployment groups are specified,
848
+ instances are considered to be in the same default group.
807
849
  """
808
850
 
809
851
  software_instances = [
@@ -839,12 +881,25 @@ class DeploymentEnvironment(DslDeploymentEnvironment):
839
881
  if not relationship.destinationId in other_softwares_ids:
840
882
  continue
841
883
 
884
+ if software.model.id not in software_instance_map:
885
+ continue
886
+
887
+ if relationship.destinationId not in software_instance_map:
888
+ continue
889
+
842
890
  this_software_instances = software_instance_map[software.model.id]
843
891
  other_software_instances = software_instance_map[relationship.destinationId]
844
892
 
845
893
  for this_software_instance in this_software_instances:
846
894
  for other_software_instance in other_software_instances:
847
895
 
896
+ # Only create relationship if instances share a deployment group
897
+ if not self._instances_share_deployment_group(
898
+ this_software_instance,
899
+ other_software_instance
900
+ ):
901
+ continue
902
+
848
903
  already_exists = this_software_instance.model.relationships is not None and any(
849
904
  r.sourceId == this_software_instance.model.id and
850
905
  r.destinationId == other_software_instance.model.id and
@@ -862,6 +917,40 @@ class DeploymentEnvironment(DslDeploymentEnvironment):
862
917
  )
863
918
  r.model.linkedRelationshipId = relationship.id
864
919
 
920
+ def _instances_share_deployment_group(
921
+ self,
922
+ instance1: Union['ContainerInstance', 'SoftwareSystemInstance'],
923
+ instance2: Union['ContainerInstance', 'SoftwareSystemInstance']
924
+ ) -> bool:
925
+ """
926
+ Check if two deployment instances share at least one common deployment group.
927
+
928
+ If either instance has no deployment groups specified, they are considered
929
+ to be in the "default" group and can relate to all other instances without
930
+ deployment groups.
931
+
932
+ Args:
933
+ instance1: First deployment instance
934
+ instance2: Second deployment instance
935
+
936
+ Returns:
937
+ True if instances share at least one deployment group or if both have
938
+ no deployment groups specified, False otherwise.
939
+ """
940
+ groups1 = set(instance1.model.deploymentGroups or [])
941
+ groups2 = set(instance2.model.deploymentGroups or [])
942
+
943
+ # If both have no deployment groups, they can relate
944
+ if not groups1 and not groups2:
945
+ return True
946
+
947
+ # If one has groups and the other doesn't, they cannot relate
948
+ if (groups1 and not groups2) or (not groups1 and groups2):
949
+ return False
950
+
951
+ # Check if they share at least one common group
952
+ return bool(groups1.intersection(groups2))
953
+
865
954
  def _imply_container_instance_relationships(self, workspace: Workspace) -> None:
866
955
 
867
956
  """
@@ -871,6 +960,10 @@ class DeploymentEnvironment(DslDeploymentEnvironment):
871
960
  between those container instances.
872
961
 
873
962
  These implied relationships are used in `DeploymentView`.
963
+
964
+ Relationships are only created between instances that share at least
965
+ one common deployment group. If no deployment groups are specified,
966
+ instances are considered to be in the same default group.
874
967
  """
875
968
 
876
969
  from buildzr.dsl.expression import Expression
@@ -907,12 +1000,25 @@ class DeploymentEnvironment(DslDeploymentEnvironment):
907
1000
  if not relationship.destinationId in other_containers_ids:
908
1001
  continue
909
1002
 
1003
+ if container.model.id not in container_instance_map:
1004
+ continue
1005
+
1006
+ if relationship.destinationId not in container_instance_map:
1007
+ continue
1008
+
910
1009
  this_container_instances = container_instance_map[container.model.id]
911
1010
  other_container_instances = container_instance_map[relationship.destinationId]
912
1011
 
913
1012
  for this_container_instance in this_container_instances:
914
1013
  for other_container_instance in other_container_instances:
915
1014
 
1015
+ # Only create relationship if instances share a deployment group
1016
+ if not self._instances_share_deployment_group(
1017
+ this_container_instance,
1018
+ other_container_instance
1019
+ ):
1020
+ continue
1021
+
916
1022
  already_exists = this_container_instance.model.relationships is not None and any(
917
1023
  r.sourceId == this_container_instance.model.id and
918
1024
  r.destinationId == other_container_instance.model.id and
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: buildzr
3
- Version: 0.0.18
3
+ Version: 0.0.20
4
4
  Summary: Structurizr for the `buildzr`s 🧱⚒️
5
5
  Project-URL: homepage, https://github.com/amirulmenjeni/buildzr
6
6
  Project-URL: issues, https://github.com/amirulmenjeni/buildzr/issues
@@ -1,8 +1,8 @@
1
- buildzr/__about__.py,sha256=1LKzsaMbuDHBcCQ6ItSCPh_aBbnriHkKXEDMLVVsZJQ,19
1
+ buildzr/__about__.py,sha256=3JVoTwSM4MKD3-jf3WLeZSwhgAFSJco2QrGtDy-ehEI,19
2
2
  buildzr/__init__.py,sha256=hY-cOdjBQcz0v2m8cBF1oEJFIbcR3sWI-xww--0RKSo,99
3
3
  buildzr/dsl/__init__.py,sha256=qJ41IXcabKUjvwMzgfUCFdmDnSBBK7VFADpoVdOYLKQ,538
4
4
  buildzr/dsl/color.py,sha256=at5lo3WgLEDCjrnbu37ra1p1TjzdB51sxeW7pBMC_7U,4019
5
- buildzr/dsl/dsl.py,sha256=Z7dr0RLGMY5XKMtBTZJ9Kj1m6CAuA3TTTzLnpxR2SsE,84194
5
+ buildzr/dsl/dsl.py,sha256=Z0QZ-uNtP6GIYytgOkIHfiqn4At59lmtUsHplOaYZgQ,88930
6
6
  buildzr/dsl/explorer.py,sha256=m1nI0Rd0bXGj1uXDgTC4DJhc2FMma522IepPNvQF07E,1853
7
7
  buildzr/dsl/expression.py,sha256=TLSe-uGlHhNqMPQU_5IRLIP-ZGsQ_ts3DquBMcYlwBg,11777
8
8
  buildzr/dsl/relations.py,sha256=GBs5epr9uuExU_H6VcP4XY76iJPQ__rz_d8tZlhhWQ4,11891
@@ -18,7 +18,7 @@ buildzr/models/models.py,sha256=NJOFYiRQ2i_1gP2ajPNpEfVLAz-1iCqqt1gPOHDPIks,4258
18
18
  buildzr/sinks/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  buildzr/sinks/interfaces.py,sha256=LOZekP4WNjomD5J5f3FnZTwGj0aXMr6RbrvyFV5zn0E,383
20
20
  buildzr/sinks/json_sink.py,sha256=w_16ulQl2s-J-Yokp6GvDhAhuqN8XggXyEHCUNETLu4,865
21
- buildzr-0.0.18.dist-info/METADATA,sha256=naP5ylRsLZTmqIQkQay09BL7PKo8t_Cns3WzFJCTdhE,6596
22
- buildzr-0.0.18.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
23
- buildzr-0.0.18.dist-info/licenses/LICENSE.md,sha256=e8e6W6tL4MbBY-c-gXMgDbaMf_BnaQDQv4Yoy42b-CI,1070
24
- buildzr-0.0.18.dist-info/RECORD,,
21
+ buildzr-0.0.20.dist-info/METADATA,sha256=hFxv7edVPOOPQlm14LUSbn_FkibpFAk1U1j7eR1wSw0,6596
22
+ buildzr-0.0.20.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
23
+ buildzr-0.0.20.dist-info/licenses/LICENSE.md,sha256=e8e6W6tL4MbBY-c-gXMgDbaMf_BnaQDQv4Yoy42b-CI,1070
24
+ buildzr-0.0.20.dist-info/RECORD,,