droppass-cli 0.1.3__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.
@@ -0,0 +1,51 @@
1
+ Metadata-Version: 2.4
2
+ Name: droppass-cli
3
+ Version: 0.1.3
4
+ Summary: droppass CLI distributed via pip
5
+ Author: AFK Surf
6
+ License-Expression: LicenseRef-UNLICENSED
7
+ Project-URL: Homepage, https://github.com/AFK-surf/droppass
8
+ Project-URL: Repository, https://github.com/AFK-surf/droppass
9
+ Keywords: droppass,cli,secrets,agent
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Environment :: Console
12
+ Classifier: Operating System :: MacOS
13
+ Classifier: Operating System :: Microsoft :: Windows
14
+ Classifier: Operating System :: POSIX :: Linux
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Topic :: Utilities
18
+ Requires-Python: >=3.9
19
+ Description-Content-Type: text/markdown
20
+
21
+ # droppass-cli
22
+
23
+ Install globally with pip:
24
+
25
+ ```bash
26
+ pip install droppass-cli
27
+ ```
28
+
29
+ The package ships a Python launcher plus prebuilt `droppass` binaries for the
30
+ same targets as the standalone release assets:
31
+
32
+ - `darwin-x64`
33
+ - `darwin-arm64`
34
+ - `linux-x64`
35
+ - `linux-arm64`
36
+ - `linux-arm`
37
+ - `win32-x64`
38
+ - `win32-arm64`
39
+
40
+ The launcher selects the matching embedded binary at runtime.
41
+
42
+ Maintainer release flow:
43
+
44
+ ```bash
45
+ cd cli
46
+ node ./scripts/build-pip-package.mjs
47
+ python3 -m build --outdir ./dist/pip/dist ./dist/pip/package
48
+ ```
49
+
50
+ CI publishes the package to PyPI from `v*` tags. See `cli/RELEASING.md`
51
+ for the full release workflow.
@@ -0,0 +1,31 @@
1
+ # droppass-cli
2
+
3
+ Install globally with pip:
4
+
5
+ ```bash
6
+ pip install droppass-cli
7
+ ```
8
+
9
+ The package ships a Python launcher plus prebuilt `droppass` binaries for the
10
+ same targets as the standalone release assets:
11
+
12
+ - `darwin-x64`
13
+ - `darwin-arm64`
14
+ - `linux-x64`
15
+ - `linux-arm64`
16
+ - `linux-arm`
17
+ - `win32-x64`
18
+ - `win32-arm64`
19
+
20
+ The launcher selects the matching embedded binary at runtime.
21
+
22
+ Maintainer release flow:
23
+
24
+ ```bash
25
+ cd cli
26
+ node ./scripts/build-pip-package.mjs
27
+ python3 -m build --outdir ./dist/pip/dist ./dist/pip/package
28
+ ```
29
+
30
+ CI publishes the package to PyPI from `v*` tags. See `cli/RELEASING.md`
31
+ for the full release workflow.
@@ -0,0 +1,3 @@
1
+ from ._version import __version__
2
+
3
+ __all__ = ["__version__"]
@@ -0,0 +1,5 @@
1
+ from .launcher import main
2
+
3
+
4
+ if __name__ == "__main__":
5
+ raise SystemExit(main())
@@ -0,0 +1 @@
1
+ __version__ = "0.1.3"
@@ -0,0 +1,106 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import platform
5
+ import stat
6
+ import subprocess
7
+ import sys
8
+ from importlib import resources
9
+
10
+ TARGETS = {
11
+ "darwin-x64": {
12
+ "platform": "darwin",
13
+ "arch": "x64",
14
+ "binary_name": "droppass-darwin-x64",
15
+ },
16
+ "darwin-arm64": {
17
+ "platform": "darwin",
18
+ "arch": "arm64",
19
+ "binary_name": "droppass-darwin-arm64",
20
+ },
21
+ "linux-x64": {
22
+ "platform": "linux",
23
+ "arch": "x64",
24
+ "binary_name": "droppass-linux-x64",
25
+ },
26
+ "linux-arm64": {
27
+ "platform": "linux",
28
+ "arch": "arm64",
29
+ "binary_name": "droppass-linux-arm64",
30
+ },
31
+ "linux-arm": {
32
+ "platform": "linux",
33
+ "arch": "arm",
34
+ "binary_name": "droppass-linux-arm",
35
+ },
36
+ "win32-x64": {
37
+ "platform": "win32",
38
+ "arch": "x64",
39
+ "binary_name": "droppass-win32-x64.exe",
40
+ },
41
+ "win32-arm64": {
42
+ "platform": "win32",
43
+ "arch": "arm64",
44
+ "binary_name": "droppass-win32-arm64.exe",
45
+ },
46
+ }
47
+
48
+
49
+ def format_target(runtime_platform: str, runtime_arch: str) -> str:
50
+ return f"{runtime_platform}-{runtime_arch}"
51
+
52
+
53
+ def detect_target() -> dict[str, str]:
54
+ runtime_platform = "win32" if sys.platform.startswith("win") else sys.platform
55
+ machine = platform.machine().lower()
56
+
57
+ if runtime_platform == "darwin":
58
+ runtime_arch = "arm64" if machine in {"arm64", "aarch64"} else "x64"
59
+ elif runtime_platform == "linux":
60
+ if machine in {"x86_64", "amd64"}:
61
+ runtime_arch = "x64"
62
+ elif machine in {"aarch64", "arm64"}:
63
+ runtime_arch = "arm64"
64
+ elif machine.startswith("armv7") or machine.startswith("armv6") or machine == "arm":
65
+ runtime_arch = "arm"
66
+ else:
67
+ runtime_arch = machine
68
+ elif runtime_platform == "win32":
69
+ if machine in {"arm64", "aarch64"}:
70
+ runtime_arch = "arm64"
71
+ else:
72
+ runtime_arch = "x64"
73
+ else:
74
+ runtime_arch = machine
75
+
76
+ key = format_target(runtime_platform, runtime_arch)
77
+ target = TARGETS.get(key)
78
+ if not target:
79
+ supported = ", ".join(sorted(TARGETS))
80
+ raise RuntimeError(f"Unsupported platform {key}. Supported targets: {supported}")
81
+ return target
82
+
83
+
84
+ def resolve_binary_path() -> str:
85
+ target = detect_target()
86
+ binary = resources.files("droppass_cli").joinpath("bin", target["binary_name"])
87
+ if not binary.is_file():
88
+ raise RuntimeError(
89
+ f"Missing embedded binary {target['binary_name']} for "
90
+ f"{format_target(target['platform'], target['arch'])}."
91
+ )
92
+
93
+ path = os.fspath(binary)
94
+ if not path.endswith(".exe"):
95
+ mode = os.stat(path).st_mode
96
+ if not mode & stat.S_IXUSR:
97
+ os.chmod(path, mode | stat.S_IXUSR)
98
+ return path
99
+
100
+
101
+ def main(argv: list[str] | None = None) -> int:
102
+ binary_path = resolve_binary_path()
103
+ completed = subprocess.run([binary_path, *(argv if argv is not None else sys.argv[1:])])
104
+ if completed.returncode < 0:
105
+ os.kill(os.getpid(), -completed.returncode)
106
+ return completed.returncode
@@ -0,0 +1,51 @@
1
+ Metadata-Version: 2.4
2
+ Name: droppass-cli
3
+ Version: 0.1.3
4
+ Summary: droppass CLI distributed via pip
5
+ Author: AFK Surf
6
+ License-Expression: LicenseRef-UNLICENSED
7
+ Project-URL: Homepage, https://github.com/AFK-surf/droppass
8
+ Project-URL: Repository, https://github.com/AFK-surf/droppass
9
+ Keywords: droppass,cli,secrets,agent
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Environment :: Console
12
+ Classifier: Operating System :: MacOS
13
+ Classifier: Operating System :: Microsoft :: Windows
14
+ Classifier: Operating System :: POSIX :: Linux
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3 :: Only
17
+ Classifier: Topic :: Utilities
18
+ Requires-Python: >=3.9
19
+ Description-Content-Type: text/markdown
20
+
21
+ # droppass-cli
22
+
23
+ Install globally with pip:
24
+
25
+ ```bash
26
+ pip install droppass-cli
27
+ ```
28
+
29
+ The package ships a Python launcher plus prebuilt `droppass` binaries for the
30
+ same targets as the standalone release assets:
31
+
32
+ - `darwin-x64`
33
+ - `darwin-arm64`
34
+ - `linux-x64`
35
+ - `linux-arm64`
36
+ - `linux-arm`
37
+ - `win32-x64`
38
+ - `win32-arm64`
39
+
40
+ The launcher selects the matching embedded binary at runtime.
41
+
42
+ Maintainer release flow:
43
+
44
+ ```bash
45
+ cd cli
46
+ node ./scripts/build-pip-package.mjs
47
+ python3 -m build --outdir ./dist/pip/dist ./dist/pip/package
48
+ ```
49
+
50
+ CI publishes the package to PyPI from `v*` tags. See `cli/RELEASING.md`
51
+ for the full release workflow.
@@ -0,0 +1,19 @@
1
+ README.md
2
+ pyproject.toml
3
+ droppass_cli/__init__.py
4
+ droppass_cli/__main__.py
5
+ droppass_cli/_version.py
6
+ droppass_cli/launcher.py
7
+ droppass_cli.egg-info/PKG-INFO
8
+ droppass_cli.egg-info/SOURCES.txt
9
+ droppass_cli.egg-info/dependency_links.txt
10
+ droppass_cli.egg-info/entry_points.txt
11
+ droppass_cli.egg-info/top_level.txt
12
+ droppass_cli/bin/droppass-darwin-arm64
13
+ droppass_cli/bin/droppass-darwin-x64
14
+ droppass_cli/bin/droppass-linux-arm
15
+ droppass_cli/bin/droppass-linux-arm64
16
+ droppass_cli/bin/droppass-linux-x64
17
+ droppass_cli/bin/droppass-win32-arm64.exe
18
+ droppass_cli/bin/droppass-win32-x64.exe
19
+ tests/test_launcher.py
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ droppass = droppass_cli.__main__:main
@@ -0,0 +1 @@
1
+ droppass_cli
@@ -0,0 +1,39 @@
1
+ [build-system]
2
+ requires = ["setuptools>=69", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "droppass-cli"
7
+ version = "0.1.3"
8
+ description = "droppass CLI distributed via pip"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = "LicenseRef-UNLICENSED"
12
+ keywords = ["droppass", "cli", "secrets", "agent"]
13
+ authors = [{ name = "AFK Surf" }]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Environment :: Console",
17
+ "Operating System :: MacOS",
18
+ "Operating System :: Microsoft :: Windows",
19
+ "Operating System :: POSIX :: Linux",
20
+ "Programming Language :: Python :: 3",
21
+ "Programming Language :: Python :: 3 :: Only",
22
+ "Topic :: Utilities",
23
+ ]
24
+
25
+ [project.urls]
26
+ Homepage = "https://github.com/AFK-surf/droppass"
27
+ Repository = "https://github.com/AFK-surf/droppass"
28
+
29
+ [project.scripts]
30
+ droppass = "droppass_cli.__main__:main"
31
+
32
+ [tool.setuptools]
33
+ include-package-data = true
34
+
35
+ [tool.setuptools.packages.find]
36
+ include = ["droppass_cli*"]
37
+
38
+ [tool.setuptools.package-data]
39
+ "droppass_cli" = ["bin/*"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,107 @@
1
+ from __future__ import annotations
2
+
3
+ import os
4
+ import stat
5
+ import tempfile
6
+ import unittest
7
+ from pathlib import Path
8
+ from types import SimpleNamespace
9
+ from unittest import mock
10
+
11
+ from droppass_cli import launcher
12
+
13
+
14
+ class DetectTargetTests(unittest.TestCase):
15
+ def test_detect_target_linux_x64(self) -> None:
16
+ with (
17
+ mock.patch.object(launcher.sys, "platform", "linux"),
18
+ mock.patch.object(launcher.platform, "machine", return_value="x86_64"),
19
+ ):
20
+ target = launcher.detect_target()
21
+
22
+ self.assertEqual(target, launcher.TARGETS["linux-x64"])
23
+
24
+ def test_detect_target_linux_arm64(self) -> None:
25
+ with (
26
+ mock.patch.object(launcher.sys, "platform", "linux"),
27
+ mock.patch.object(launcher.platform, "machine", return_value="aarch64"),
28
+ ):
29
+ target = launcher.detect_target()
30
+
31
+ self.assertEqual(target, launcher.TARGETS["linux-arm64"])
32
+
33
+ def test_detect_target_windows_x64(self) -> None:
34
+ with (
35
+ mock.patch.object(launcher.sys, "platform", "win32"),
36
+ mock.patch.object(launcher.platform, "machine", return_value="AMD64"),
37
+ ):
38
+ target = launcher.detect_target()
39
+
40
+ self.assertEqual(target, launcher.TARGETS["win32-x64"])
41
+
42
+ def test_detect_target_unsupported_platform_raises(self) -> None:
43
+ with (
44
+ mock.patch.object(launcher.sys, "platform", "linux"),
45
+ mock.patch.object(launcher.platform, "machine", return_value="ppc64le"),
46
+ ):
47
+ with self.assertRaisesRegex(RuntimeError, "Unsupported platform linux-ppc64le"):
48
+ launcher.detect_target()
49
+
50
+
51
+ class ResolveBinaryPathTests(unittest.TestCase):
52
+ def test_resolve_binary_path_sets_execute_bit(self) -> None:
53
+ with tempfile.TemporaryDirectory() as temp_dir:
54
+ package_root = Path(temp_dir)
55
+ bin_dir = package_root / "bin"
56
+ bin_dir.mkdir(parents=True)
57
+ binary_path = bin_dir / "droppass-linux-x64"
58
+ binary_path.write_text("#!/bin/sh\nexit 0\n", encoding="utf-8")
59
+ binary_path.chmod(0o644)
60
+
61
+ with (
62
+ mock.patch.object(launcher, "detect_target", return_value=launcher.TARGETS["linux-x64"]),
63
+ mock.patch.object(launcher.resources, "files", return_value=package_root),
64
+ ):
65
+ resolved = launcher.resolve_binary_path()
66
+
67
+ self.assertEqual(resolved, os.fspath(binary_path))
68
+ self.assertTrue(os.stat(resolved).st_mode & stat.S_IXUSR)
69
+
70
+ def test_resolve_binary_path_missing_binary_raises(self) -> None:
71
+ with tempfile.TemporaryDirectory() as temp_dir:
72
+ package_root = Path(temp_dir)
73
+
74
+ with (
75
+ mock.patch.object(launcher, "detect_target", return_value=launcher.TARGETS["linux-x64"]),
76
+ mock.patch.object(launcher.resources, "files", return_value=package_root),
77
+ ):
78
+ with self.assertRaisesRegex(RuntimeError, "Missing embedded binary droppass-linux-x64"):
79
+ launcher.resolve_binary_path()
80
+
81
+
82
+ class MainTests(unittest.TestCase):
83
+ def test_main_invokes_embedded_binary_with_args(self) -> None:
84
+ completed = SimpleNamespace(returncode=0)
85
+
86
+ with (
87
+ mock.patch.object(launcher, "resolve_binary_path", return_value="/tmp/droppass"),
88
+ mock.patch.object(launcher.subprocess, "run", return_value=completed) as run_mock,
89
+ ):
90
+ exit_code = launcher.main(["version"])
91
+
92
+ run_mock.assert_called_once_with(["/tmp/droppass", "version"])
93
+ self.assertEqual(exit_code, 0)
94
+
95
+ def test_main_forwards_signal_exit(self) -> None:
96
+ completed = SimpleNamespace(returncode=-15)
97
+
98
+ with (
99
+ mock.patch.object(launcher, "resolve_binary_path", return_value="/tmp/droppass"),
100
+ mock.patch.object(launcher.subprocess, "run", return_value=completed),
101
+ mock.patch.object(launcher.os, "getpid", return_value=1234),
102
+ mock.patch.object(launcher.os, "kill") as kill_mock,
103
+ ):
104
+ exit_code = launcher.main(["version"])
105
+
106
+ kill_mock.assert_called_once_with(1234, 15)
107
+ self.assertEqual(exit_code, -15)