spaceforge 1.1.3__py3-none-any.whl → 1.1.5__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.
spaceforge/README.md CHANGED
@@ -13,7 +13,7 @@ Spaceforge provides a simple, declarative way to create Spacelift plugins by inh
13
13
  - **SpaceforgePlugin** (`plugin.py`) - Base class with hook methods and utilities
14
14
  - **PluginRunner** (`runner.py`) - Executes hook methods, loads parameters from environment
15
15
  - **PluginGenerator** (`generator.py`) - Analyzes Python plugins and generates `plugin.yaml`
16
- - **CLI Interface** (`__main__.py`) - Click-based CLI with `generate` and `runner` subcommands
16
+ - **CLI Interface** (`__main__.py`) - Click-based CLI with `generate` and `run` subcommands
17
17
  - **Pydantic Dataclasses** (`cls.py`) - Type-safe data structures with validation
18
18
 
19
19
  ### Data Validation
@@ -242,10 +242,10 @@ python -m spaceforge generate my_plugin.py -o my_plugin.yaml
242
242
  export API_KEY="your-key"
243
243
 
244
244
  # Run specific hook
245
- python -m spaceforge runner after_plan
245
+ python -m spaceforge run after_plan
246
246
 
247
247
  # Run with specific plugin file
248
- python -m spaceforge runner --plugin-file my_plugin.py before_apply
248
+ python -m spaceforge run --plugin-file my_plugin.py before_apply
249
249
  ```
250
250
 
251
251
  ### Get Help
@@ -253,7 +253,7 @@ python -m spaceforge runner --plugin-file my_plugin.py before_apply
253
253
  ```bash
254
254
  python -m spaceforge --help
255
255
  python -m spaceforge generate --help
256
- python -m spaceforge runner --help
256
+ python -m spaceforge run --help
257
257
  ```
258
258
 
259
259
  ## Generated YAML Structure
@@ -264,7 +264,7 @@ The framework automatically generates standard Spacelift plugin YAML:
264
264
 
265
265
  1. **Requirements**: If your plugin has dependencies, create a `requirements.txt` file. The generator will automatically add a `before_init` hook to install them.
266
266
 
267
- 2. **Testing**: Use the runner command to test individual hooks during development.
267
+ 2. **Testing**: Use the `run` command to test individual hooks during development.
268
268
 
269
269
  3. **Debugging**: Set `SPACELIFT_DEBUG=true` to enable debug logging.
270
270
 
spaceforge/__main__.py CHANGED
@@ -6,7 +6,7 @@ import click
6
6
 
7
7
  from spaceforge._version import get_version
8
8
  from spaceforge.generator import generate_command
9
- from spaceforge.runner import runner_command
9
+ from spaceforge.runner import run_command
10
10
 
11
11
 
12
12
  @click.group()
@@ -21,7 +21,18 @@ def cli() -> None:
21
21
 
22
22
  # Add subcommands
23
23
  cli.add_command(generate_command)
24
- cli.add_command(runner_command)
24
+ cli.add_command(run_command)
25
+
26
+ # KLUDGE: Add a hidden "runner" alias to the "run" command for backward compatibility.
27
+ # It could be removed in the next major version.
28
+ runner_alias = click.Command(
29
+ callback=run_command.callback,
30
+ help=run_command.help,
31
+ hidden=True,
32
+ name="runner",
33
+ params=run_command.params,
34
+ )
35
+ cli.add_command(runner_alias)
25
36
 
26
37
 
27
38
  def main() -> None:
spaceforge/_version.py CHANGED
@@ -1,60 +1,19 @@
1
1
  """
2
- Dynamic version detection from git tags.
2
+ Version detection using setuptools_scm.
3
3
  """
4
4
 
5
- import subprocess
6
- from typing import Optional
7
-
8
-
9
- def get_git_version() -> Optional[str]:
10
- """
11
- Get version from git tags.
12
-
13
- Returns:
14
- Version string (without 'v' prefix) or None if not available
15
- """
16
- try:
17
- # Try to get the current tag
18
- result = subprocess.run(
19
- ["git", "describe", "--tags", "--exact-match"],
20
- capture_output=True,
21
- text=True,
22
- check=True,
23
- )
24
- tag = result.stdout.strip()
25
- # Remove 'v' prefix if present
26
- return tag[1:] if tag.startswith("v") else tag
27
- except (subprocess.CalledProcessError, FileNotFoundError):
28
- # Fall back to describe with commit info
29
- try:
30
- result = subprocess.run(
31
- ["git", "describe", "--tags", "--always"],
32
- capture_output=True,
33
- text=True,
34
- check=True,
35
- )
36
- tag = result.stdout.strip()
37
- # Remove 'v' prefix if present
38
- return tag[1:] if tag.startswith("v") else tag
39
- except (subprocess.CalledProcessError, FileNotFoundError):
40
- return None
41
-
42
5
 
43
6
  def get_version() -> str:
44
7
  """
45
8
  Get the package version.
46
9
 
47
- Tries git tags first, then setuptools-scm, falls back to default version.
10
+ Uses setuptools_scm generated version file, which is created during build.
11
+ Falls back to a development version if not available.
48
12
 
49
13
  Returns:
50
14
  Version string
51
15
  """
52
- # Try git version first
53
- git_version = get_git_version()
54
- if git_version:
55
- return git_version
56
-
57
- # Try setuptools-scm generated version file
16
+ # Try setuptools-scm generated version file (created during build)
58
17
  try:
59
18
  from ._version_scm import version # type: ignore[import-not-found]
60
19
 
@@ -62,7 +21,7 @@ def get_version() -> str:
62
21
  except ImportError:
63
22
  pass
64
23
 
65
- # Try setuptools-scm directly
24
+ # Try setuptools-scm directly (works in development)
66
25
  try:
67
26
  from setuptools_scm import (
68
27
  get_version as scm_get_version, # type: ignore[import-untyped]
@@ -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.1.3'
32
- __version_tuple__ = version_tuple = (1, 1, 3)
31
+ __version__ = version = '1.1.5'
32
+ __version_tuple__ = version_tuple = (1, 1, 5)
33
33
 
34
34
  __commit_id__ = commit_id = None
spaceforge/runner.py CHANGED
@@ -84,7 +84,7 @@ class PluginRunner:
84
84
  import click
85
85
 
86
86
 
87
- @click.command(name="runner")
87
+ @click.command(name="run")
88
88
  @click.argument("hook_name")
89
89
  @click.option(
90
90
  "--plugin-file",
@@ -92,7 +92,7 @@ import click
92
92
  type=click.Path(exists=True, dir_okay=False, readable=True),
93
93
  help="Path to the plugin Python file (default: plugin.py)",
94
94
  )
95
- def runner_command(hook_name: str, plugin_file: str) -> None:
95
+ def run_command(hook_name: str, plugin_file: str) -> None:
96
96
  """Run a specific hook method from a plugin.
97
97
 
98
98
  HOOK_NAME: Name of the hook method to execute (e.g., after_plan, before_apply)
@@ -21,4 +21,4 @@ fi
21
21
  export PATH="/mnt/workspace/plugins/plugin_binaries:$PATH"
22
22
  {% endif %}
23
23
  cd /mnt/workspace/source/$TF_VAR_spacelift_project_root
24
- spaceforge runner --plugin-file {{plugin_file}} {{phase}}
24
+ spaceforge run --plugin-file {{plugin_file}} {{phase}}
@@ -88,7 +88,6 @@ class PluginExample(SpaceforgePlugin):
88
88
 
89
89
 
90
90
  class TestPluginGenerator:
91
-
92
91
  def setup_method(self) -> None:
93
92
  """Setup test fixtures."""
94
93
  self.temp_dir = tempfile.mkdtemp()
@@ -534,7 +533,7 @@ class NotAPlugin:
534
533
  after_plan_script = mf
535
534
  break
536
535
  assert after_plan_script is not None
537
- assert "spaceforge runner" in after_plan_script.content
536
+ assert "spaceforge run" in after_plan_script.content
538
537
  assert "after_plan" in after_plan_script.content
539
538
 
540
539
  def test_generate_manifest(self) -> None:
spaceforge/test_runner.py CHANGED
@@ -6,7 +6,7 @@ from unittest.mock import Mock, patch
6
6
  import pytest
7
7
 
8
8
  from spaceforge.plugin import SpaceforgePlugin
9
- from spaceforge.runner import PluginRunner, runner_command
9
+ from spaceforge.runner import PluginRunner, run_command
10
10
 
11
11
 
12
12
  class PluginForTesting(SpaceforgePlugin):
@@ -41,7 +41,6 @@ class PluginForTesting(SpaceforgePlugin):
41
41
 
42
42
 
43
43
  class TestPluginRunner:
44
-
45
44
  def setup_method(self) -> None:
46
45
  """Setup test fixtures."""
47
46
  self.temp_dir = tempfile.mkdtemp()
@@ -293,7 +292,7 @@ class ClickTestPlugin(SpaceforgePlugin):
293
292
 
294
293
  shutil.rmtree(self.temp_dir, ignore_errors=True)
295
294
 
296
- def test_runner_command(self) -> None:
295
+ def test_run_command(self) -> None:
297
296
  """Test the Click runner command."""
298
297
  from click.testing import CliRunner
299
298
 
@@ -305,7 +304,7 @@ class ClickTestPlugin(SpaceforgePlugin):
305
304
 
306
305
  # Test the command using Click's test runner
307
306
  result = cli_runner.invoke(
308
- runner_command, ["after_plan", "--plugin-file", self.test_plugin_path]
307
+ run_command, ["after_plan", "--plugin-file", self.test_plugin_path]
309
308
  )
310
309
 
311
310
  assert result.exit_code == 0
@@ -316,7 +315,7 @@ class ClickTestPlugin(SpaceforgePlugin):
316
315
  # Verify run_hook was called with correct hook name
317
316
  mock_runner.run_hook.assert_called_once_with("after_plan")
318
317
 
319
- def test_runner_command_default_plugin_file(self) -> None:
318
+ def test_run_command_default_plugin_file(self) -> None:
320
319
  """Test runner command with default plugin file."""
321
320
  from click.testing import CliRunner
322
321
 
@@ -328,7 +327,7 @@ class ClickTestPlugin(SpaceforgePlugin):
328
327
 
329
328
  # Test with explicit plugin file path
330
329
  result = cli_runner.invoke(
331
- runner_command, ["before_apply", "--plugin-file", self.test_plugin_path]
330
+ run_command, ["before_apply", "--plugin-file", self.test_plugin_path]
332
331
  )
333
332
 
334
333
  assert result.exit_code == 0
@@ -3,7 +3,7 @@
3
3
  import os
4
4
  from unittest.mock import Mock, patch
5
5
 
6
- from spaceforge.runner import runner_command
6
+ from spaceforge.runner import run_command
7
7
 
8
8
 
9
9
  class TestRunnerClickCommand:
@@ -34,7 +34,7 @@ class ClickTestPlugin(SpaceforgePlugin):
34
34
  mock_runner_class.return_value = mock_runner
35
35
 
36
36
  result = cli_runner.invoke(
37
- runner_command, ["after_plan", "--plugin-file", click_plugin_path]
37
+ run_command, ["after_plan", "--plugin-file", click_plugin_path]
38
38
  )
39
39
 
40
40
  # Assert
@@ -60,7 +60,7 @@ class ClickTestPlugin(SpaceforgePlugin):
60
60
  mock_runner_class.return_value = mock_runner
61
61
 
62
62
  result = cli_runner.invoke(
63
- runner_command, ["before_apply", "--plugin-file", custom_plugin_path]
63
+ run_command, ["before_apply", "--plugin-file", custom_plugin_path]
64
64
  )
65
65
 
66
66
  # Assert
@@ -1,9 +1,7 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spaceforge
3
- Version: 1.1.3
3
+ Version: 1.1.5
4
4
  Summary: A Python framework for building Spacelift plugins
5
- Home-page: https://github.com/spacelift-io/plugins
6
- Author: Spacelift
7
5
  Author-email: Spacelift <support@spacelift.io>
8
6
  Maintainer-email: Spacelift <support@spacelift.io>
9
7
  License: MIT
@@ -39,10 +37,7 @@ Requires-Dist: mypy; extra == "dev"
39
37
  Requires-Dist: types-PyYAML; extra == "dev"
40
38
  Requires-Dist: setuptools-scm[toml]>=6.2; extra == "dev"
41
39
  Requires-Dist: autoflake; extra == "dev"
42
- Dynamic: author
43
- Dynamic: home-page
44
40
  Dynamic: license-file
45
- Dynamic: requires-python
46
41
 
47
42
  # Spaceforge - Build Spacelift Plugins in Python
48
43
 
@@ -60,15 +55,15 @@ pip install spaceforge
60
55
 
61
56
  ### 1. Create Your Plugin
62
57
 
63
- Create a Python file (e.g., `my_plugin.py`) and inherit from `SpaceforgePlugin`:
58
+ Create a Python file (e.g., `plugin.py`) and inherit from `SpaceforgePlugin`:
64
59
 
65
60
  ```python
66
- from spaceforge import SpaceforgePlugin, Parameter, Variable, Context, Binary, Policy, Webhook, MountedFile
61
+ from spaceforge import SpaceforgePlugin, Parameter, Variable, Context
67
62
  import os
68
63
 
69
64
  class MyPlugin(SpaceforgePlugin):
70
65
  # Plugin metadata
71
- __plugin_name__ = "my-awesome-plugin"
66
+ __plugin_name__ = "my-plugin"
72
67
  __version__ = "1.0.0"
73
68
  __author__ = "Your Name"
74
69
  __labels__ = ["security", "monitoring"] # Optional labels for categorization
@@ -127,7 +122,7 @@ class MyPlugin(SpaceforgePlugin):
127
122
  Generate the Spacelift plugin YAML manifest:
128
123
 
129
124
  ```bash
130
- spaceforge generate my_plugin.py
125
+ spaceforge generate plugin.py
131
126
  ```
132
127
 
133
128
  This creates `plugin.yaml` that you can upload to Spacelift.
@@ -142,7 +137,7 @@ export API_KEY="your-api-key"
142
137
  export ENVIRONMENT="staging"
143
138
 
144
139
  # Test the after_plan hook
145
- spaceforge runner after_plan
140
+ spaceforge run after_plan
146
141
  ```
147
142
 
148
143
  ## Available Hooks
@@ -527,13 +522,13 @@ export API_KEY="test-key"
527
522
  export TIMEOUT="60"
528
523
 
529
524
  # Test specific hook
530
- spaceforge runner after_plan
525
+ spaceforge run after_plan
531
526
 
532
527
  # Test with specific plugin file
533
- spaceforge runner --plugin-file my_plugin.py before_apply
528
+ spaceforge run --plugin-file my_plugin.py before_apply
534
529
 
535
530
  # Get help
536
- spaceforge runner --help
531
+ spaceforge run --help
537
532
  ```
538
533
 
539
534
  ## Plugin Development Tips
@@ -577,7 +572,7 @@ def after_plan(self):
577
572
  ### 4. Testing and Debugging
578
573
 
579
574
  - Set `SPACELIFT_DEBUG=true` to enable debug logging
580
- - Use the runner command to test hooks during development
575
+ - Use the `run` command to test hooks during development
581
576
  - Test with different parameter combinations
582
577
  - Validate your generated YAML before uploading to Spacelift
583
578
 
@@ -718,7 +713,7 @@ spaceforge generate security_scanner.py
718
713
  # Test locally
719
714
  export API_TOKEN="your-token"
720
715
  export SEVERITY_THRESHOLD="high"
721
- spaceforge runner after_plan
716
+ spaceforge run after_plan
722
717
  ```
723
718
 
724
719
  ## Speeding up plugin execution
@@ -734,8 +729,8 @@ There are a few things you can do to speed up plugin execution.
734
729
 
735
730
  1. **Install spaceforge:** `pip install spaceforge`
736
731
  2. **Create your plugin:** Start with the quick start example
737
- 3. **Test locally:** Use the runner command to test your hooks
738
- 4. **Generate manifest:** Use the generate command to create plugin.yaml
732
+ 3. **Test locally:** Use the `run` command to test your hooks
733
+ 4. **Generate manifest:** Use the `generate` command to create plugin.yaml
739
734
  5. **Upload to Spacelift:** Add your plugin manifest to your Spacelift account
740
735
 
741
736
  For more advanced examples, see the [plugins](plugins/) directory in this repository.
@@ -1,16 +1,16 @@
1
- spaceforge/README.md,sha256=8o1Nuyasb4OxX3E7ZycyducOrR4J19bZcHrLvFeoFNg,7730
1
+ spaceforge/README.md,sha256=gDyCQN0EW4xp8Skvs6J0qHpO9CjVTnRfSnhduAIFQs4,7717
2
2
  spaceforge/__init__.py,sha256=TU-vvm15dK1ucixNW0V42eTT72x3_hmKSyxP4MC1Occ,589
3
- spaceforge/__main__.py,sha256=c3nAw4WBnHXIcfMlRV6Ja7r87pEhSeK-SAqiSYIasIY,643
4
- spaceforge/_version.py,sha256=RP_LfUd4ODnrfwn9nam8wB6bR3lM4VwmoRxK08Tkiiw,2155
5
- spaceforge/_version_scm.py,sha256=87v_vDfphCRXvmiytdhoHtQyIWrsYHjMp8634JpDrR4,704
3
+ spaceforge/__main__.py,sha256=UKbeCuEFgoNlEOX44-kYUAQuUdySdkAKsvbjXEyLeWI,965
4
+ spaceforge/_version.py,sha256=70eCBV_uVCm0U7qrtYRUZM3GJnJRtvZQ_aPFLd8H7CI,1009
5
+ spaceforge/_version_scm.py,sha256=SBXhEAFQbfcjLb_eXnqg0cn0I8-y4wDGA3DkPBmBv2s,704
6
6
  spaceforge/cls.py,sha256=oYW5t5_xs9ZM6Ne_b4trxCPxLHQrqbqgUeibeM8O4PU,6329
7
7
  spaceforge/conftest.py,sha256=U-xCavCsgRAQXqflIIOMeq9pcGbeqRviUNkEXgZol8g,2141
8
8
  spaceforge/generator.py,sha256=hCxtbOKmrGd7HCCz7HMaiK566kIre5MNxcJEx2TVURM,18430
9
9
  spaceforge/plugin.py,sha256=Ytm2B7nnJNH231V4gUFY1pBmwVNTpIg3YviUL_Bnf24,14963
10
- spaceforge/runner.py,sha256=EUZ98gmOiJ766zOSk7YcTTrLCtHfst1xf3iE2Xu7Tao,3172
10
+ spaceforge/runner.py,sha256=NNddgK_OsnQWx2YFcyTpAOWfFLBDUphufBVfXYEzfzM,3166
11
11
  spaceforge/schema.json,sha256=89IROLVlCj8txGMiLt4Bbuo_2muSxKoZCyaXQ2vuA9c,10869
12
12
  spaceforge/test_cls.py,sha256=nXAgbnFnGdFxrtA7vNXiePjNUASuoYW-lEuQGx9WMGs,468
13
- spaceforge/test_generator.py,sha256=Nst3YVu_iZbFopH6ajjxCfqYrZvybteGbwMfZzjBFnI,32615
13
+ spaceforge/test_generator.py,sha256=k2jPEqNEJ9jYiY3xGf59Bo3VxTK6s_jEe3hZ0D8i79U,32611
14
14
  spaceforge/test_generator_binaries.py,sha256=X_7pPLGE45eQt-Kv9_ku__LsyLgOvViHc_BvVpSCMp0,7263
15
15
  spaceforge/test_generator_core.py,sha256=gOqRx0rnME-srGMHun4KidXMN-iaqfKKTyoQ0Tw6b9Q,6253
16
16
  spaceforge/test_generator_hooks.py,sha256=2lJs8dYlFb7QehWcYF0O4qg38s5UudEpzJyBi1XiS3k,2542
@@ -19,15 +19,15 @@ spaceforge/test_plugin.py,sha256=rZ4Uv_0lIR0qb1GFHkiosGO3WHTWhO7epz8INDxV8Q0,130
19
19
  spaceforge/test_plugin_file_operations.py,sha256=B0qvIo5EcfKMiHLhBv-hAnpSonn83ojcmJHXasydojA,3782
20
20
  spaceforge/test_plugin_hooks.py,sha256=ugaVdzH1-heRJSJN0lu8zoqLcLPC3tg_PzUX98qu9Sw,1038
21
21
  spaceforge/test_plugin_inheritance.py,sha256=WHfvU5s-2GtfcI9-1bHXH7bacr77ikq68V3Z3BBQKvQ,3617
22
- spaceforge/test_runner.py,sha256=fDnUf6gEuf1CNMxz6zs3xXvERQsQU3z8qy9KdUc0Wo4,17739
23
- spaceforge/test_runner_cli.py,sha256=Sf5X0O9Wc9EhGB5L8SzvlmO7QmgQZQoClSdNYefa-lQ,2299
22
+ spaceforge/test_runner.py,sha256=PWFiGsBSJ6QXL5OyGA_OoDIILtRaX1NDQnech15Ady0,17723
23
+ spaceforge/test_runner_cli.py,sha256=qkklvRHETCmgKaVxPfUR_IBy7Vne5hKupAOK9igKqLA,2290
24
24
  spaceforge/test_runner_core.py,sha256=eNR9YOwJwv7LsMtNQ4WXXMPIW6RE_A7hUp4bCpzz1Rk,3941
25
25
  spaceforge/test_runner_execution.py,sha256=GJhoECdhIY2M3MWcmTrIYfkJd2P5n86zixO3FY38_CQ,5344
26
26
  spaceforge/templates/binary_install.sh.j2,sha256=I3setUsp6fCUJLkynvfZT4DCqVsoEQ42rhSmK6MJVAY,1517
27
- spaceforge/templates/ensure_spaceforge_and_run.sh.j2,sha256=g5BldIEve0IkZ-mCzTXfB_rFvyWqUJqymRRaaMrpp0s,550
28
- spaceforge-1.1.3.dist-info/licenses/LICENSE,sha256=wyljRrfnWY2ggQKkSCg3Nw2hxwPMmupopaKs9Kpgys8,1065
29
- spaceforge-1.1.3.dist-info/METADATA,sha256=Coa8xC2VcIG_k4mB_uPXMF_uTSzA3tK8MUCJ-AeZ9d0,21164
30
- spaceforge-1.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
31
- spaceforge-1.1.3.dist-info/entry_points.txt,sha256=qawuuKBSNTGg-njnQnhxxFldFvXYAPej6bF_f3iyQ48,56
32
- spaceforge-1.1.3.dist-info/top_level.txt,sha256=eVw-Lw4Th0oHM8Gx1Y8YetyNgbNbMBU00yWs-kwGeSs,11
33
- spaceforge-1.1.3.dist-info/RECORD,,
27
+ spaceforge/templates/ensure_spaceforge_and_run.sh.j2,sha256=8vq9cvFtNLjgcEr8OPblZ6bQRsOsklOnDOzygnw3We4,547
28
+ spaceforge-1.1.5.dist-info/licenses/LICENSE,sha256=wyljRrfnWY2ggQKkSCg3Nw2hxwPMmupopaKs9Kpgys8,1065
29
+ spaceforge-1.1.5.dist-info/METADATA,sha256=6a5k8eotU_WQipZXRVuIxytYHcf9cxuGo5AM34hnnQU,20968
30
+ spaceforge-1.1.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
31
+ spaceforge-1.1.5.dist-info/entry_points.txt,sha256=qawuuKBSNTGg-njnQnhxxFldFvXYAPej6bF_f3iyQ48,56
32
+ spaceforge-1.1.5.dist-info/top_level.txt,sha256=eVw-Lw4Th0oHM8Gx1Y8YetyNgbNbMBU00yWs-kwGeSs,11
33
+ spaceforge-1.1.5.dist-info/RECORD,,