spaceforge 1.0.1__py3-none-any.whl → 1.1.0__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.
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '1.0.1'
32
- __version_tuple__ = version_tuple = (1, 0, 1)
31
+ __version__ = version = '1.1.0'
32
+ __version_tuple__ = version_tuple = (1, 1, 0)
33
33
 
34
34
  __commit_id__ = commit_id = None
spaceforge/cls.py CHANGED
@@ -121,6 +121,7 @@ class Context:
121
121
  labels (Optional[List[str]]): Labels associated with the context.
122
122
  env (list): List of variables associated with the context.
123
123
  hooks (dict): Hooks associated with the context.
124
+ priority (optional[int]): The priority of the context, contexts with 0 priority run before contexts with 1 priority.
124
125
  """
125
126
 
126
127
  name_prefix: str
@@ -129,6 +130,7 @@ class Context:
129
130
  mounted_files: Optional[List[MountedFile]] = optional_field
130
131
  hooks: Optional[Dict[HookType, List[str]]] = optional_field
131
132
  labels: Optional[List[str]] = optional_field
133
+ priority: int = 0
132
134
 
133
135
 
134
136
  @pydantic_dataclass
spaceforge/generator.py CHANGED
@@ -30,6 +30,41 @@ from .plugin import SpaceforgePlugin
30
30
  static_binary_directory = "/mnt/workspace/plugins/plugin_binaries"
31
31
 
32
32
 
33
+ def _update_context_names_for_priority(contexts: List[Context]) -> List[Context]:
34
+ if len(contexts) <= 1:
35
+ return contexts
36
+
37
+ # Get unique priority values and sort them
38
+ priorities = sorted(set(ctx.priority for ctx in contexts))
39
+
40
+ # Create mapping from priority to letter prefix
41
+ priority_to_letter = {}
42
+
43
+ for i, priority in enumerate(priorities):
44
+ if priority == 0:
45
+ # Priority 0 gets 'Z' (lowest priority = furthest from A)
46
+ letter = "Z"
47
+ else:
48
+ # Higher priority numbers get letters closer to 'A'
49
+ # Reverse the mapping: higher priority index = closer to A
50
+ letter_index = max(0, 25 - i) # Start from Z and work backwards
51
+ letter = chr(ord("A") + letter_index)
52
+
53
+ priority_to_letter[priority] = letter * 5 # Repeat 5 times
54
+
55
+ # Update context names
56
+ for ctx in contexts:
57
+ # Remove existing prefix if it starts with repeated letters
58
+ name = ctx.name_prefix
59
+ if len(name) >= 5 and name[:5].isupper() and len(set(name[:5])) == 1:
60
+ name = name[5:]
61
+
62
+ prefix = priority_to_letter[ctx.priority]
63
+ ctx.name_prefix = prefix + "-" + name
64
+
65
+ return contexts
66
+
67
+
33
68
  class PluginGenerator:
34
69
  """Generates plugin.yaml from a Python plugin class."""
35
70
 
@@ -257,29 +292,39 @@ class PluginGenerator:
257
292
  if self.plugin_class is None:
258
293
  raise ValueError("Plugin class not loaded. Call load_plugin() first.")
259
294
 
260
- contexts = getattr(
261
- self.plugin_class,
262
- "__contexts__",
263
- [
264
- Context(
265
- name_prefix=self.plugin_class.__plugin_name__.lower(),
266
- description=f"Main context for {self.plugin_class.__plugin_name__}",
267
- )
268
- ],
269
- )
295
+ contexts = getattr(self.plugin_class, "__contexts__", [])
270
296
 
271
- if contexts[0].hooks is None:
272
- contexts[0].hooks = {}
273
- if contexts[0].mounted_files is None:
274
- contexts[0].mounted_files = []
275
- if contexts[0].env is None:
276
- contexts[0].env = []
297
+ main_context: Optional[Context] = None
298
+ main_context_found = False
299
+ for context in contexts:
300
+ if context.priority == 0:
301
+ main_context = context
302
+ main_context_found = True
303
+ break
304
+
305
+ if main_context is None:
306
+ main_context = Context(
307
+ name_prefix=self.plugin_class.__plugin_name__.lower(),
308
+ description=f"Main context for {self.plugin_class.__plugin_name__}",
309
+ )
310
+
311
+ if main_context.hooks is None:
312
+ main_context.hooks = {}
313
+ if main_context.mounted_files is None:
314
+ main_context.mounted_files = []
315
+ if main_context.env is None:
316
+ main_context.env = []
277
317
 
278
318
  # Add the hooks and mounted files to the first context
279
- merge(contexts[0].hooks, hooks, strategy=Strategy.TYPESAFE_ADDITIVE)
280
- contexts[0].mounted_files += mounted_files
319
+ merge(main_context.hooks, hooks, strategy=Strategy.TYPESAFE_ADDITIVE)
320
+ main_context.mounted_files += mounted_files
321
+
322
+ # Ensure the main context is first
323
+ if not main_context_found:
324
+ contexts.insert(0, main_context)
281
325
 
282
326
  self._map_variables_to_parameters(contexts)
327
+ contexts = _update_context_names_for_priority(contexts)
283
328
 
284
329
  return contexts
285
330
 
@@ -380,6 +425,7 @@ class PluginGenerator:
380
425
  field.name: getattr(data, field.name)
381
426
  for field in fields(data)
382
427
  if getattr(data, field.name) is not None
428
+ and field.name != "priority"
383
429
  }
384
430
  return self.represent_dict(filtered_dict)
385
431
 
spaceforge/schema.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$defs": {
3
3
  "Context": {
4
- "description": "A class to represent a context for a plugin.\n\nAttributes:\n name_prefix (str): The name of the context, will be appended with a unique ID.\n description (str): A description of the context.\n labels (Optional[List[str]]): Labels associated with the context.\n env (list): List of variables associated with the context.\n hooks (dict): Hooks associated with the context.",
4
+ "description": "A class to represent a context for a plugin.\n\nAttributes:\n name_prefix (str): The name of the context, will be appended with a unique ID.\n description (str): A description of the context.\n labels (Optional[List[str]]): Labels associated with the context.\n env (list): List of variables associated with the context.\n hooks (dict): Hooks associated with the context.\n priority (optional[int]): The priority of the context, contexts with 0 priority run before contexts with 1 priority.",
5
5
  "properties": {
6
6
  "name_prefix": {
7
7
  "title": "Name Prefix",
@@ -84,6 +84,11 @@
84
84
  }
85
85
  ],
86
86
  "title": "Labels"
87
+ },
88
+ "priority": {
89
+ "default": 0,
90
+ "title": "Priority",
91
+ "type": "integer"
87
92
  }
88
93
  },
89
94
  "required": [
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spaceforge
3
- Version: 1.0.1
3
+ Version: 1.1.0
4
4
  Summary: A Python framework for building Spacelift plugins
5
5
  Home-page: https://github.com/spacelift-io/plugins
6
6
  Author: Spacelift
@@ -2,13 +2,13 @@ spaceforge/README.md,sha256=8o1Nuyasb4OxX3E7ZycyducOrR4J19bZcHrLvFeoFNg,7730
2
2
  spaceforge/__init__.py,sha256=TU-vvm15dK1ucixNW0V42eTT72x3_hmKSyxP4MC1Occ,589
3
3
  spaceforge/__main__.py,sha256=c3nAw4WBnHXIcfMlRV6Ja7r87pEhSeK-SAqiSYIasIY,643
4
4
  spaceforge/_version.py,sha256=RP_LfUd4ODnrfwn9nam8wB6bR3lM4VwmoRxK08Tkiiw,2155
5
- spaceforge/_version_scm.py,sha256=JvmBpae6cHui8lSCsCcZQAxzawN2NERHGsr-rIUeJMo,704
6
- spaceforge/cls.py,sha256=8jZ0noS-kIBQWHp7pWHOX6yzs5N30gIEm6-slWgBaKI,6182
5
+ spaceforge/_version_scm.py,sha256=ePNVzJOkxR8FY5bezqKQ_fgBRbzH1G7QTaRDHvGQRAY,704
6
+ spaceforge/cls.py,sha256=oYW5t5_xs9ZM6Ne_b4trxCPxLHQrqbqgUeibeM8O4PU,6329
7
7
  spaceforge/conftest.py,sha256=U-xCavCsgRAQXqflIIOMeq9pcGbeqRviUNkEXgZol8g,2141
8
- spaceforge/generator.py,sha256=7tt0zpqrD2pZsoVxQa0BfzBH1ZtGr6o3r_LmpBjrOJk,16739
8
+ spaceforge/generator.py,sha256=hCxtbOKmrGd7HCCz7HMaiK566kIre5MNxcJEx2TVURM,18430
9
9
  spaceforge/plugin.py,sha256=nNMus9cfVsazqvZG-buTWhK9CkeROdC5vQdOvc8EUQA,16129
10
10
  spaceforge/runner.py,sha256=EUZ98gmOiJ766zOSk7YcTTrLCtHfst1xf3iE2Xu7Tao,3172
11
- spaceforge/schema.json,sha256=F0STokM3YYT0xzcNdtnELZJJgpyi49mwk9Oj8ueD39s,10631
11
+ spaceforge/schema.json,sha256=89IROLVlCj8txGMiLt4Bbuo_2muSxKoZCyaXQ2vuA9c,10869
12
12
  spaceforge/test_cls.py,sha256=nXAgbnFnGdFxrtA7vNXiePjNUASuoYW-lEuQGx9WMGs,468
13
13
  spaceforge/test_generator.py,sha256=Nst3YVu_iZbFopH6ajjxCfqYrZvybteGbwMfZzjBFnI,32615
14
14
  spaceforge/test_generator_binaries.py,sha256=X_7pPLGE45eQt-Kv9_ku__LsyLgOvViHc_BvVpSCMp0,7263
@@ -25,9 +25,9 @@ spaceforge/test_runner_core.py,sha256=eNR9YOwJwv7LsMtNQ4WXXMPIW6RE_A7hUp4bCpzz1R
25
25
  spaceforge/test_runner_execution.py,sha256=GJhoECdhIY2M3MWcmTrIYfkJd2P5n86zixO3FY38_CQ,5344
26
26
  spaceforge/templates/binary_install.sh.j2,sha256=znz2G9mm3dOg0iqyxZoj4_ATBEi7HviMETMGRk5D7uM,536
27
27
  spaceforge/templates/ensure_spaceforge_and_run.sh.j2,sha256=g5BldIEve0IkZ-mCzTXfB_rFvyWqUJqymRRaaMrpp0s,550
28
- spaceforge-1.0.1.dist-info/licenses/LICENSE,sha256=wyljRrfnWY2ggQKkSCg3Nw2hxwPMmupopaKs9Kpgys8,1065
29
- spaceforge-1.0.1.dist-info/METADATA,sha256=OGZlYPvN4ualNlijN7PFq55LIZWNfcfgWCN6YgzHHhY,16803
30
- spaceforge-1.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
31
- spaceforge-1.0.1.dist-info/entry_points.txt,sha256=qawuuKBSNTGg-njnQnhxxFldFvXYAPej6bF_f3iyQ48,56
32
- spaceforge-1.0.1.dist-info/top_level.txt,sha256=eVw-Lw4Th0oHM8Gx1Y8YetyNgbNbMBU00yWs-kwGeSs,11
33
- spaceforge-1.0.1.dist-info/RECORD,,
28
+ spaceforge-1.1.0.dist-info/licenses/LICENSE,sha256=wyljRrfnWY2ggQKkSCg3Nw2hxwPMmupopaKs9Kpgys8,1065
29
+ spaceforge-1.1.0.dist-info/METADATA,sha256=pn-bRqlzGeEYFB-mqbrdgfYWOJUvy9pU3lGsbUuR-Ro,16803
30
+ spaceforge-1.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
31
+ spaceforge-1.1.0.dist-info/entry_points.txt,sha256=qawuuKBSNTGg-njnQnhxxFldFvXYAPej6bF_f3iyQ48,56
32
+ spaceforge-1.1.0.dist-info/top_level.txt,sha256=eVw-Lw4Th0oHM8Gx1Y8YetyNgbNbMBU00yWs-kwGeSs,11
33
+ spaceforge-1.1.0.dist-info/RECORD,,