reyk-cli 0.0.1__tar.gz → 0.0.2__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.
- reyk_cli-0.0.2/.gitignore +36 -0
- reyk_cli-0.0.2/PKG-INFO +8 -0
- {reyk_cli-0.0.1 → reyk_cli-0.0.2}/pyproject.toml +8 -3
- {reyk_cli-0.0.1 → reyk_cli-0.0.2}/src/reyk_cli/cli.py +1 -0
- {reyk_cli-0.0.1 → reyk_cli-0.0.2}/src/reyk_cli/configuration_reader.py +2 -0
- {reyk_cli-0.0.1 → reyk_cli-0.0.2}/src/reyk_cli/uv_vendorizer.py +9 -1
- reyk_cli-0.0.2/src/reyk_cli/version.py +1 -0
- reyk_cli-0.0.2/tests/__init__.py +0 -0
- reyk_cli-0.0.2/tests/conftest.py +21 -0
- reyk_cli-0.0.2/tests/example_project.py +67 -0
- reyk_cli-0.0.2/tests/test_cli.py +137 -0
- reyk_cli-0.0.1/PKG-INFO +0 -9
- {reyk_cli-0.0.1 → reyk_cli-0.0.2}/README.md +0 -0
- {reyk_cli-0.0.1 → reyk_cli-0.0.2}/src/reyk_cli/__init__.py +0 -0
- {reyk_cli-0.0.1 → reyk_cli-0.0.2}/src/reyk_cli/command_executor.py +0 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Byte-compiled
|
|
2
|
+
__pycache__/
|
|
3
|
+
|
|
4
|
+
# Distribution / packaging
|
|
5
|
+
build/
|
|
6
|
+
dist/
|
|
7
|
+
|
|
8
|
+
# Unit test / coverage reports
|
|
9
|
+
htmlcov/
|
|
10
|
+
.tox/
|
|
11
|
+
.nox/
|
|
12
|
+
.coverage
|
|
13
|
+
.coverage.*
|
|
14
|
+
.cache
|
|
15
|
+
nosetests.xml
|
|
16
|
+
coverage.xml
|
|
17
|
+
*.cover
|
|
18
|
+
*.py,cover
|
|
19
|
+
.hypothesis/
|
|
20
|
+
.pytest_cache/
|
|
21
|
+
coverage/
|
|
22
|
+
coverage.lcov
|
|
23
|
+
|
|
24
|
+
# Environments
|
|
25
|
+
.venv/
|
|
26
|
+
|
|
27
|
+
# PyPI configuration file
|
|
28
|
+
.pypirc
|
|
29
|
+
|
|
30
|
+
# Tests
|
|
31
|
+
tests/blackbox/locked_files_pending_deletion/
|
|
32
|
+
tests/blackbox/specific_libraries/test_libs
|
|
33
|
+
tests/blackbox/specific_libraries/vendor.lock
|
|
34
|
+
|
|
35
|
+
# Docs
|
|
36
|
+
.vercel
|
reyk_cli-0.0.2/PKG-INFO
ADDED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "reyk-cli"
|
|
3
|
-
|
|
3
|
+
dynamic = ["version"]
|
|
4
4
|
description = "Manage isolated environment dependencies."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.9"
|
|
7
7
|
dependencies = ["typer>=0.20.0", "tomli>=2.4.0; python_version < '3.11'"]
|
|
8
|
+
license = 'MIT'
|
|
9
|
+
license-files = ['LICENSE']
|
|
8
10
|
|
|
9
11
|
[dependency-groups]
|
|
10
12
|
dev = ["pytest>=8.4.2", "tomli-w>=1.2.0"]
|
|
11
13
|
|
|
12
14
|
[build-system]
|
|
13
|
-
requires = ["
|
|
14
|
-
build-backend = "
|
|
15
|
+
requires = ["hatchling"]
|
|
16
|
+
build-backend = "hatchling.build"
|
|
17
|
+
|
|
18
|
+
[tool.hatch.version]
|
|
19
|
+
path = "src/reyk_cli/version.py"
|
|
15
20
|
|
|
16
21
|
[project.scripts]
|
|
17
22
|
reyk-cli = "reyk_cli.cli:app"
|
|
@@ -20,6 +20,7 @@ DEFAULT_VENDOR_GROUPS = {DEFAULT_VENDOR_GROUP}
|
|
|
20
20
|
class ReykConfiguration:
|
|
21
21
|
libraries_path: str
|
|
22
22
|
vendor_groups: set[str]
|
|
23
|
+
vendor_exclusions: set[str]
|
|
23
24
|
|
|
24
25
|
|
|
25
26
|
def read_reyk_configuration(toml_path: Path) -> ReykConfiguration:
|
|
@@ -30,4 +31,5 @@ def read_reyk_configuration(toml_path: Path) -> ReykConfiguration:
|
|
|
30
31
|
)
|
|
31
32
|
configuration["libraries_path"] = configuration.pop("libraries-path", DEFAULT_LIBRARIES_TARGET_PATH)
|
|
32
33
|
configuration["vendor_groups"] = set(configuration.pop("vendor-groups", DEFAULT_VENDOR_GROUPS))
|
|
34
|
+
configuration["vendor_exclusions"] = set(configuration.pop("vendor-exclusions", set()))
|
|
33
35
|
return ReykConfiguration(**configuration)
|
|
@@ -10,9 +10,16 @@ LOCK_FILE_NAME = "vendor.lock"
|
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class UVBasedVendorizer:
|
|
13
|
-
def __init__(
|
|
13
|
+
def __init__(
|
|
14
|
+
self,
|
|
15
|
+
project_root: Path,
|
|
16
|
+
vendor_groups: set[str],
|
|
17
|
+
vendor_exclusions: set[str],
|
|
18
|
+
libraries_target_path: Path,
|
|
19
|
+
) -> None:
|
|
14
20
|
self._project_root = project_root
|
|
15
21
|
self._vendor_groups = vendor_groups
|
|
22
|
+
self._vendor_exclusions = vendor_exclusions
|
|
16
23
|
self._libraries_target_path = libraries_target_path
|
|
17
24
|
|
|
18
25
|
def add_new_requirement_to_pyproject(self, vendor_group: str, command_args: Sequence[str]) -> None:
|
|
@@ -44,6 +51,7 @@ class UVBasedVendorizer:
|
|
|
44
51
|
"uv",
|
|
45
52
|
"export",
|
|
46
53
|
*itertools.chain.from_iterable([("--only-group", group) for group in self._vendor_groups]),
|
|
54
|
+
*itertools.chain.from_iterable([("--no-emit-package", package) for package in self._vendor_exclusions]),
|
|
47
55
|
"--no-header",
|
|
48
56
|
"--quiet",
|
|
49
57
|
"--no-emit-project",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VERSION = "0.0.2"
|
|
File without changes
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
from collections.abc import Iterable
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
import os
|
|
4
|
+
import pytest
|
|
5
|
+
from typer.testing import CliRunner
|
|
6
|
+
from tests.example_project import ExampleProject
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.fixture(scope="session")
|
|
10
|
+
def runner() -> CliRunner:
|
|
11
|
+
return CliRunner()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
@pytest.fixture
|
|
15
|
+
def example_project(request: pytest.FixtureRequest, tmpdir: Path) -> Iterable[ExampleProject]:
|
|
16
|
+
example_project = ExampleProject(Path(tmpdir), getattr(request, "param", None))
|
|
17
|
+
example_project.write_pyproject_toml()
|
|
18
|
+
previous_cwd = Path.cwd()
|
|
19
|
+
os.chdir(tmpdir)
|
|
20
|
+
yield example_project
|
|
21
|
+
os.chdir(previous_cwd)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Any, Optional
|
|
3
|
+
|
|
4
|
+
import tomli_w
|
|
5
|
+
from reyk_cli.configuration_reader import (
|
|
6
|
+
DEFAULT_LIBRARIES_TARGET_PATH,
|
|
7
|
+
DEFAULT_VENDOR_GROUPS,
|
|
8
|
+
ReykConfiguration,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
PYPROJECT_TOML_NAME = "pyproject.toml"
|
|
12
|
+
DIST_INFO_SUBSTRING = "dist-info"
|
|
13
|
+
IGNORED_DIRECTORIES_IN_LIBS = {"bin"} # Directories which aren't packages
|
|
14
|
+
|
|
15
|
+
PYPROJECT_EXAMPLE: dict[str, Any] = {
|
|
16
|
+
"project": {
|
|
17
|
+
"name": "project-example",
|
|
18
|
+
"version": "0.0.1",
|
|
19
|
+
"description": "Example Pyproject",
|
|
20
|
+
"readme": "README.md",
|
|
21
|
+
"requires-python": ">=3.8",
|
|
22
|
+
"dependencies": [],
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ExampleProject:
|
|
28
|
+
def __init__(self, project_path: Path, configuration: Optional[ReykConfiguration]) -> None:
|
|
29
|
+
self._project_path = project_path
|
|
30
|
+
self._configuration = (
|
|
31
|
+
ReykConfiguration(DEFAULT_LIBRARIES_TARGET_PATH, DEFAULT_VENDOR_GROUPS, set())
|
|
32
|
+
if configuration is None
|
|
33
|
+
else configuration
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
def write_pyproject_toml(self) -> None:
|
|
37
|
+
pyproject = PYPROJECT_EXAMPLE.copy()
|
|
38
|
+
# Only add values if any are not the default:
|
|
39
|
+
if (
|
|
40
|
+
self._configuration.libraries_path != DEFAULT_LIBRARIES_TARGET_PATH
|
|
41
|
+
or self._configuration.vendor_groups != DEFAULT_VENDOR_GROUPS
|
|
42
|
+
or len(self._configuration.vendor_exclusions) > 0
|
|
43
|
+
):
|
|
44
|
+
pyproject["tool"] = {
|
|
45
|
+
"reyk": {
|
|
46
|
+
"libraries-path": self._configuration.libraries_path,
|
|
47
|
+
"vendor-groups": list(self._configuration.vendor_groups),
|
|
48
|
+
"vendor-exclusions": list(self._configuration.vendor_exclusions),
|
|
49
|
+
},
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
with (self._project_path / PYPROJECT_TOML_NAME).open("wb") as fp:
|
|
53
|
+
tomli_w.dump(pyproject, fp)
|
|
54
|
+
|
|
55
|
+
def get_existing_libraries(self) -> set[str]:
|
|
56
|
+
return {
|
|
57
|
+
library_path.name
|
|
58
|
+
for library_path in (self._project_path / self._configuration.libraries_path).iterdir()
|
|
59
|
+
if (
|
|
60
|
+
library_path.is_dir()
|
|
61
|
+
and library_path.name not in IGNORED_DIRECTORIES_IN_LIBS
|
|
62
|
+
and DIST_INFO_SUBSTRING not in library_path.name
|
|
63
|
+
)
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
def has_libs_directory(self) -> bool:
|
|
67
|
+
return (self._project_path / self._configuration.libraries_path).exists()
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
from reyk_cli.cli import app
|
|
3
|
+
from reyk_cli.configuration_reader import (
|
|
4
|
+
DEFAULT_LIBRARIES_TARGET_PATH,
|
|
5
|
+
DEFAULT_VENDOR_GROUP,
|
|
6
|
+
DEFAULT_VENDOR_GROUPS,
|
|
7
|
+
ReykConfiguration,
|
|
8
|
+
)
|
|
9
|
+
from typer.testing import CliRunner
|
|
10
|
+
|
|
11
|
+
from tests.example_project import ExampleProject
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_add(runner: CliRunner, example_project: ExampleProject) -> None:
|
|
15
|
+
result = runner.invoke(app, ["add", "tomli"])
|
|
16
|
+
assert result.exit_code == 0
|
|
17
|
+
assert example_project.get_existing_libraries() == {"tomli"}
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def test_remove_existing_package(runner: CliRunner, example_project: ExampleProject) -> None:
|
|
21
|
+
result = runner.invoke(app, ["add", "tomli"])
|
|
22
|
+
assert result.exit_code == 0
|
|
23
|
+
|
|
24
|
+
result = runner.invoke(app, ["remove", "tomli"])
|
|
25
|
+
assert result.exit_code == 0
|
|
26
|
+
assert example_project.get_existing_libraries() == set()
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def test_remove_non_existing_package(runner: CliRunner, example_project: ExampleProject) -> None:
|
|
30
|
+
result = runner.invoke(app, ["add", "tomli"])
|
|
31
|
+
assert result.exit_code == 0
|
|
32
|
+
|
|
33
|
+
result = runner.invoke(app, ["remove", "pytest"])
|
|
34
|
+
assert result.exit_code != 0
|
|
35
|
+
assert example_project.get_existing_libraries() == {"tomli"}
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def test_add_then_sync_multiple_times(runner: CliRunner, example_project: ExampleProject) -> None:
|
|
39
|
+
result = runner.invoke(app, ["add", "tomli"])
|
|
40
|
+
assert result.exit_code == 0
|
|
41
|
+
|
|
42
|
+
for _ in range(10):
|
|
43
|
+
result = runner.invoke(app, ["sync"])
|
|
44
|
+
assert result.exit_code == 0
|
|
45
|
+
|
|
46
|
+
assert example_project.get_existing_libraries() == {"tomli"}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
def test_add_to_unrelated_group(runner: CliRunner, example_project: ExampleProject) -> None:
|
|
50
|
+
result = runner.invoke(app, ["add", "tomli"])
|
|
51
|
+
assert result.exit_code == 0
|
|
52
|
+
result = runner.invoke(app, ["add", "tomli-w", "--group", "unrelated-group"])
|
|
53
|
+
assert result.exit_code != 0, (
|
|
54
|
+
"Adding to a group with reyk-cli that isn't in 'vendor-groups' should result in an error"
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
assert example_project.get_existing_libraries() == {"tomli"}
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@pytest.mark.parametrize(
|
|
61
|
+
"example_project",
|
|
62
|
+
[
|
|
63
|
+
ReykConfiguration(
|
|
64
|
+
libraries_path=DEFAULT_LIBRARIES_TARGET_PATH,
|
|
65
|
+
vendor_groups={DEFAULT_VENDOR_GROUP, "another-vendored-group"},
|
|
66
|
+
vendor_exclusions=set(),
|
|
67
|
+
),
|
|
68
|
+
],
|
|
69
|
+
indirect=True,
|
|
70
|
+
)
|
|
71
|
+
def test_add_to_new_vendor_groups(runner: CliRunner, example_project: ExampleProject) -> None:
|
|
72
|
+
result = runner.invoke(app, ["add", "tomli"])
|
|
73
|
+
assert result.exit_code != 0 # Because another-vendored-group does not exist
|
|
74
|
+
result = runner.invoke(app, ["add", "tomli-w", "--group", "another-vendored-group"])
|
|
75
|
+
assert result.exit_code == 0
|
|
76
|
+
|
|
77
|
+
assert example_project.get_existing_libraries() == {"tomli", "tomli_w"}
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
@pytest.mark.parametrize(
|
|
81
|
+
"example_project",
|
|
82
|
+
[
|
|
83
|
+
ReykConfiguration(
|
|
84
|
+
libraries_path=DEFAULT_LIBRARIES_TARGET_PATH,
|
|
85
|
+
vendor_groups={"different-vendored-group"},
|
|
86
|
+
vendor_exclusions=set(),
|
|
87
|
+
),
|
|
88
|
+
],
|
|
89
|
+
indirect=True,
|
|
90
|
+
)
|
|
91
|
+
def test_change_vendor_libs(runner: CliRunner, example_project: ExampleProject) -> None:
|
|
92
|
+
result = runner.invoke(app, ["add", "tomli", "--group", "different-vendored-group"])
|
|
93
|
+
assert result.exit_code == 0
|
|
94
|
+
|
|
95
|
+
assert example_project.get_existing_libraries() == {"tomli"}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
def test_sync_no_vendor_groups(runner: CliRunner, example_project: ExampleProject) -> None:
|
|
99
|
+
result = runner.invoke(app, "sync")
|
|
100
|
+
assert result.exit_code != 0, "Vendor groups does not exist in pyproject toml but sync works."
|
|
101
|
+
assert not example_project.has_libs_directory() # sync did not work
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
@pytest.mark.parametrize(
|
|
105
|
+
"example_project",
|
|
106
|
+
[
|
|
107
|
+
ReykConfiguration(
|
|
108
|
+
libraries_path="different_libs",
|
|
109
|
+
vendor_groups=DEFAULT_VENDOR_GROUPS,
|
|
110
|
+
vendor_exclusions=set(),
|
|
111
|
+
),
|
|
112
|
+
],
|
|
113
|
+
indirect=True,
|
|
114
|
+
)
|
|
115
|
+
def test_change_vendor_target(runner: CliRunner, example_project: ExampleProject) -> None:
|
|
116
|
+
result = runner.invoke(app, ["add", "tomli"])
|
|
117
|
+
assert result.exit_code == 0
|
|
118
|
+
|
|
119
|
+
assert example_project.get_existing_libraries() == {"tomli"}
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@pytest.mark.parametrize(
|
|
123
|
+
"example_project",
|
|
124
|
+
[
|
|
125
|
+
ReykConfiguration(
|
|
126
|
+
libraries_path=DEFAULT_LIBRARIES_TARGET_PATH,
|
|
127
|
+
vendor_groups=DEFAULT_VENDOR_GROUPS,
|
|
128
|
+
vendor_exclusions={"colorama"},
|
|
129
|
+
),
|
|
130
|
+
],
|
|
131
|
+
indirect=True,
|
|
132
|
+
)
|
|
133
|
+
def test_vendor_exclusions(runner: CliRunner, example_project: ExampleProject) -> None:
|
|
134
|
+
result = runner.invoke(app, ["add", "tqdm"])
|
|
135
|
+
assert result.exit_code == 0
|
|
136
|
+
|
|
137
|
+
assert example_project.get_existing_libraries() == {"tqdm"}
|
reyk_cli-0.0.1/PKG-INFO
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.3
|
|
2
|
-
Name: reyk-cli
|
|
3
|
-
Version: 0.0.1
|
|
4
|
-
Summary: Manage isolated environment dependencies.
|
|
5
|
-
Requires-Dist: typer>=0.20.0
|
|
6
|
-
Requires-Dist: tomli>=2.4.0 ; python_full_version < '3.11'
|
|
7
|
-
Requires-Python: >=3.9
|
|
8
|
-
Description-Content-Type: text/markdown
|
|
9
|
-
|
|
File without changes
|
|
File without changes
|
|
File without changes
|