jvcli 2.0.12__tar.gz → 2.0.14__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.
Files changed (82) hide show
  1. {jvcli-2.0.12/jvcli.egg-info → jvcli-2.0.14}/PKG-INFO +1 -1
  2. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/__init__.py +1 -1
  3. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/commands/startproject.py +16 -2
  4. jvcli-2.0.14/jvcli/templates/2.0.0/project/gitignore.example +53 -0
  5. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/2.0.0/project/sh/importagent.sh +1 -1
  6. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/utils.py +43 -48
  7. {jvcli-2.0.12 → jvcli-2.0.14/jvcli.egg-info}/PKG-INFO +1 -1
  8. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli.egg-info/SOURCES.txt +1 -0
  9. {jvcli-2.0.12 → jvcli-2.0.14}/tests/test_startproject.py +13 -4
  10. {jvcli-2.0.12 → jvcli-2.0.14}/tests/test_utils.py +51 -20
  11. {jvcli-2.0.12 → jvcli-2.0.14}/LICENSE +0 -0
  12. {jvcli-2.0.12 → jvcli-2.0.14}/MANIFEST.in +0 -0
  13. {jvcli-2.0.12 → jvcli-2.0.14}/README.md +0 -0
  14. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/api.py +0 -0
  15. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/auth.py +0 -0
  16. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/cli.py +0 -0
  17. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/client/__init__.py +0 -0
  18. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/client/app.py +0 -0
  19. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/client/lib/__init__.py +0 -0
  20. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/client/lib/page.py +0 -0
  21. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/client/lib/utils.py +0 -0
  22. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/client/lib/widgets.py +0 -0
  23. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/client/pages/__init__.py +0 -0
  24. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/client/pages/analytics_page.py +0 -0
  25. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/client/pages/chat_page.py +0 -0
  26. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/client/pages/dashboard_page.py +0 -0
  27. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/client/pages/graph_page.py +0 -0
  28. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/commands/__init__.py +0 -0
  29. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/commands/auth.py +0 -0
  30. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/commands/client.py +0 -0
  31. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/commands/create.py +0 -0
  32. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/commands/download.py +0 -0
  33. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/commands/info.py +0 -0
  34. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/commands/publish.py +0 -0
  35. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/commands/studio.py +0 -0
  36. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/commands/update.py +0 -0
  37. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/studio/assets/index-DDV79SDu.js +0 -0
  38. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/studio/assets/index-DdMMONxd.css +0 -0
  39. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/studio/index.html +0 -0
  40. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/studio/jac_logo.png +0 -0
  41. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/studio/tauri.svg +0 -0
  42. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/studio/vite.svg +0 -0
  43. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/studio-auth/assets/index-Bh6lyeXA.js +0 -0
  44. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/studio-auth/assets/index-DdMMONxd.css +0 -0
  45. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/studio-auth/index.html +0 -0
  46. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/studio-auth/jac_logo.png +0 -0
  47. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/studio-auth/tauri.svg +0 -0
  48. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/studio-auth/vite.svg +0 -0
  49. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/2.0.0/action_info.yaml +0 -0
  50. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/2.0.0/agent_descriptor.yaml +0 -0
  51. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/2.0.0/agent_info.yaml +0 -0
  52. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/2.0.0/agent_knowledge.yaml +0 -0
  53. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/2.0.0/agent_memory.yaml +0 -0
  54. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/2.0.0/project/README.md +0 -0
  55. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/2.0.0/project/actions/README.md +0 -0
  56. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/2.0.0/project/daf/README.md +0 -0
  57. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/2.0.0/project/env.example +0 -0
  58. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/2.0.0/project/globals.jac +0 -0
  59. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/2.0.0/project/main.jac +0 -0
  60. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/2.0.0/project/sh/exportenv.sh +0 -0
  61. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/2.0.0/project/sh/initagents.sh +0 -0
  62. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/2.0.0/project/sh/inituser.sh +0 -0
  63. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/2.0.0/project/sh/serve.sh +0 -0
  64. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/2.0.0/project/sh/startclient.sh +0 -0
  65. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/2.0.0/project/tests/README.md +0 -0
  66. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/CHANGELOG.md +0 -0
  67. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli/templates/README.md +0 -0
  68. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli.egg-info/dependency_links.txt +0 -0
  69. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli.egg-info/entry_points.txt +0 -0
  70. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli.egg-info/requires.txt +0 -0
  71. {jvcli-2.0.12 → jvcli-2.0.14}/jvcli.egg-info/top_level.txt +0 -0
  72. {jvcli-2.0.12 → jvcli-2.0.14}/setup.cfg +0 -0
  73. {jvcli-2.0.12 → jvcli-2.0.14}/setup.py +0 -0
  74. {jvcli-2.0.12 → jvcli-2.0.14}/tests/test_api.py +0 -0
  75. {jvcli-2.0.12 → jvcli-2.0.14}/tests/test_auth.py +0 -0
  76. {jvcli-2.0.12 → jvcli-2.0.14}/tests/test_cli.py +0 -0
  77. {jvcli-2.0.12 → jvcli-2.0.14}/tests/test_create.py +0 -0
  78. {jvcli-2.0.12 → jvcli-2.0.14}/tests/test_download.py +0 -0
  79. {jvcli-2.0.12 → jvcli-2.0.14}/tests/test_info.py +0 -0
  80. {jvcli-2.0.12 → jvcli-2.0.14}/tests/test_publish.py +0 -0
  81. {jvcli-2.0.12 → jvcli-2.0.14}/tests/test_studio.py +0 -0
  82. {jvcli-2.0.12 → jvcli-2.0.14}/tests/test_update.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jvcli
3
- Version: 2.0.12
3
+ Version: 2.0.14
4
4
  Summary: CLI tool for Jivas Package Repository
5
5
  Home-page: https://github.com/TrueSelph/jvcli
6
6
  Author: TrueSelph Inc.
@@ -4,5 +4,5 @@ jvcli package initialization.
4
4
  This package provides the CLI tool for Jivas Package Repository.
5
5
  """
6
6
 
7
- __version__ = "2.0.12"
7
+ __version__ = "2.0.14"
8
8
  __supported__jivas__versions__ = ["2.0.0"]
@@ -23,6 +23,7 @@ def startproject(project_name: str, version: str) -> None:
23
23
  Usage:
24
24
  jvcli startproject <project_name> [--version <jivas_version>]
25
25
  """
26
+
26
27
  template_path = os.path.join(TEMPLATES_DIR, version, "project")
27
28
 
28
29
  if not os.path.exists(template_path):
@@ -61,9 +62,22 @@ def startproject(project_name: str, version: str) -> None:
61
62
  with open(template_file_path, "r") as template_file:
62
63
  contents = template_file.read()
63
64
 
64
- # Write `.env` instead of `env.example`
65
+ if file_name == "gitignore.example":
66
+ # Write `.gitignore`
67
+ target_file_path_gitignore = os.path.join(target_dir, ".gitignore")
68
+ with open(target_file_path_gitignore, "w") as gitignore_file:
69
+ gitignore_file.write(contents)
70
+
65
71
  if file_name == "env.example":
66
- target_file_path = os.path.join(target_dir, ".env")
72
+ # Write `.env`
73
+ target_file_path_env = os.path.join(target_dir, ".env")
74
+ with open(target_file_path_env, "w") as env_file:
75
+ env_file.write(contents)
76
+
77
+ # Write `env.example`
78
+ target_file_path_example = os.path.join(target_dir, "env.example")
79
+ with open(target_file_path_example, "w") as example_file:
80
+ example_file.write(contents)
67
81
 
68
82
  with open(target_file_path, "w") as project_file:
69
83
  project_file.write(contents)
@@ -0,0 +1,53 @@
1
+ # Python #
2
+ *.pyc
3
+ __pycache__
4
+ venv
5
+ .pytest_cache
6
+ __jac_gen__
7
+
8
+ # Distribution / packaging
9
+ .Python
10
+ play/
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib64/
18
+ parts/
19
+ sdist/
20
+ var/
21
+ wheels/
22
+ share/python-wheels/
23
+ *.egg-info/
24
+ .installed.cfg
25
+ *.egg
26
+ MANIFEST
27
+ test_source/
28
+
29
+ # Others #
30
+ .coverage
31
+ .session
32
+ *.session.db
33
+ mydatabase/
34
+ actions/jivas/
35
+ .DS_Store
36
+ .vscode
37
+ build
38
+ *Zone.Identifier
39
+ .DS_Store
40
+ parser.out
41
+ codegen_output*
42
+ .qodo
43
+ .files
44
+ *.rdb
45
+ node_modules
46
+ out.dot
47
+ out.txt
48
+ .jvdata
49
+ .env
50
+
51
+ # Mypy files #
52
+ .mypy_cache*
53
+ .jac_mypy_cache*
@@ -25,7 +25,7 @@ done
25
25
  # Check if JIVAS_TOKEN is set
26
26
  if [ -n "$JIVAS_TOKEN" ]; then
27
27
 
28
- echo -e "\n\nImporting demo agent...\n"
28
+ echo -e "\n\nImporting agent...\n"
29
29
  # Import the agent
30
30
  AGENT_ID=$(curl --silent --show-error --no-progress-meter \
31
31
  --request POST \
@@ -6,8 +6,8 @@ import tarfile
6
6
 
7
7
  import click
8
8
  import yaml
9
- from packaging.specifiers import SpecifierSet
10
- from packaging.version import parse as parse_version
9
+ from packaging.specifiers import InvalidSpecifier, SpecifierSet
10
+ from packaging.version import InvalidVersion, Version
11
11
 
12
12
  from jvcli import __supported__jivas__versions__
13
13
  from jvcli.api import RegistryAPI
@@ -92,61 +92,56 @@ def validate_package_name(name: str) -> None:
92
92
 
93
93
  def is_version_compatible(version: str, specifiers: str) -> bool:
94
94
  """
95
- Compares the provided version to a given set of specifications/modifiers or exact version match.
95
+ Determines if the provided version satisfies the given specifiers or exact version match.
96
96
 
97
97
  Args:
98
- - version (str): The version to be compared. E.g., "2.1.0".
99
- - specifiers (str): The version specifier set or exact version. E.g., "2.1.0" or ">=0.2,<0.3" or "0.0.1" or "^2.0.0"
98
+ - version (str): The version to be checked. E.g., "2.1.0".
99
+ - specifiers (str): The version specifier set or exact version. E.g., "2.1.0", ">=0.2,<0.3", or "^2.0.0".
100
100
 
101
101
  Returns:
102
102
  - bool: True if the version satisfies the specifier set or exact match, False otherwise.
103
103
  """
104
104
  try:
105
- # Parse the version to check
106
- version = parse_version(version)
107
-
108
- # Check if specifiers is a simple exact version match
109
- try:
110
- exact_version = parse_version(specifiers)
111
- return version == exact_version
112
- except Exception:
113
- # If parsing fails, treat it as a specifier set
114
- pass
115
-
116
- # Handle "~" shorthand by translating it to a compatible range
105
+ # Handle edge cases for empty strings or None inputs
106
+ if not version or not specifiers:
107
+ return False
108
+
109
+ # Handle exact version equality when no special characters present
110
+ if all(c not in specifiers for c in "<>!=~^*,"):
111
+ return Version(version) == Version(specifiers)
112
+
113
+ # Handle tilde (~) syntax, as in npm semver, if used
117
114
  if specifiers.startswith("~"):
118
- base_version = specifiers[1:]
119
- parsed_base = parse_version(base_version)
120
- major = parsed_base.major
121
- minor = parsed_base.minor
122
- # Assuming the next release constraint is on minor bump
123
- upper_bound = f"<{major}.{minor + 1}"
124
- specifiers = f">={base_version},{upper_bound}"
125
-
126
- # Handle "^" shorthand to translate to a compatible range
127
- if specifiers.startswith("^"):
128
- base_version = specifiers[1:]
129
- parsed_base = parse_version(base_version)
130
- major = parsed_base.major
131
- minor = parsed_base.minor
132
- patch = parsed_base.micro
115
+ base_version = Version(specifiers[1:])
116
+ if base_version.release is None or len(base_version.release) < 2:
117
+ raise InvalidSpecifier(f"Invalid tilde specifier: '{specifiers}'")
118
+ next_minor = base_version.minor + 1
119
+ specifiers = f">={base_version},<{base_version.major}.{next_minor}.0"
120
+
121
+ # Explicitly handle caret (^) syntax (npm semver style)
122
+ elif specifiers.startswith("^"):
123
+ base_version = Version(specifiers[1:])
124
+ major, minor, patch = (
125
+ base_version.major,
126
+ base_version.minor,
127
+ base_version.micro,
128
+ )
129
+
133
130
  if major > 0:
134
- upper_bound = f"<{major + 1}.0.0"
135
- elif minor > 0:
136
- upper_bound = f"<0.{minor + 1}.0"
137
- else:
138
- upper_bound = f"<0.0.{patch + 1}"
139
- specifiers = f">={base_version},{upper_bound}"
140
-
141
- # Create a SpecifierSet with the given specifiers
142
- spec_set = SpecifierSet(specifiers)
143
-
144
- # Check if the version matches the specifier set
145
- return version in spec_set
146
-
147
- except Exception as e:
148
- # Handle exceptions if the inputs are malformed or invalid
149
- click.secho(f"Error comparing versions: {e}", fg="red")
131
+ specifiers = f">={base_version},<{major + 1}.0.0"
132
+ elif major == 0 and minor > 0:
133
+ specifiers = f">={base_version},<0.{minor + 1}.0"
134
+ else: # major == 0 and minor == 0
135
+ specifiers = f">={base_version},<0.0.{patch + 1}"
136
+
137
+ # Finally check using the SpecifierSet
138
+ specifier_set = SpecifierSet(specifiers)
139
+ parsed_version = Version(version)
140
+
141
+ return parsed_version in specifier_set
142
+
143
+ except (InvalidVersion, InvalidSpecifier, TypeError) as e:
144
+ print(f"Version parsing error: {e}")
150
145
  return False
151
146
 
152
147
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: jvcli
3
- Version: 2.0.12
3
+ Version: 2.0.14
4
4
  Summary: CLI tool for Jivas Package Repository
5
5
  Home-page: https://github.com/TrueSelph/jvcli
6
6
  Author: TrueSelph Inc.
@@ -55,6 +55,7 @@ jvcli/templates/2.0.0/agent_knowledge.yaml
55
55
  jvcli/templates/2.0.0/agent_memory.yaml
56
56
  jvcli/templates/2.0.0/project/README.md
57
57
  jvcli/templates/2.0.0/project/env.example
58
+ jvcli/templates/2.0.0/project/gitignore.example
58
59
  jvcli/templates/2.0.0/project/globals.jac
59
60
  jvcli/templates/2.0.0/project/main.jac
60
61
  jvcli/templates/2.0.0/project/actions/README.md
@@ -17,7 +17,7 @@ class TestStartProjectCommand:
17
17
 
18
18
  # Mock file system operations
19
19
  mock_makedirs = mocker.patch("os.makedirs")
20
- mocker.patch("os.path.exists", return_value=True)
20
+ mocker.patch("os.path.exists", side_effect=lambda path: path != "test_project")
21
21
 
22
22
  # Mock open with support for both text and binary modes
23
23
  mock_file = mocker.mock_open(read_data=b"template content")
@@ -45,6 +45,9 @@ class TestStartProjectCommand:
45
45
  "main.jac",
46
46
  "globals.jac",
47
47
  ".env",
48
+ "env.example",
49
+ ".gitignore",
50
+ "gitignore.example",
48
51
  "README.md",
49
52
  "actions/README.md",
50
53
  "daf/README.md",
@@ -58,10 +61,16 @@ class TestStartProjectCommand:
58
61
  ]
59
62
 
60
63
  mock_calls = mock_open.mock_calls
61
- written_files = [
62
- call.args[0] for call in mock_calls if "test_project" in str(call)
64
+ written_files = {
65
+ os.path.normpath(call.args[0])
66
+ for call in mock_calls
67
+ if "test_project" in str(call)
68
+ }
69
+ normalized_expected_files = [
70
+ os.path.normpath(os.path.join("test_project", file))
71
+ for file in expected_files
63
72
  ]
64
- assert len(written_files) == len(expected_files)
73
+ assert set(written_files) == set(normalized_expected_files)
65
74
 
66
75
  # Verify success message
67
76
  mock_click.assert_called_with(
@@ -67,12 +67,6 @@ class TestUtils:
67
67
 
68
68
  validate_package_name("test-ns/package-name")
69
69
 
70
- def test_is_version_compatible_with_exact_match(self) -> None:
71
- """is_version_compatible correctly handles exact version matches and version ranges."""
72
- assert is_version_compatible("1.0.0", "1.0.0") is True
73
- assert is_version_compatible("2.1.0", ">=2.0.0,<3.0.0") is True
74
- assert is_version_compatible("1.0.0", "^1.0.0") is True
75
-
76
70
  def test_validate_snake_case_rejects_invalid_strings(self) -> None:
77
71
  """validate_snake_case rejects strings with uppercase letters or special characters."""
78
72
  ctx = click.Context(click.Command("test"))
@@ -130,6 +124,57 @@ class TestUtils:
130
124
  assert is_version_compatible("1.0.0", "invalid") is False
131
125
  assert is_version_compatible("1.0", ">=invalid") is False
132
126
 
127
+ def test_is_version_compatible_with_exact_match(self) -> None:
128
+ """is_version_compatible correctly handles exact version matches and version ranges."""
129
+ assert is_version_compatible("1.0.0", "1.0.0") is True
130
+ assert is_version_compatible("2.1.0", ">=2.0.0,<3.0.0") is True
131
+ assert is_version_compatible("1.0.0", "^1.0.0") is True
132
+
133
+ def test_is_version_compatible_with_incompatible_versions(self) -> None:
134
+ """is_version_compatible returns False for incompatible versions."""
135
+ assert is_version_compatible("1.0.0", "2.0.0") is False
136
+ assert is_version_compatible("1.0.0", ">=2.0.0,<3.0.0") is False
137
+ assert is_version_compatible("1.0.0", "^2.0.0") is False
138
+
139
+ def test_is_version_compatible_with_invalid_version(self) -> None:
140
+ """is_version_compatible handles invalid version inputs gracefully."""
141
+ assert is_version_compatible("invalid_version", "1.0.0") is False
142
+ assert is_version_compatible("1.0.0", "invalid_specifier") is False
143
+ assert is_version_compatible("invalid_version", "invalid_specifier") is False
144
+
145
+ def test_is_version_compatible_with_shorthand_tilde(self) -> None:
146
+ """is_version_compatible correctly handles shorthand '~' specifier."""
147
+ assert is_version_compatible("1.2.3", "~1.2.0") is True
148
+ assert is_version_compatible("1.3.0", "~1.2.0") is False
149
+ assert is_version_compatible("1.2.0", "~1.2.0") is True
150
+
151
+ def test_is_version_compatible_with_shorthand_caret(self) -> None:
152
+ """is_version_compatible correctly handles shorthand '^' specifier."""
153
+ assert is_version_compatible("1.2.3", "^1.2.0") is True
154
+ assert is_version_compatible("2.0.0", "^1.2.0") is False
155
+ assert is_version_compatible("0.2.3", "^0.2.0") is True
156
+ assert is_version_compatible("0.3.0", "^0.2.0") is False
157
+
158
+ def test_is_version_compatible_with_edge_cases(self) -> None:
159
+ """is_version_compatible handles edge cases like empty strings and None."""
160
+ assert is_version_compatible("", "1.0.0") is False
161
+ assert is_version_compatible("1.0.0", "") is False
162
+ assert is_version_compatible("", "") is False
163
+ assert is_version_compatible(None, "1.0.0") is False # type: ignore
164
+ assert is_version_compatible("1.0.0", None) is False # type: ignore
165
+ assert is_version_compatible(None, None) is False # type: ignore
166
+
167
+ def test_is_version_compatible_with_pre_release_versions(self) -> None:
168
+ """is_version_compatible correctly handles pre-release versions."""
169
+ assert is_version_compatible("1.0.0-alpha", ">=1.0.0-alpha,<2.0.0") is True
170
+ assert is_version_compatible("1.0.0-alpha", ">=1.0.0,<2.0.0") is False
171
+ assert is_version_compatible("1.0.0-beta", "^1.0.0-alpha") is True
172
+
173
+ def test_is_version_compatible_with_exact_pre_release(self) -> None:
174
+ """is_version_compatible correctly matches exact pre-release versions."""
175
+ assert is_version_compatible("1.0.0-alpha", "1.0.0-alpha") is True
176
+ assert is_version_compatible("1.0.0-alpha", "1.0.0-beta") is False
177
+
133
178
  def test_compress_package_to_tgz(self) -> None:
134
179
  """Test that compress_package_to_tgz correctly creates a .tgz archive, excluding unwanted folders."""
135
180
 
@@ -167,20 +212,6 @@ class TestUtils:
167
212
  assert "__jac_gen__" not in archive_files
168
213
  assert "__pycache__" not in archive_files
169
214
 
170
- def test_is_version_compatible_with_tilde_and_caret_specifiers(self) -> None:
171
- """is_version_compatible processes tilde (~) and caret (^) version specifiers."""
172
- # Test cases for tilde (~) specifier
173
- assert is_version_compatible("2.1.0", "~2.1.0") is True
174
- assert is_version_compatible("2.1.5", "~2.1.0") is True
175
- assert is_version_compatible("2.2.0", "~2.1.0") is False
176
-
177
- # Test cases for caret (^) specifier
178
- assert is_version_compatible("2.1.0", "^2.0.0") is True
179
- assert is_version_compatible("3.0.0", "^2.0.0") is False
180
- assert is_version_compatible("0.2.5", "^0.2.0") is True
181
- assert is_version_compatible("0.3.0", "^0.2.0") is False
182
- assert is_version_compatible("0.0.6", "^0.0.4") is False
183
-
184
215
  def test_compress_package_to_tgz_preserves_structure_and_permissions(
185
216
  self, mocker: MockerFixture
186
217
  ) -> None:
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