pluck-cli 0.1.0__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,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 gh-install contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,390 @@
1
+ Metadata-Version: 2.4
2
+ Name: pluck-cli
3
+ Version: 0.1.0
4
+ Summary: Pluck any git repo from any forge β€” auto-detect, auto-install, done!
5
+ Author: pluck contributors
6
+ License-Expression: MIT
7
+ Keywords: git,forge,installer,cli,github,gitlab,codeberg
8
+ Classifier: Development Status :: 3 - Alpha
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: End Users/Desktop
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.6
13
+ Classifier: Programming Language :: Python :: 3.7
14
+ Classifier: Programming Language :: Python :: 3.8
15
+ Classifier: Programming Language :: Python :: 3.9
16
+ Classifier: Programming Language :: Python :: 3.10
17
+ Classifier: Programming Language :: Python :: 3.11
18
+ Classifier: Programming Language :: Python :: 3.12
19
+ Classifier: Topic :: System :: Installation/Setup
20
+ Classifier: Topic :: Utilities
21
+ Requires-Python: >=3.6
22
+ Description-Content-Type: text/markdown
23
+ License-File: LICENSE
24
+ Dynamic: license-file
25
+
26
+ <p align="center">
27
+ <img src="assets/images/pluck_logo.png" alt="pluck" width="400"/>
28
+ <br>
29
+ <strong>Pluck git repos from any forge β€” auto-detect, auto-install, done!</strong>
30
+ </p>
31
+
32
+ <p align="center">
33
+ <img src="https://img.shields.io/badge/Platform-Linux%20%7C%20macOS-333?logo=linux" alt="Platform: Linux | macOS">
34
+ <img src="https://img.shields.io/badge/Python-3.8%2B-3776AB?logo=python&logoColor=white" alt="Python 3.8+">
35
+ <img src="https://img.shields.io/badge/License-MIT-yellow" alt="License: MIT">
36
+ <img src="https://img.shields.io/badge/Dependencies-Zero-brightgreen" alt="Zero dependencies">
37
+ <img src="https://img.shields.io/badge/Tests-111%20passing-brightgreen" alt="111 passing tests">
38
+ <img src="https://img.shields.io/badge/Forges-11%20supported-blue" alt="11 forges supported">
39
+ <img src="https://img.shields.io/badge/Code%20style-ruff-EF5552" alt="Code style: ruff">
40
+ </p>
41
+
42
+ ---
43
+
44
+ - [Quick Start](#-quick-start)
45
+ - [How It Works](#-how-it-works)
46
+ - [Features](#-features)
47
+ - [Commands](#-commands)
48
+ - [Flags](#-flags)
49
+ - [Installation](#-installation)
50
+ - [Configuration](#-configuration)
51
+ - [Project Structure](#-project-structure)
52
+ - [Development](#-development)
53
+
54
+ ## πŸš€ Quick Start
55
+
56
+ <p align="center">
57
+ <img src="assets/images/pluck_chasing.png" alt="pluck chasing repos" width="600"/>
58
+ </p>
59
+
60
+ ```bash
61
+ # Install from any git forge β€” one command, zero fuss
62
+ pluck install https://github.com/user/repo
63
+ pluck install https://gitlab.com/user/project
64
+ pluck install https://codeberg.org/user/repo
65
+ pluck install https://bitbucket.org/owner/repo
66
+
67
+ # That's it. Pluck detects the project type and installs it.
68
+ ```
69
+
70
+ ## πŸ”„ How It Works
71
+
72
+ <p align="center">
73
+ <img src="assets/images/pluck_stalking.png" alt="pluck stalking a repo" width="600"/>
74
+ </p>
75
+
76
+ ```
77
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
78
+ β”‚ Any git URL │────▢│ Clone to │────▢│ Detect Method │────▢│ Install β”‚
79
+ β”‚ (any forge) β”‚ β”‚ Temp Dir β”‚ β”‚ (Auto-detect) β”‚ β”‚ (8 methods) β”‚
80
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
81
+ β”‚
82
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
83
+ β”‚ Post-Install │◀────│ Register β”‚β—€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
84
+ β”‚ Hook (opt) β”‚ β”‚ App β”‚
85
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
86
+ β”‚
87
+ β–Ό
88
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
89
+ β”‚ Summary + β”‚
90
+ β”‚ Cleanup β”‚
91
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
92
+ ```
93
+
94
+ ### Install Methods
95
+
96
+ | Method | Detection | Action |
97
+ |--------|-----------|--------|
98
+ | πŸ”§ **Script** | `install.sh` | Runs `bash install.sh --yes` |
99
+ | 🐍 **Python** | `pyproject.toml`, `setup.py` | Creates venv, pip installs |
100
+ | 🟒 **Node.js** | `package.json` | Copies source, runs `npm install` |
101
+ | πŸ”΅ **Go** | `go.mod`, `*.go` | Runs `go build -o` to install dir |
102
+ | πŸ¦€ **Rust** | `Cargo.toml` | Runs `cargo build --release`, copies binary |
103
+ | πŸ“‹ **Makefile** | `Makefile` | Runs `make install PREFIX=...` |
104
+ | πŸ“¦ **Binary** | `release/`, `bin/`, `*.AppImage`, `*.deb` | Copies to install dir |
105
+ | πŸ“₯ **Download** | Fallback | Copies entire directory |
106
+
107
+ ## ✨ Features
108
+
109
+ ### Installation
110
+ - πŸ”— **Any git forge** β€” Install from GitHub, GitLab, Codeberg, Bitbucket, SourceHut, Gitea, Gogs, Pagure, Forgejo, self-hosted, or any git URL
111
+ - πŸ” **Auto-detection** β€” Automatically detects project type and install method
112
+ - πŸ“¦ **Batch install** β€” Install multiple repositories in one command
113
+ - ⚑ **Shallow clone** β€” `--shallow` for faster downloads
114
+ - 🏷️ **Branch/tag support** β€” `--ref` to install specific versions
115
+ - 🎯 **Force method** β€” `--method` to override auto-detection
116
+ - ⏱️ **Timeout & retry** β€” `--timeout` and `--retries` for flaky connections
117
+
118
+ ### Management
119
+ - πŸ“‹ **List apps** β€” See all installed applications with disk size
120
+ - πŸ”„ **Update apps** β€” Re-install from original URL
121
+ - πŸ—‘οΈ **Uninstall** β€” Remove apps with safety guards
122
+ - βœ… **Verify** β€” Check installed apps integrity
123
+ - 🧹 **Clean** β€” Remove orphaned registry entries
124
+ - πŸ“Š **Stats** β€” Installation statistics and method breakdown
125
+ - 🌐 **Multi-forge search** β€” Search GitHub, GitLab, or Codeberg with `--forge`
126
+ - πŸ–±οΈ **Browser right-click** β€” Optional extension + protocol handler to install from any page
127
+ - πŸ“€ **Export/Import** β€” Migrate registry between machines
128
+
129
+ ### Configuration
130
+ - πŸ“ **Custom directory** β€” `--dir` to override default install location
131
+ - βš™οΈ **User config** β€” Persistent settings via config file
132
+ - 🎨 **JSON output** β€” `--json` for machine-readable output
133
+ - 🚫 **No colors** β€” `--no-color` for clean terminal output
134
+ - πŸ”‡ **Non-interactive** β€” `--yes` for scripting
135
+ - 🐳 **Docker support** β€” Containerized installation
136
+ - πŸ“– **Man page** β€” `man pluck` for offline docs
137
+ - πŸ”§ **Post-install hooks** β€” Custom scripts after each install
138
+
139
+ ## 🌐 Supported Forges
140
+
141
+ | Forge | Host | Built-in | Notes |
142
+ |-------|------|----------|-------|
143
+ | **GitHub** | `github.com` | βœ… | Full support including gists |
144
+ | **GitLab** | `gitlab.com` | βœ… | HTTPS & SSH, self-hosted instances auto-detected |
145
+ | **Codeberg** | `codeberg.org` | βœ… | Powered by Forgejo |
146
+ | **Bitbucket** | `bitbucket.org` | βœ… | Both cloud & self-hosted |
147
+ | **SourceHut** | `git.sr.ht` | βœ… | Supports `~user` prefix |
148
+ | **Gitea** | `gitea.com` | βœ… | Any Gitea instance works |
149
+ | **Gogs** | `gogs.io` | βœ… | Lightweight git service |
150
+ | **Pagure** | `pagure.io` | βœ… | Fedora's git hosting |
151
+ | **Forgejo** | `forgejo.org` | βœ… | Self-hosted friendly |
152
+ | **Any other hosted git** | Any domain | βœ… | Parses as `generic` type |
153
+ | **Self-hosted** | Any IP/domain | βœ… | SSH & HTTPS both supported |
154
+
155
+ Any git hosting platform that follows the standard `host/owner/repo` URL pattern works β€” no plugin or config needed.
156
+
157
+ ## πŸ“– Commands
158
+
159
+ | Command | Description | Example |
160
+ |---------|-------------|---------|
161
+ | `install <url>` | Install from any git repo URL | `pluck install https://gitlab.com/user/project` |
162
+ | `update <name>` | Update an installed app | `pluck update myapp` |
163
+ | `info <name>` | Show app details | `pluck info myapp` |
164
+ | `list` | List installed apps | `pluck list` |
165
+ | `uninstall <name>` | Uninstall an app | `pluck uninstall myapp` |
166
+ | `remove <name>` | Alias for uninstall | `pluck remove myapp` |
167
+ | `verify` | Check apps validity | `pluck verify` |
168
+ | `clean` | Remove orphaned entries | `pluck clean --force` |
169
+ | `stats` | Show statistics | `pluck stats` |
170
+ | `doctor` | Check tool availability | `pluck doctor` |
171
+ | `config [key] [val]` | View/set config | `pluck config install_dir ~/Apps` |
172
+ | `search <query>` | Search GitHub repos (other forges coming) | `pluck search python installer` |
173
+ | `export <file>` | Export registry | `pluck export ~/backup.json` |
174
+ | `import <file>` | Import registry | `pluck import ~/backup.json` |
175
+ | `completion <shell>` | Generate shell completion | `pluck completion bash` |
176
+ | `version` | Show version | `pluck version` |
177
+ | `help` | Show help | `pluck help` |
178
+
179
+ ## 🏷️ Flags
180
+
181
+ | Flag | Description |
182
+ |------|-------------|
183
+ | `--dir <path>` | Install to a custom directory |
184
+ | `--dry-run` | Preview without making changes |
185
+ | `--force` | Skip confirmation prompts |
186
+ | `--shallow` | Use shallow clone (`--depth 1`) |
187
+ | `--ref <ref>` | Clone a specific branch or tag |
188
+ | `--method <method>` | Force install method |
189
+ | `--yes` | Non-interactive mode (alias for `--force`) |
190
+ | `--json` | Output in JSON format (for scripting) |
191
+ | `--no-color` | Disable colored output |
192
+ | `--timeout <secs>` | Timeout for git clone in seconds |
193
+ | `--retries <n>` | Number of retries for failed git clone |
194
+
195
+ ## πŸ“₯ Installation
196
+
197
+ ### From Source
198
+
199
+ ```bash
200
+ # Clone the repository
201
+ git clone https://gitlab.com/mabodu/pluck.git
202
+ cd pluck
203
+
204
+ # Install via pip
205
+ pip install -e .
206
+
207
+ # Or run directly
208
+ ./src/gh_install.py install https://gitlab.com/user/project
209
+ ```
210
+
211
+ ### Via pip (not yet on PyPI)
212
+
213
+ ```bash
214
+ # Once published to PyPI:
215
+ pip install pluck-cli
216
+ ```
217
+
218
+ > **Note**: `pluck-cli` is not yet published to PyPI. Install from source above, or use the Docker image.
219
+
220
+ ### Via Docker
221
+
222
+ ```bash
223
+ docker build -t pluck .
224
+ docker run pluck install https://gitlab.com/user/project
225
+ ```
226
+
227
+ ## βš™οΈ Configuration
228
+
229
+ ### Default Paths
230
+
231
+ | Constant | macOS | Linux | Description |
232
+ |----------|-------|-------|-------------|
233
+ | `DEFAULT_INSTALL_DIR` | `~/Applications` | `~/.local/opt` | Where apps are installed |
234
+ | `APP_REGISTRY_FILE` | `~/.pluck-registry.json` | `~/.pluck-registry.json` | App registry |
235
+ | `CONFIG_FILE` | `~/.config/pluck/config.json` | `~/.config/pluck/config.json` | User config |
236
+
237
+ ### User Config File
238
+
239
+ ```json
240
+ {
241
+ "install_dir": "/custom/path",
242
+ "method_priority": ["script", "python", "node", "go", "rust", "make", "binary", "download"]
243
+ }
244
+ ```
245
+
246
+ Manage via CLI:
247
+
248
+ ```bash
249
+ pluck config install_dir ~/Apps
250
+ pluck config method_priority '["python","node","binary","download"]'
251
+ ```
252
+
253
+ ### Post-Install Hooks
254
+
255
+ Create `~/.config/pluck/hooks/post-install.sh` to run custom scripts after each install.
256
+
257
+ Available environment variables:
258
+ - `$PLUCK_APP` β€” Repository name
259
+ - `$PLUCK_PATH` β€” Installation path
260
+ - `$PLUCK_METHOD` β€” Install method used
261
+
262
+ ## πŸ–±οΈ Browser Integration
263
+
264
+ Pluck includes a **right-click context menu** integration. Install a repo from any
265
+ forge without leaving your browser.
266
+
267
+ ### Quick Setup
268
+
269
+ ```bash
270
+ # 1. Register the pluck:// protocol handler on your OS
271
+ bash scripts/install-protocol-handler.sh
272
+
273
+ # 2. Load the browser extension (Chrome/Chromium/Brave/Edge)
274
+ # Open chrome://extensions β†’ Developer mode β†’ Load unpacked
275
+ # Select assets/browser-extension/
276
+
277
+ # 3. Right-click any git repo link β†’ "Install with pluck"
278
+ ```
279
+
280
+ Works with GitHub, GitLab, Codeberg, Bitbucket, SourceHut β€” any forge.
281
+
282
+ ### No Extension? Use the Bookmarklet
283
+
284
+ If you prefer not to install an extension, create a bookmark with this URL:
285
+
286
+ ```
287
+ javascript:location.href='pluck://install?url='+encodeURIComponent(location.href)
288
+ ```
289
+
290
+ When you're on a git repo page, click the bookmark to install it.
291
+
292
+ ### How It Works
293
+
294
+ The protocol handler is a small shell script (`scripts/pluck-protocol-handler.sh`)
295
+ that receives `pluck://install?url=...` calls from the browser, decodes the URL,
296
+ and runs `pluck install <url>`. The browser extension adds the right-click menu
297
+ item that triggers this protocol call.
298
+
299
+ ## πŸ“ Project Structure
300
+
301
+ ```
302
+ pluck/
303
+ β”œβ”€β”€ src/
304
+ β”‚ └── gh_install.py # Main application (~1700 lines)
305
+ β”œβ”€β”€ tests/
306
+ β”‚ └── test_gh_install.py # Test suite (111 tests)
307
+ β”œβ”€β”€ assets/
308
+ β”‚ β”œβ”€β”€ images/ # Logo and illustrations
309
+ β”‚ └── browser-extension/ # Chrome/Chromium right-click extension
310
+ β”œβ”€β”€ scripts/
311
+ β”‚ β”œβ”€β”€ pluck-protocol-handler.sh # pluck:// URL handler
312
+ β”‚ └── install-protocol-handler.sh # Protocol registration
313
+ β”œβ”€β”€ docs/
314
+ β”‚ └── IMPLEMENTATION.md # Implementation details
315
+ β”œβ”€β”€ man/
316
+ β”‚ β”œβ”€β”€ pluck.1 # Man page
317
+ β”‚ └── gh-install.1 # Legacy man page
318
+ β”œβ”€β”€ .github/
319
+ β”‚ └── workflows/
320
+ β”‚ β”œβ”€β”€ ci.yml # CI: test + lint
321
+ β”‚ └── publish-pypi.yml # PyPI publish
322
+ β”œβ”€β”€ README.md # This file
323
+ β”œβ”€β”€ CHANGELOG.md # Version history
324
+ β”œβ”€β”€ CONTRIBUTING.md # Developer guide
325
+ β”œβ”€β”€ LICENSE # MIT License
326
+ β”œβ”€β”€ Dockerfile # Container image
327
+ β”œβ”€β”€ pyproject.toml # Package config
328
+ β”œβ”€β”€ .pre-commit-config.yaml # Pre-commit hooks
329
+ β”œβ”€β”€ .gitignore # Git ignore patterns
330
+ └── .dockerignore # Docker ignore patterns
331
+ ```
332
+
333
+ ## πŸ› οΈ Development
334
+
335
+ ```bash
336
+ # Install dev dependencies
337
+ pip install pytest ruff
338
+
339
+ # Run tests
340
+ python -m pytest tests/ -v
341
+
342
+ # Run linter
343
+ ruff check src/ tests/
344
+
345
+ # Install pre-commit hooks
346
+ pip install pre-commit
347
+ pre-commit install
348
+ ```
349
+
350
+ ### Test Coverage
351
+
352
+ ```
353
+ 111 tests passing across 24 test classes:
354
+ β”œβ”€β”€ TestParseRepoUrl (22 tests)
355
+ β”œβ”€β”€ TestGistUrl (7 tests) β€” includes GitLab snippets
356
+ β”œβ”€β”€ TestDetectInstallMethod (17 tests)
357
+ β”œβ”€β”€ TestSharedPaths (2 tests)
358
+ β”œβ”€β”€ TestValidMethods (2 tests)
359
+ β”œβ”€β”€ TestSanitizeRepoName (4 tests)
360
+ β”œβ”€β”€ TestIsExecutable (6 tests)
361
+ β”œβ”€β”€ TestGetDiskSize (3 tests)
362
+ β”œβ”€β”€ TestParseArgs (10 tests)
363
+ β”œβ”€β”€ TestDryRun (1 test)
364
+ β”œβ”€β”€ TestRegistryOperations (3 tests)
365
+ β”œβ”€β”€ TestUpdateApp (2 tests)
366
+ β”œβ”€β”€ TestInfoApp (2 tests)
367
+ β”œβ”€β”€ TestDoctor (2 tests)
368
+ β”œβ”€β”€ TestConfigCommand (2 tests)
369
+ β”œβ”€β”€ TestExportImport (4 tests)
370
+ β”œβ”€β”€ TestVerifyApps (3 tests)
371
+ β”œβ”€β”€ TestStatsCommand (2 tests)
372
+ β”œβ”€β”€ TestFormatBytes (5 tests)
373
+ β”œβ”€β”€ TestExtractGlobalFlags (5 tests)
374
+ └── TestDownloadAndInstallMocked (4 tests)
375
+ ```
376
+
377
+
378
+ ## πŸ“„ License
379
+
380
+ This project is licensed under the MIT License β€” see the [LICENSE](LICENSE) file for details.
381
+
382
+ ## 🀝 Contributing
383
+
384
+ Contributions are welcome! Please read the [Contributing Guide](CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests.
385
+
386
+ ---
387
+
388
+ <p align="center">
389
+ Made with ❀️ for non-technical users everywhere
390
+ </p>