jvcli 2.0.25__tar.gz → 2.0.27__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.
- {jvcli-2.0.25/jvcli.egg-info → jvcli-2.0.27}/PKG-INFO +1 -1
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/__init__.py +1 -1
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/utils.py +35 -11
- {jvcli-2.0.25 → jvcli-2.0.27/jvcli.egg-info}/PKG-INFO +1 -1
- {jvcli-2.0.25 → jvcli-2.0.27}/tests/test_utils.py +4 -2
- {jvcli-2.0.25 → jvcli-2.0.27}/LICENSE +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/MANIFEST.in +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/README.md +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/api.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/auth.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/cli.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/client/__init__.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/client/app.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/client/lib/__init__.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/client/lib/page.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/client/lib/utils.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/client/lib/widgets.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/client/pages/__init__.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/client/pages/action_dashboard_page.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/client/pages/analytics_page.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/client/pages/chat_page.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/client/pages/graph_page.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/commands/__init__.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/commands/auth.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/commands/clean.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/commands/client.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/commands/create.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/commands/download.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/commands/info.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/commands/publish.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/commands/server.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/commands/startproject.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/commands/studio.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/commands/update.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/studio/assets/index-DDV79SDu.js +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/studio/assets/index-DdMMONxd.css +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/studio/index.html +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/studio/jac_logo.png +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/studio/tauri.svg +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/studio/vite.svg +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/studio-auth/assets/index-Bh6lyeXA.js +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/studio-auth/assets/index-DdMMONxd.css +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/studio-auth/index.html +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/studio-auth/jac_logo.png +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/studio-auth/tauri.svg +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/studio-auth/vite.svg +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/templates/2.0.0/action_info.yaml +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/templates/2.0.0/agent_descriptor.yaml +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/templates/2.0.0/agent_info.yaml +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/templates/2.0.0/agent_knowledge.yaml +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/templates/2.0.0/agent_memory.yaml +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/templates/2.0.0/project/README.md +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/templates/2.0.0/project/actions/README.md +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/templates/2.0.0/project/daf/README.md +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/templates/2.0.0/project/env.example +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/templates/2.0.0/project/gitignore.example +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/templates/2.0.0/project/globals.jac +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/templates/2.0.0/project/main.jac +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/templates/2.0.0/project/tests/README.md +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/templates/CHANGELOG.md +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli/templates/README.md +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli.egg-info/SOURCES.txt +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli.egg-info/dependency_links.txt +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli.egg-info/entry_points.txt +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli.egg-info/requires.txt +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/jvcli.egg-info/top_level.txt +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/setup.cfg +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/setup.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/tests/test_api.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/tests/test_auth.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/tests/test_clean.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/tests/test_cli.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/tests/test_create.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/tests/test_download.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/tests/test_info.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/tests/test_publish.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/tests/test_render_basic.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/tests/test_server.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/tests/test_startproject.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/tests/test_studio.py +0 -0
- {jvcli-2.0.25 → jvcli-2.0.27}/tests/test_update.py +0 -0
@@ -96,27 +96,24 @@ def is_version_compatible(
|
|
96
96
|
version: str, specifiers: str, allow_prerelease: bool = True
|
97
97
|
) -> bool:
|
98
98
|
"""
|
99
|
-
Determines if the provided version satisfies the given specifiers
|
100
|
-
|
101
|
-
|
102
|
-
- Converts comma-separated specifiers to space-separated (Node-style).
|
99
|
+
Determines if the provided version satisfies the given specifiers, with strict
|
100
|
+
prerelease checks when `allow_prerelease` is True.
|
103
101
|
"""
|
104
102
|
if not version or not specifiers:
|
105
103
|
return False
|
106
104
|
|
107
|
-
#
|
105
|
+
# Normalize specifiers to Node.js format
|
108
106
|
specifiers = re.sub(r"\s*,\s*", " ", specifiers.strip())
|
109
107
|
|
110
108
|
try:
|
111
|
-
#
|
112
|
-
|
109
|
+
# Check using nodesemver
|
110
|
+
result = nodesemver.satisfies(
|
113
111
|
version, specifiers, include_prerelease=allow_prerelease
|
114
112
|
)
|
115
113
|
except ImportError:
|
116
114
|
try:
|
117
|
-
#
|
118
|
-
|
119
|
-
return semver.satisfies(
|
115
|
+
# Fallback to python-semver
|
116
|
+
result = semver.satisfies(
|
120
117
|
version, specifiers, allow_prerelease=allow_prerelease
|
121
118
|
)
|
122
119
|
except Exception:
|
@@ -124,6 +121,31 @@ def is_version_compatible(
|
|
124
121
|
except Exception:
|
125
122
|
return False
|
126
123
|
|
124
|
+
# Additional scrutiny for prerelease logic
|
125
|
+
if allow_prerelease and result:
|
126
|
+
try:
|
127
|
+
version_info = semver.VersionInfo.parse(version)
|
128
|
+
# Extract base version from specifier (e.g., "^2.0.0-alpha.44" → "2.0.0-alpha.44")
|
129
|
+
base_version_match = re.search(
|
130
|
+
r"[\^~>=<]*(?P<version>\d+\.\d+\.\d+(-[a-zA-Z0-9\.]+)?)", specifiers
|
131
|
+
)
|
132
|
+
if base_version_match:
|
133
|
+
base_version_str = base_version_match.group("version")
|
134
|
+
base_version_info = semver.VersionInfo.parse(base_version_str)
|
135
|
+
|
136
|
+
# Case 1: Specifier is a prerelease
|
137
|
+
if base_version_info.prerelease:
|
138
|
+
# Reject stable versions or prereleases lower than the base prerelease
|
139
|
+
if (not version_info.prerelease) or (
|
140
|
+
version_info < base_version_info
|
141
|
+
):
|
142
|
+
return False
|
143
|
+
|
144
|
+
except (ValueError, TypeError):
|
145
|
+
pass # Fallback to original result if parsing fails
|
146
|
+
|
147
|
+
return result
|
148
|
+
|
127
149
|
|
128
150
|
def validate_dependencies(dependencies: dict, token: Optional[str] = None) -> None:
|
129
151
|
"""Ensure all dependencies exist in the registry."""
|
@@ -135,7 +157,9 @@ def validate_dependencies(dependencies: dict, token: Optional[str] = None) -> No
|
|
135
157
|
# Check if the version is in list of supported versions
|
136
158
|
def supported(spec: str) -> bool:
|
137
159
|
return any(
|
138
|
-
is_version_compatible(
|
160
|
+
is_version_compatible(
|
161
|
+
version, spec, False
|
162
|
+
) # ignore prerelase specs for this validation
|
139
163
|
for version in __supported__jivas__versions__
|
140
164
|
)
|
141
165
|
|
@@ -344,9 +344,11 @@ class TestUtilsFullCoverage:
|
|
344
344
|
mock_api = mocker.patch(
|
345
345
|
"jvcli.api.RegistryAPI.download_package", return_value={"file": 1}
|
346
346
|
)
|
347
|
-
dependencies = {
|
347
|
+
dependencies = {
|
348
|
+
"actions": {"a": "^1.0.0", "b": ">=2.0.0", "c": "^2.0.0-alpha.44"}
|
349
|
+
}
|
348
350
|
validate_dependencies(dependencies)
|
349
|
-
assert mock_api.call_count ==
|
351
|
+
assert mock_api.call_count == 3
|
350
352
|
|
351
353
|
def test_validate_dependencies_actions_missing(self, mocker: MockerFixture) -> None:
|
352
354
|
"""Test validate_dependencies for missing action."""
|
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
|
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
|
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
|
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
|
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
|