spaceforge 1.1.7__py3-none-any.whl → 1.2.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.
- spaceforge/_version_scm.py +2 -2
- spaceforge/cls.py +31 -3
- spaceforge/conftest.py +1 -0
- spaceforge/schema.json +21 -2
- spaceforge/test_cls.py +85 -0
- spaceforge/test_generator.py +6 -1
- spaceforge/test_generator_parameters.py +2 -0
- {spaceforge-1.1.7.dist-info → spaceforge-1.2.0.dist-info}/METADATA +2 -1
- {spaceforge-1.1.7.dist-info → spaceforge-1.2.0.dist-info}/RECORD +13 -13
- {spaceforge-1.1.7.dist-info → spaceforge-1.2.0.dist-info}/WHEEL +0 -0
- {spaceforge-1.1.7.dist-info → spaceforge-1.2.0.dist-info}/entry_points.txt +0 -0
- {spaceforge-1.1.7.dist-info → spaceforge-1.2.0.dist-info}/licenses/LICENSE +0 -0
- {spaceforge-1.1.7.dist-info → spaceforge-1.2.0.dist-info}/top_level.txt +0 -0
spaceforge/_version_scm.py
CHANGED
|
@@ -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.
|
|
32
|
-
__version_tuple__ = version_tuple = (1,
|
|
31
|
+
__version__ = version = '1.2.0'
|
|
32
|
+
__version_tuple__ = version_tuple = (1, 2, 0)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
spaceforge/cls.py
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import uuid
|
|
2
|
-
from typing import Dict, List, Literal, Optional
|
|
2
|
+
from typing import Dict, List, Literal, Optional, Union
|
|
3
3
|
|
|
4
4
|
from pydantic import Field
|
|
5
5
|
from pydantic.dataclasses import dataclass as pydantic_dataclass
|
|
@@ -12,6 +12,12 @@ BinaryType = Literal[
|
|
|
12
12
|
"arm64",
|
|
13
13
|
]
|
|
14
14
|
|
|
15
|
+
ParameterType = Literal[
|
|
16
|
+
"string",
|
|
17
|
+
"number",
|
|
18
|
+
"boolean",
|
|
19
|
+
]
|
|
20
|
+
|
|
15
21
|
|
|
16
22
|
@pydantic_dataclass
|
|
17
23
|
class Binary:
|
|
@@ -35,17 +41,19 @@ class Parameter:
|
|
|
35
41
|
Attributes:
|
|
36
42
|
name (str): The name of the parameter.
|
|
37
43
|
description (str): A description of the parameter.
|
|
44
|
+
type (ParameterType): The type of the parameter.
|
|
38
45
|
sensitive (bool): Whether the parameter contains sensitive information.
|
|
39
46
|
required (bool): Whether the parameter is required.
|
|
40
|
-
default (Optional[str]): The default value of the parameter, if any. (required if sensitive is False)
|
|
47
|
+
default (Optional[Union[str, int, float, bool]]): The default value of the parameter, if any. (required if sensitive is False)
|
|
41
48
|
id (str): Unique identifier for the parameter.
|
|
42
49
|
"""
|
|
43
50
|
|
|
44
51
|
name: str
|
|
45
52
|
description: str
|
|
53
|
+
type: ParameterType
|
|
46
54
|
sensitive: bool = False
|
|
47
55
|
required: bool = False
|
|
48
|
-
default: Optional[str] = None
|
|
56
|
+
default: Optional[Union[str, int, float, bool]] = None
|
|
49
57
|
id: str = Field(default_factory=lambda: str(uuid.uuid4()))
|
|
50
58
|
|
|
51
59
|
def __post_init__(self) -> None:
|
|
@@ -54,6 +62,26 @@ class Parameter:
|
|
|
54
62
|
f"Default value for parameter {self.name} should be set if parameter is optional."
|
|
55
63
|
)
|
|
56
64
|
|
|
65
|
+
# Validate that default value Python type matches the declared type
|
|
66
|
+
if self.default is not None:
|
|
67
|
+
if self.type == "string":
|
|
68
|
+
if not isinstance(self.default, str):
|
|
69
|
+
raise ValueError(
|
|
70
|
+
f"Parameter {self.name} has type 'string' but default value has Python type {type(self.default).__name__}. Expected str."
|
|
71
|
+
)
|
|
72
|
+
elif self.type == "number":
|
|
73
|
+
if not isinstance(self.default, (int, float)) or isinstance(
|
|
74
|
+
self.default, bool
|
|
75
|
+
):
|
|
76
|
+
raise ValueError(
|
|
77
|
+
f"Parameter {self.name} has type 'number' but default value has Python type {type(self.default).__name__}. Expected int or float."
|
|
78
|
+
)
|
|
79
|
+
elif self.type == "boolean":
|
|
80
|
+
if not isinstance(self.default, bool):
|
|
81
|
+
raise ValueError(
|
|
82
|
+
f"Parameter {self.name} has type 'boolean' but default value has Python type {type(self.default).__name__}. Expected bool."
|
|
83
|
+
)
|
|
84
|
+
|
|
57
85
|
|
|
58
86
|
@pydantic_dataclass
|
|
59
87
|
class Variable:
|
spaceforge/conftest.py
CHANGED
spaceforge/schema.json
CHANGED
|
@@ -123,7 +123,7 @@
|
|
|
123
123
|
"type": "object"
|
|
124
124
|
},
|
|
125
125
|
"Parameter": {
|
|
126
|
-
"description": "A class to represent a parameter with a name and value.\n\nAttributes:\n name (str): The name of the parameter.\n description (str): A description of the parameter.\n sensitive (bool): Whether the parameter contains sensitive information.\n required (bool): Whether the parameter is required.\n default (Optional[str]): The default value of the parameter, if any. (required if sensitive is False)\n id (str): Unique identifier for the parameter.",
|
|
126
|
+
"description": "A class to represent a parameter with a name and value.\n\nAttributes:\n name (str): The name of the parameter.\n description (str): A description of the parameter.\n type (ParameterType): The type of the parameter.\n sensitive (bool): Whether the parameter contains sensitive information.\n required (bool): Whether the parameter is required.\n default (Optional[Union[str, int, float, bool]]): The default value of the parameter, if any. (required if sensitive is False)\n id (str): Unique identifier for the parameter.",
|
|
127
127
|
"properties": {
|
|
128
128
|
"name": {
|
|
129
129
|
"title": "Name",
|
|
@@ -133,6 +133,15 @@
|
|
|
133
133
|
"title": "Description",
|
|
134
134
|
"type": "string"
|
|
135
135
|
},
|
|
136
|
+
"type": {
|
|
137
|
+
"enum": [
|
|
138
|
+
"string",
|
|
139
|
+
"number",
|
|
140
|
+
"boolean"
|
|
141
|
+
],
|
|
142
|
+
"title": "Type",
|
|
143
|
+
"type": "string"
|
|
144
|
+
},
|
|
136
145
|
"sensitive": {
|
|
137
146
|
"default": false,
|
|
138
147
|
"title": "Sensitive",
|
|
@@ -148,6 +157,15 @@
|
|
|
148
157
|
{
|
|
149
158
|
"type": "string"
|
|
150
159
|
},
|
|
160
|
+
{
|
|
161
|
+
"type": "integer"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"type": "number"
|
|
165
|
+
},
|
|
166
|
+
{
|
|
167
|
+
"type": "boolean"
|
|
168
|
+
},
|
|
151
169
|
{
|
|
152
170
|
"type": "null"
|
|
153
171
|
}
|
|
@@ -162,7 +180,8 @@
|
|
|
162
180
|
},
|
|
163
181
|
"required": [
|
|
164
182
|
"name",
|
|
165
|
-
"description"
|
|
183
|
+
"description",
|
|
184
|
+
"type"
|
|
166
185
|
],
|
|
167
186
|
"title": "Parameter",
|
|
168
187
|
"type": "object"
|
spaceforge/test_cls.py
CHANGED
|
@@ -8,6 +8,7 @@ def test_ensure_optional_parameters_require_default_values() -> None:
|
|
|
8
8
|
Parameter(
|
|
9
9
|
name="optional_default",
|
|
10
10
|
description="default value",
|
|
11
|
+
type="string",
|
|
11
12
|
required=False,
|
|
12
13
|
)
|
|
13
14
|
|
|
@@ -15,3 +16,87 @@ def test_ensure_optional_parameters_require_default_values() -> None:
|
|
|
15
16
|
def test_ensure_variables_have_either_value_or_value_from_parameter() -> None:
|
|
16
17
|
with pytest.raises(ValueError):
|
|
17
18
|
Variable(key="test_var", sensitive=False)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def test_parameter_type_validation_string() -> None:
|
|
22
|
+
"""Test that string type accepts any default value."""
|
|
23
|
+
# Should not raise
|
|
24
|
+
Parameter(
|
|
25
|
+
name="string_param",
|
|
26
|
+
description="A string parameter",
|
|
27
|
+
type="string",
|
|
28
|
+
required=False,
|
|
29
|
+
default="any value works",
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_parameter_type_validation_number_valid() -> None:
|
|
34
|
+
"""Test that number type accepts valid numeric strings."""
|
|
35
|
+
# Integer
|
|
36
|
+
Parameter(
|
|
37
|
+
name="int_param",
|
|
38
|
+
description="An integer parameter",
|
|
39
|
+
type="number",
|
|
40
|
+
required=False,
|
|
41
|
+
default=42,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
# Float
|
|
45
|
+
Parameter(
|
|
46
|
+
name="float_param",
|
|
47
|
+
description="A float parameter",
|
|
48
|
+
type="number",
|
|
49
|
+
required=False,
|
|
50
|
+
default=3.14,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
# Negative number
|
|
54
|
+
Parameter(
|
|
55
|
+
name="negative_param",
|
|
56
|
+
description="A negative parameter",
|
|
57
|
+
type="number",
|
|
58
|
+
required=False,
|
|
59
|
+
default=-100,
|
|
60
|
+
)
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_parameter_type_validation_number_invalid() -> None:
|
|
64
|
+
"""Test that number type rejects non-numeric strings."""
|
|
65
|
+
with pytest.raises(
|
|
66
|
+
ValueError,
|
|
67
|
+
match="Parameter invalid_number has type 'number' but default value has Python type str.",
|
|
68
|
+
):
|
|
69
|
+
Parameter(
|
|
70
|
+
name="invalid_number",
|
|
71
|
+
description="Invalid number parameter",
|
|
72
|
+
type="number",
|
|
73
|
+
required=False,
|
|
74
|
+
default="not a number",
|
|
75
|
+
)
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def test_parameter_type_validation_boolean_invalid() -> None:
|
|
79
|
+
"""Test that boolean type rejects values other than 'true'/'false'."""
|
|
80
|
+
with pytest.raises(
|
|
81
|
+
ValueError,
|
|
82
|
+
match="Parameter invalid_bool has type 'boolean' but default value has Python type str.",
|
|
83
|
+
):
|
|
84
|
+
Parameter(
|
|
85
|
+
name="invalid_bool",
|
|
86
|
+
description="Invalid boolean parameter",
|
|
87
|
+
type="boolean",
|
|
88
|
+
required=False,
|
|
89
|
+
default="1",
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
with pytest.raises(
|
|
93
|
+
ValueError,
|
|
94
|
+
match="Parameter invalid_bool2 has type 'boolean' but default value has Python type str.",
|
|
95
|
+
):
|
|
96
|
+
Parameter(
|
|
97
|
+
name="invalid_bool2",
|
|
98
|
+
description="Invalid boolean parameter",
|
|
99
|
+
type="boolean",
|
|
100
|
+
required=False,
|
|
101
|
+
default="yes",
|
|
102
|
+
)
|
spaceforge/test_generator.py
CHANGED
|
@@ -30,12 +30,14 @@ class PluginExample(SpaceforgePlugin):
|
|
|
30
30
|
Parameter(
|
|
31
31
|
name="api_key",
|
|
32
32
|
description="API key for authentication",
|
|
33
|
+
type="string",
|
|
33
34
|
required=True,
|
|
34
35
|
sensitive=True,
|
|
35
36
|
),
|
|
36
37
|
Parameter(
|
|
37
38
|
name="endpoint",
|
|
38
39
|
description="API endpoint URL",
|
|
40
|
+
type="string",
|
|
39
41
|
required=False,
|
|
40
42
|
default="https://api.example.com",
|
|
41
43
|
),
|
|
@@ -106,7 +108,7 @@ class TestPlugin(SpaceforgePlugin):
|
|
|
106
108
|
__author__ = "Test"
|
|
107
109
|
|
|
108
110
|
__parameters__ = [
|
|
109
|
-
Parameter(name="test_param", description="Test parameter", required=False, default="default_value")
|
|
111
|
+
Parameter(name="test_param", description="Test parameter", type="string", required=False, default="default_value")
|
|
110
112
|
]
|
|
111
113
|
|
|
112
114
|
def after_plan(self) -> None:
|
|
@@ -619,6 +621,7 @@ class FullTestPlugin(SpaceforgePlugin):
|
|
|
619
621
|
Parameter(
|
|
620
622
|
name="test_param",
|
|
621
623
|
description="Test parameter",
|
|
624
|
+
type="string",
|
|
622
625
|
required=False,
|
|
623
626
|
default="test_value"
|
|
624
627
|
)
|
|
@@ -811,12 +814,14 @@ class TestPluginGeneratorEdgeCases:
|
|
|
811
814
|
Parameter(
|
|
812
815
|
name="api key",
|
|
813
816
|
description="API key for authentication",
|
|
817
|
+
type="string",
|
|
814
818
|
required=True,
|
|
815
819
|
sensitive=True,
|
|
816
820
|
),
|
|
817
821
|
Parameter(
|
|
818
822
|
name="endpoint",
|
|
819
823
|
description="API endpoint URL",
|
|
824
|
+
type="string",
|
|
820
825
|
required=False,
|
|
821
826
|
default="https://api.example.com",
|
|
822
827
|
),
|
|
@@ -17,12 +17,14 @@ class TestPluginGeneratorParameters:
|
|
|
17
17
|
Parameter(
|
|
18
18
|
name="api_key",
|
|
19
19
|
description="API key for authentication",
|
|
20
|
+
type="string",
|
|
20
21
|
required=True,
|
|
21
22
|
sensitive=True,
|
|
22
23
|
),
|
|
23
24
|
Parameter(
|
|
24
25
|
name="endpoint",
|
|
25
26
|
description="API endpoint URL",
|
|
27
|
+
type="string",
|
|
26
28
|
required=False,
|
|
27
29
|
default="https://api.example.com",
|
|
28
30
|
),
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: spaceforge
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2.0
|
|
4
4
|
Summary: A Python framework for building Spacelift plugins
|
|
5
5
|
Author-email: Spacelift <support@spacelift.io>
|
|
6
6
|
Maintainer-email: Spacelift <support@spacelift.io>
|
|
@@ -34,6 +34,7 @@ Requires-Dist: pytest-cov; extra == "dev"
|
|
|
34
34
|
Requires-Dist: black; extra == "dev"
|
|
35
35
|
Requires-Dist: isort; extra == "dev"
|
|
36
36
|
Requires-Dist: mypy; extra == "dev"
|
|
37
|
+
Requires-Dist: pylint; extra == "dev"
|
|
37
38
|
Requires-Dist: types-PyYAML; extra == "dev"
|
|
38
39
|
Requires-Dist: setuptools-scm[toml]>=6.2; extra == "dev"
|
|
39
40
|
Requires-Dist: autoflake; extra == "dev"
|
|
@@ -2,19 +2,19 @@ spaceforge/README.md,sha256=gDyCQN0EW4xp8Skvs6J0qHpO9CjVTnRfSnhduAIFQs4,7717
|
|
|
2
2
|
spaceforge/__init__.py,sha256=TU-vvm15dK1ucixNW0V42eTT72x3_hmKSyxP4MC1Occ,589
|
|
3
3
|
spaceforge/__main__.py,sha256=UKbeCuEFgoNlEOX44-kYUAQuUdySdkAKsvbjXEyLeWI,965
|
|
4
4
|
spaceforge/_version.py,sha256=70eCBV_uVCm0U7qrtYRUZM3GJnJRtvZQ_aPFLd8H7CI,1009
|
|
5
|
-
spaceforge/_version_scm.py,sha256
|
|
6
|
-
spaceforge/cls.py,sha256=
|
|
7
|
-
spaceforge/conftest.py,sha256=
|
|
5
|
+
spaceforge/_version_scm.py,sha256=-uLONazCO1SzFfcY-K6A1keL--LIVfTYccGX6ciADac,704
|
|
6
|
+
spaceforge/cls.py,sha256=qe_-pQ9G7p6Hxv8FxNw9OwhPeMQk3vIS_SezxSoca2M,7644
|
|
7
|
+
spaceforge/conftest.py,sha256=J2BIqOu0VYpUlxnJf07cW6l2NHSzVvkXw18jKTTR3hE,2168
|
|
8
8
|
spaceforge/generator.py,sha256=qOC9YeP9QmwFZQoe0BbvJb8RHtv3BVupYxvu2ceQMkE,18768
|
|
9
9
|
spaceforge/plugin.py,sha256=Ytm2B7nnJNH231V4gUFY1pBmwVNTpIg3YviUL_Bnf24,14963
|
|
10
10
|
spaceforge/runner.py,sha256=NNddgK_OsnQWx2YFcyTpAOWfFLBDUphufBVfXYEzfzM,3166
|
|
11
|
-
spaceforge/schema.json,sha256=
|
|
12
|
-
spaceforge/test_cls.py,sha256=
|
|
13
|
-
spaceforge/test_generator.py,sha256=
|
|
11
|
+
spaceforge/schema.json,sha256=nZf438rSKThw64Au7-tmoVw8EYsb7OGhzLfInO31ddA,11328
|
|
12
|
+
spaceforge/test_cls.py,sha256=uDnEmgF7bHzu3FjMk4-boEuJqk_B5AWKMPiKgl83Onc,2777
|
|
13
|
+
spaceforge/test_generator.py,sha256=Gm3IA-8ykwCbj1JMKe03mj5DMZSNFEtCz8ue0xKjUUs,32791
|
|
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
|
|
17
|
-
spaceforge/test_generator_parameters.py,sha256=
|
|
17
|
+
spaceforge/test_generator_parameters.py,sha256=aZRNwYcogJqp2NiYrqEkuxDi2Z6Z2S1SVoejUvsHHCE,1948
|
|
18
18
|
spaceforge/test_plugin.py,sha256=rZ4Uv_0lIR0qb1GFHkiosGO3WHTWhO7epz8INDxV8Q0,13018
|
|
19
19
|
spaceforge/test_plugin_file_operations.py,sha256=B0qvIo5EcfKMiHLhBv-hAnpSonn83ojcmJHXasydojA,3782
|
|
20
20
|
spaceforge/test_plugin_hooks.py,sha256=ugaVdzH1-heRJSJN0lu8zoqLcLPC3tg_PzUX98qu9Sw,1038
|
|
@@ -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=xyq-ol6z8M4RJ107GAs5cdvudVV45JmhwExHovfCHMI,1544
|
|
27
27
|
spaceforge/templates/ensure_spaceforge_and_run.sh.j2,sha256=OKrpZI-M1VU5rCdu7XMbBto7R-HV9lAImc3x3112vhY,580
|
|
28
|
-
spaceforge-1.
|
|
29
|
-
spaceforge-1.
|
|
30
|
-
spaceforge-1.
|
|
31
|
-
spaceforge-1.
|
|
32
|
-
spaceforge-1.
|
|
33
|
-
spaceforge-1.
|
|
28
|
+
spaceforge-1.2.0.dist-info/licenses/LICENSE,sha256=qtl16T_VToz1-IpjGKSLCHsy_zmCFg2H5SkvJi85C4c,1065
|
|
29
|
+
spaceforge-1.2.0.dist-info/METADATA,sha256=xVeIjTzuT5KXGjN2wajp8_er_4B8BTIhWYe_lw9FWQs,2345
|
|
30
|
+
spaceforge-1.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
31
|
+
spaceforge-1.2.0.dist-info/entry_points.txt,sha256=qawuuKBSNTGg-njnQnhxxFldFvXYAPej6bF_f3iyQ48,56
|
|
32
|
+
spaceforge-1.2.0.dist-info/top_level.txt,sha256=eVw-Lw4Th0oHM8Gx1Y8YetyNgbNbMBU00yWs-kwGeSs,11
|
|
33
|
+
spaceforge-1.2.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|