envrcctl 0.2.5__tar.gz → 0.2.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.
- {envrcctl-0.2.5 → envrcctl-0.2.6}/PKG-INFO +1 -1
- {envrcctl-0.2.5 → envrcctl-0.2.6}/pyproject.toml +1 -1
- {envrcctl-0.2.5 → envrcctl-0.2.6}/scripts/release_artifacts.py +101 -5
- {envrcctl-0.2.5 → envrcctl-0.2.6}/.gitignore +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/LICENSE +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/README.md +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/completions/envrcctl.bash +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/completions/envrcctl.fish +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/completions/envrcctl.zsh +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/scripts/build_macos_auth_helper.sh +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/scripts/generate_completions.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/scripts/macos/envrcctl-macos-auth.swift +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/scripts/package_for_ship.sh +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/src/envrcctl/__init__.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/src/envrcctl/audit.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/src/envrcctl/auth.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/src/envrcctl/cli.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/src/envrcctl/command_runner.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/src/envrcctl/envrc.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/src/envrcctl/envrcctl-macos-auth.bak +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/src/envrcctl/errors.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/src/envrcctl/keychain.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/src/envrcctl/main.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/src/envrcctl/managed_block.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/src/envrcctl/secrets.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/src/envrcctl/secretservice.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/__init__.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/conftest.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/helpers/__init__.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/helpers/cli_support.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_audit.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_audit_cli.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_auth.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_cli.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_cli_doctor.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_cli_errors.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_cli_eval.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_cli_exec.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_cli_helpers.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_cli_inject.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_cli_migrate.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_cli_secret_get.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_cli_secret_list.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_cli_secret_set_unset.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_command_runner.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_envrc.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_keychain.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_main.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_managed_block.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_secrets.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_secretservice.py +0 -0
- {envrcctl-0.2.5 → envrcctl-0.2.6}/tests/test_smoke.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: envrcctl
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.6
|
|
4
4
|
Summary: Manage .envrc with managed blocks and OS-backed secrets.
|
|
5
5
|
Project-URL: Homepage, https://github.com/rioriost/envrcctl
|
|
6
6
|
Project-URL: Issues, https://github.com/rioriost/envrcctl/issues
|
|
@@ -3,6 +3,7 @@ from __future__ import annotations
|
|
|
3
3
|
|
|
4
4
|
import argparse
|
|
5
5
|
import hashlib
|
|
6
|
+
import re
|
|
6
7
|
import shutil
|
|
7
8
|
import subprocess
|
|
8
9
|
import sys
|
|
@@ -40,6 +41,87 @@ def project_version(pyproject_path: Path) -> str:
|
|
|
40
41
|
raise RuntimeError(f"Could not find project version in {pyproject_path}")
|
|
41
42
|
|
|
42
43
|
|
|
44
|
+
def project_dependencies(pyproject_path: Path) -> list[str]:
|
|
45
|
+
text = pyproject_path.read_text(encoding="utf-8")
|
|
46
|
+
match = re.search(r"(?ms)^\[project\]\n.*?^dependencies\s*=\s*\[(.*?)\]", text)
|
|
47
|
+
if not match:
|
|
48
|
+
return []
|
|
49
|
+
|
|
50
|
+
dependencies: list[str] = []
|
|
51
|
+
for raw_line in match.group(1).splitlines():
|
|
52
|
+
stripped = raw_line.strip().rstrip(",")
|
|
53
|
+
if not stripped:
|
|
54
|
+
continue
|
|
55
|
+
if stripped.startswith('"') and stripped.endswith('"'):
|
|
56
|
+
dependencies.append(stripped[1:-1])
|
|
57
|
+
elif stripped.startswith("'") and stripped.endswith("'"):
|
|
58
|
+
dependencies.append(stripped[1:-1])
|
|
59
|
+
return dependencies
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def normalize_package_name(name: str) -> str:
|
|
63
|
+
return re.sub(r"[-_.]+", "-", name).lower()
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def dependency_name(requirement: str) -> str:
|
|
67
|
+
base = re.split(r"[<>=!~;\[\]\s]", requirement, maxsplit=1)[0]
|
|
68
|
+
if not base:
|
|
69
|
+
raise RuntimeError(f"Could not parse dependency requirement: {requirement}")
|
|
70
|
+
return normalize_package_name(base)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def uv_lock_package_block(lock_text: str, package_name: str) -> str:
|
|
74
|
+
normalized = normalize_package_name(package_name)
|
|
75
|
+
current: list[str] = []
|
|
76
|
+
in_package = False
|
|
77
|
+
|
|
78
|
+
for line in lock_text.splitlines():
|
|
79
|
+
if line == "[[package]]":
|
|
80
|
+
if in_package:
|
|
81
|
+
block = "\n".join(current)
|
|
82
|
+
name_match = re.search(r'^name = "([^"]+)"$', block, re.MULTILINE)
|
|
83
|
+
if name_match and normalize_package_name(name_match.group(1)) == normalized:
|
|
84
|
+
return block
|
|
85
|
+
current = [line]
|
|
86
|
+
in_package = True
|
|
87
|
+
continue
|
|
88
|
+
|
|
89
|
+
if in_package:
|
|
90
|
+
current.append(line)
|
|
91
|
+
|
|
92
|
+
if in_package:
|
|
93
|
+
block = "\n".join(current)
|
|
94
|
+
name_match = re.search(r'^name = "([^"]+)"$', block, re.MULTILINE)
|
|
95
|
+
if name_match and normalize_package_name(name_match.group(1)) == normalized:
|
|
96
|
+
return block
|
|
97
|
+
|
|
98
|
+
raise RuntimeError(f"Package {package_name!r} not found in uv.lock")
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def extract_sdist_url_and_sha(block: str, package_name: str) -> tuple[str, str]:
|
|
102
|
+
sdist_match = re.search(
|
|
103
|
+
r'sdist = \{ url = "([^"]+\.tar\.gz)", hash = "sha256:([0-9a-f]+)"',
|
|
104
|
+
block,
|
|
105
|
+
)
|
|
106
|
+
if sdist_match:
|
|
107
|
+
return sdist_match.group(1), sdist_match.group(2)
|
|
108
|
+
|
|
109
|
+
raise RuntimeError(f"Could not find sdist URL and sha256 for {package_name!r} in uv.lock")
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def dependency_resource_specs(repo_root: Path) -> list[tuple[str, str, str]]:
|
|
113
|
+
lock_text = (repo_root / "uv.lock").read_text(encoding="utf-8")
|
|
114
|
+
specs: list[tuple[str, str, str]] = []
|
|
115
|
+
|
|
116
|
+
for requirement in project_dependencies(repo_root / "pyproject.toml"):
|
|
117
|
+
package_name = dependency_name(requirement)
|
|
118
|
+
block = uv_lock_package_block(lock_text, package_name)
|
|
119
|
+
url, sha256 = extract_sdist_url_and_sha(block, package_name)
|
|
120
|
+
specs.append((package_name, url, sha256))
|
|
121
|
+
|
|
122
|
+
return specs
|
|
123
|
+
|
|
124
|
+
|
|
43
125
|
def require_command(name: str) -> None:
|
|
44
126
|
if shutil.which(name) is None:
|
|
45
127
|
raise RuntimeError(f"Required command not found in PATH: {name}")
|
|
@@ -141,11 +223,26 @@ def formula_content(
|
|
|
141
223
|
helper_sha256: str,
|
|
142
224
|
homepage: str,
|
|
143
225
|
license_name: str,
|
|
226
|
+
dependency_resources: list[tuple[str, str, str]],
|
|
144
227
|
) -> str:
|
|
145
228
|
release_base = f"{homepage}/releases/download/{version}"
|
|
146
229
|
source_url = f"{release_base}/envrcctl-{version}.tar.gz"
|
|
147
230
|
helper_url = f"{release_base}/envrcctl-macos-auth-{version}-arm64.tar.gz"
|
|
148
231
|
|
|
232
|
+
resource_blocks = []
|
|
233
|
+
install_lines = []
|
|
234
|
+
for package_name, package_url, package_sha256 in dependency_resources:
|
|
235
|
+
resource_blocks.append(
|
|
236
|
+
f""" resource "{package_name}" do
|
|
237
|
+
url "{package_url}"
|
|
238
|
+
sha256 "{package_sha256}"
|
|
239
|
+
end"""
|
|
240
|
+
)
|
|
241
|
+
install_lines.append(f' venv.pip_install resource("{package_name}")')
|
|
242
|
+
|
|
243
|
+
resources_section = "\n\n".join(resource_blocks)
|
|
244
|
+
install_resources = "\n".join(install_lines)
|
|
245
|
+
|
|
149
246
|
return f"""class Envrcctl < Formula
|
|
150
247
|
include Language::Python::Virtualenv
|
|
151
248
|
|
|
@@ -157,10 +254,7 @@ def formula_content(
|
|
|
157
254
|
|
|
158
255
|
depends_on "python@3.12"
|
|
159
256
|
|
|
160
|
-
|
|
161
|
-
url "https://files.pythonhosted.org/packages/source/t/typer/typer-0.24.1.tar.gz"
|
|
162
|
-
sha256 "8bf4e81499611d3161106e998fe4d624a83abf8bfda3b99898b4498d0c2f0976"
|
|
163
|
-
end
|
|
257
|
+
{resources_section}
|
|
164
258
|
|
|
165
259
|
on_macos do
|
|
166
260
|
on_arm do
|
|
@@ -173,7 +267,7 @@ def formula_content(
|
|
|
173
267
|
|
|
174
268
|
def install
|
|
175
269
|
venv = virtualenv_create(libexec, "python3.12")
|
|
176
|
-
|
|
270
|
+
{install_resources}
|
|
177
271
|
venv.pip_install buildpath
|
|
178
272
|
|
|
179
273
|
bin.install_symlink libexec/"bin/envrcctl"
|
|
@@ -261,6 +355,7 @@ def main() -> int:
|
|
|
261
355
|
|
|
262
356
|
source_sha256 = sha256_file(sdist_path)
|
|
263
357
|
helper_sha256 = sha256_file(helper_archive)
|
|
358
|
+
dependency_resources = dependency_resource_specs(repo_root)
|
|
264
359
|
|
|
265
360
|
formula_path = write_formula(
|
|
266
361
|
repo_root,
|
|
@@ -270,6 +365,7 @@ def main() -> int:
|
|
|
270
365
|
helper_sha256=helper_sha256,
|
|
271
366
|
homepage=args.homepage,
|
|
272
367
|
license_name=args.license_name,
|
|
368
|
+
dependency_resources=dependency_resources,
|
|
273
369
|
),
|
|
274
370
|
args.formula_dir,
|
|
275
371
|
)
|
|
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
|