xenfra 0.3.5__tar.gz → 0.3.6__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.
- {xenfra-0.3.5 → xenfra-0.3.6}/PKG-INFO +2 -1
- {xenfra-0.3.5 → xenfra-0.3.6}/pyproject.toml +56 -55
- {xenfra-0.3.5 → xenfra-0.3.6}/src/xenfra/utils/config.py +62 -0
- {xenfra-0.3.5 → xenfra-0.3.6}/README.md +0 -0
- {xenfra-0.3.5 → xenfra-0.3.6}/src/xenfra/__init__.py +0 -0
- {xenfra-0.3.5 → xenfra-0.3.6}/src/xenfra/commands/__init__.py +0 -0
- {xenfra-0.3.5 → xenfra-0.3.6}/src/xenfra/commands/auth.py +0 -0
- {xenfra-0.3.5 → xenfra-0.3.6}/src/xenfra/commands/auth_device.py +0 -0
- {xenfra-0.3.5 → xenfra-0.3.6}/src/xenfra/commands/deployments.py +0 -0
- {xenfra-0.3.5 → xenfra-0.3.6}/src/xenfra/commands/intelligence.py +0 -0
- {xenfra-0.3.5 → xenfra-0.3.6}/src/xenfra/commands/projects.py +0 -0
- {xenfra-0.3.5 → xenfra-0.3.6}/src/xenfra/commands/security_cmd.py +0 -0
- {xenfra-0.3.5 → xenfra-0.3.6}/src/xenfra/main.py +0 -0
- {xenfra-0.3.5 → xenfra-0.3.6}/src/xenfra/utils/__init__.py +0 -0
- {xenfra-0.3.5 → xenfra-0.3.6}/src/xenfra/utils/auth.py +0 -0
- {xenfra-0.3.5 → xenfra-0.3.6}/src/xenfra/utils/codebase.py +0 -0
- {xenfra-0.3.5 → xenfra-0.3.6}/src/xenfra/utils/errors.py +0 -0
- {xenfra-0.3.5 → xenfra-0.3.6}/src/xenfra/utils/security.py +0 -0
- {xenfra-0.3.5 → xenfra-0.3.6}/src/xenfra/utils/validation.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: xenfra
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.6
|
|
4
4
|
Summary: A 'Zen Mode' infrastructure engine for Python developers.
|
|
5
5
|
Author: xenfra-cloud
|
|
6
6
|
Author-email: xenfra-cloud <xenfracloud@gmail.com>
|
|
@@ -24,6 +24,7 @@ Requires-Dist: keyring>=25.7.0
|
|
|
24
24
|
Requires-Dist: keyrings-alt>=5.0.2
|
|
25
25
|
Requires-Dist: tenacity>=8.2.3
|
|
26
26
|
Requires-Dist: cryptography>=43.0.0
|
|
27
|
+
Requires-Dist: toml>=0.10.2
|
|
27
28
|
Requires-Dist: pytest>=8.0.0 ; extra == 'test'
|
|
28
29
|
Requires-Dist: pytest-mock>=3.12.0 ; extra == 'test'
|
|
29
30
|
Requires-Python: >=3.13
|
|
@@ -1,55 +1,56 @@
|
|
|
1
|
-
[project]
|
|
2
|
-
name = "xenfra"
|
|
3
|
-
version = "0.3.
|
|
4
|
-
description = "A 'Zen Mode' infrastructure engine for Python developers."
|
|
5
|
-
readme = "README.md"
|
|
6
|
-
authors = [
|
|
7
|
-
{ name = "xenfra-cloud", email = "xenfracloud@gmail.com" }
|
|
8
|
-
]
|
|
9
|
-
|
|
10
|
-
classifiers = [
|
|
11
|
-
"Programming Language :: Python :: 3",
|
|
12
|
-
"License :: OSI Approved :: MIT License",
|
|
13
|
-
"Operating System :: OS Independent",
|
|
14
|
-
"Development Status :: 3 - Alpha",
|
|
15
|
-
"Intended Audience :: Developers",
|
|
16
|
-
"Topic :: Software Development :: Build Tools",
|
|
17
|
-
"Topic :: System :: Systems Administration",
|
|
18
|
-
]
|
|
19
|
-
|
|
20
|
-
dependencies = [
|
|
21
|
-
"click>=8.1.7",
|
|
22
|
-
"rich>=14.2.0",
|
|
23
|
-
"sqlmodel>=0.0.16",
|
|
24
|
-
"python-digitalocean>=1.17.0",
|
|
25
|
-
"python-dotenv>=1.2.1",
|
|
26
|
-
"pyyaml>=6.0.1",
|
|
27
|
-
"fabric>=3.2.2",
|
|
28
|
-
"xenfra-sdk",
|
|
29
|
-
"httpx>=0.27.0",
|
|
30
|
-
"keyring>=25.7.0",
|
|
31
|
-
"keyrings.alt>=5.0.2",
|
|
32
|
-
"tenacity>=8.2.3",
|
|
33
|
-
"cryptography>=43.0.0",
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
"pytest
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
1
|
+
[project]
|
|
2
|
+
name = "xenfra"
|
|
3
|
+
version = "0.3.6"
|
|
4
|
+
description = "A 'Zen Mode' infrastructure engine for Python developers."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
authors = [
|
|
7
|
+
{ name = "xenfra-cloud", email = "xenfracloud@gmail.com" }
|
|
8
|
+
]
|
|
9
|
+
|
|
10
|
+
classifiers = [
|
|
11
|
+
"Programming Language :: Python :: 3",
|
|
12
|
+
"License :: OSI Approved :: MIT License",
|
|
13
|
+
"Operating System :: OS Independent",
|
|
14
|
+
"Development Status :: 3 - Alpha",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"Topic :: Software Development :: Build Tools",
|
|
17
|
+
"Topic :: System :: Systems Administration",
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
dependencies = [
|
|
21
|
+
"click>=8.1.7",
|
|
22
|
+
"rich>=14.2.0",
|
|
23
|
+
"sqlmodel>=0.0.16",
|
|
24
|
+
"python-digitalocean>=1.17.0",
|
|
25
|
+
"python-dotenv>=1.2.1",
|
|
26
|
+
"pyyaml>=6.0.1",
|
|
27
|
+
"fabric>=3.2.2",
|
|
28
|
+
"xenfra-sdk",
|
|
29
|
+
"httpx>=0.27.0",
|
|
30
|
+
"keyring>=25.7.0",
|
|
31
|
+
"keyrings.alt>=5.0.2",
|
|
32
|
+
"tenacity>=8.2.3", # For retry logic
|
|
33
|
+
"cryptography>=43.0.0", # For encrypted file-based token storage
|
|
34
|
+
"toml>=0.10.2",
|
|
35
|
+
]
|
|
36
|
+
requires-python = ">=3.13"
|
|
37
|
+
|
|
38
|
+
[tool.uv.sources]
|
|
39
|
+
xenfra-sdk = { workspace = true }
|
|
40
|
+
|
|
41
|
+
[project.urls]
|
|
42
|
+
Homepage = "https://github.com/xenfra-cloud/xenfra"
|
|
43
|
+
Issues = "https://github.com/xenfra-cloud/xenfra/issues"
|
|
44
|
+
|
|
45
|
+
[project.optional-dependencies]
|
|
46
|
+
test = [
|
|
47
|
+
"pytest>=8.0.0",
|
|
48
|
+
"pytest-mock>=3.12.0",
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
[project.scripts]
|
|
52
|
+
xenfra = "xenfra.main:main"
|
|
53
|
+
|
|
54
|
+
[build-system]
|
|
55
|
+
requires = ["uv_build>=0.9.18,<0.10.0"]
|
|
56
|
+
build-backend = "uv_build"
|
|
@@ -280,6 +280,68 @@ def apply_patch(patch: dict, target_file: str = None, create_backup_file: bool =
|
|
|
280
280
|
# Replace entire file
|
|
281
281
|
with open(file_to_patch, "w") as f:
|
|
282
282
|
f.write(str(value))
|
|
283
|
+
|
|
284
|
+
# For TOML files (pyproject.toml)
|
|
285
|
+
elif file_to_patch.endswith(".toml"):
|
|
286
|
+
import toml
|
|
287
|
+
|
|
288
|
+
with open(file_to_patch, "r") as f:
|
|
289
|
+
config_data = toml.load(f)
|
|
290
|
+
|
|
291
|
+
operation = patch.get("operation")
|
|
292
|
+
path = patch.get("path", "").strip("/")
|
|
293
|
+
value = patch.get("value")
|
|
294
|
+
|
|
295
|
+
if operation == "add":
|
|
296
|
+
# Special case for pyproject.toml dependencies
|
|
297
|
+
is_pyproject = os.path.basename(file_to_patch) == "pyproject.toml"
|
|
298
|
+
if is_pyproject and (not path or path == "project/dependencies"):
|
|
299
|
+
# Ensure project and dependencies exist
|
|
300
|
+
if "project" not in config_data:
|
|
301
|
+
config_data["project"] = {}
|
|
302
|
+
if "dependencies" not in config_data["project"]:
|
|
303
|
+
config_data["project"]["dependencies"] = []
|
|
304
|
+
|
|
305
|
+
# Add value if not already present
|
|
306
|
+
if value not in config_data["project"]["dependencies"]:
|
|
307
|
+
config_data["project"]["dependencies"].append(value)
|
|
308
|
+
elif path:
|
|
309
|
+
path_parts = path.split("/")
|
|
310
|
+
current = config_data
|
|
311
|
+
for part in path_parts[:-1]:
|
|
312
|
+
if part not in current:
|
|
313
|
+
current[part] = {}
|
|
314
|
+
current = current[part]
|
|
315
|
+
|
|
316
|
+
# If target is a list (like dependencies), append
|
|
317
|
+
target_key = path_parts[-1]
|
|
318
|
+
if target_key in current and isinstance(current[target_key], list):
|
|
319
|
+
if value not in current[target_key]:
|
|
320
|
+
current[target_key].append(value)
|
|
321
|
+
else:
|
|
322
|
+
current[target_key] = value
|
|
323
|
+
else:
|
|
324
|
+
# Root level add
|
|
325
|
+
if isinstance(value, dict):
|
|
326
|
+
config_data.update(value)
|
|
327
|
+
else:
|
|
328
|
+
# Ignore root-level non-dict adds for structured files
|
|
329
|
+
# to prevent overwriting the entire config with a string
|
|
330
|
+
pass
|
|
331
|
+
|
|
332
|
+
elif operation == "replace":
|
|
333
|
+
if path:
|
|
334
|
+
path_parts = path.split("/")
|
|
335
|
+
current = config_data
|
|
336
|
+
for part in path_parts[:-1]:
|
|
337
|
+
current = current[part]
|
|
338
|
+
current[path_parts[-1]] = value
|
|
339
|
+
else:
|
|
340
|
+
config_data = value
|
|
341
|
+
|
|
342
|
+
# Write back
|
|
343
|
+
with open(file_to_patch, "w") as f:
|
|
344
|
+
toml.dump(config_data, f)
|
|
283
345
|
else:
|
|
284
346
|
# Design decision: Only support auto-patching for common dependency files
|
|
285
347
|
# Other file types should be manually edited to avoid data loss
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|