Skip to main content

Pluck any git repo from any forge — auto-detect, auto-install, done!

Project description

pluck
Pluck git repos from any forge — auto-detect, auto-install, done!

Platform: Linux | macOS Python 3.8+ License: MIT Zero dependencies 111 passing tests 11 forges supported Code style: ruff


🚀 Quick Start

pluck chasing repos

# Install from any git forge — one command, zero fuss
pluck install https://github.com/user/repo
pluck install https://gitlab.com/user/project
pluck install https://codeberg.org/user/repo
pluck install https://bitbucket.org/owner/repo

# That's it. Pluck detects the project type and installs it.

🔄 How It Works

pluck stalking a repo

┌─────────────────┐     ┌──────────────┐     ┌─────────────────┐     ┌──────────────┐
│  Any git URL    │────▶│  Clone to    │────▶│  Detect Method  │────▶│  Install     │
│  (any forge)    │     │  Temp Dir    │     │  (Auto-detect)  │     │  (8 methods) │
└─────────────────┘     └──────────────┘     └─────────────────┘     └──────────────┘
                                                                         │
┌─────────────────┐     ┌──────────────┐                                │
│   Post-Install  │◀────│  Register    │◀───────────────────────────────┘
│   Hook (opt)    │     │  App         │
└─────────────────┘     └──────────────┘
         │
         ▼
┌─────────────────┐
│  Summary +      │
│  Cleanup        │
└─────────────────┘

Install Methods

Method Detection Action
🔧 Script install.sh Runs bash install.sh --yes
🐍 Python pyproject.toml, setup.py Creates venv, pip installs
🟢 Node.js package.json Copies source, runs npm install
🔵 Go go.mod, *.go Runs go build -o to install dir
🦀 Rust Cargo.toml Runs cargo build --release, copies binary
📋 Makefile Makefile Runs make install PREFIX=...
📦 Binary release/, bin/, *.AppImage, *.deb Copies to install dir
📥 Download Fallback Copies entire directory

✨ Features

Installation

  • 🔗 Any git forge — Install from GitHub, GitLab, Codeberg, Bitbucket, SourceHut, Gitea, Gogs, Pagure, Forgejo, self-hosted, or any git URL
  • 🔍 Auto-detection — Automatically detects project type and install method
  • 📦 Batch install — Install multiple repositories in one command
  • Shallow clone--shallow for faster downloads
  • 🏷️ Branch/tag support--ref to install specific versions
  • 🎯 Force method--method to override auto-detection
  • ⏱️ Timeout & retry--timeout and --retries for flaky connections

Management

  • 📋 List apps — See all installed applications with disk size
  • 🔄 Update apps — Re-install from original URL
  • 🗑️ Uninstall — Remove apps with safety guards
  • Verify — Check installed apps integrity
  • 🧹 Clean — Remove orphaned registry entries
  • 📊 Stats — Installation statistics and method breakdown
  • 🌐 Multi-forge search — Search GitHub, GitLab, or Codeberg with --forge
  • 🖱️ Browser right-click — Optional extension + protocol handler to install from any page
  • 📤 Export/Import — Migrate registry between machines

Configuration

  • 📁 Custom directory--dir to override default install location
  • ⚙️ User config — Persistent settings via config file
  • 🎨 JSON output--json for machine-readable output
  • 🚫 No colors--no-color for clean terminal output
  • 🔇 Non-interactive--yes for scripting
  • 🐳 Docker support — Containerized installation
  • 📖 Man pageman pluck for offline docs
  • 🔧 Post-install hooks — Custom scripts after each install

🌐 Supported Forges

Forge Host Built-in Notes
GitHub github.com Full support including gists
GitLab gitlab.com HTTPS & SSH, self-hosted instances auto-detected
Codeberg codeberg.org Powered by Forgejo
Bitbucket bitbucket.org Both cloud & self-hosted
SourceHut git.sr.ht Supports ~user prefix
Gitea gitea.com Any Gitea instance works
Gogs gogs.io Lightweight git service
Pagure pagure.io Fedora's git hosting
Forgejo forgejo.org Self-hosted friendly
Any other hosted git Any domain Parses as generic type
Self-hosted Any IP/domain SSH & HTTPS both supported

Any git hosting platform that follows the standard host/owner/repo URL pattern works — no plugin or config needed.

📖 Commands

Command Description Example
install <url> Install from any git repo URL pluck install https://gitlab.com/user/project
update <name> Update an installed app pluck update myapp
info <name> Show app details pluck info myapp
list List installed apps pluck list
uninstall <name> Uninstall an app pluck uninstall myapp
remove <name> Alias for uninstall pluck remove myapp
verify Check apps validity pluck verify
clean Remove orphaned entries pluck clean --force
stats Show statistics pluck stats
doctor Check tool availability pluck doctor
config [key] [val] View/set config pluck config install_dir ~/Apps
search <query> Search GitHub repos (other forges coming) pluck search python installer
export <file> Export registry pluck export ~/backup.json
import <file> Import registry pluck import ~/backup.json
completion <shell> Generate shell completion pluck completion bash
version Show version pluck version
help Show help pluck help

🏷️ Flags

Flag Description
--dir <path> Install to a custom directory
--dry-run Preview without making changes
--force Skip confirmation prompts
--shallow Use shallow clone (--depth 1)
--ref <ref> Clone a specific branch or tag
--method <method> Force install method
--yes Non-interactive mode (alias for --force)
--json Output in JSON format (for scripting)
--no-color Disable colored output
--timeout <secs> Timeout for git clone in seconds
--retries <n> Number of retries for failed git clone

📥 Installation

From Source

# Clone the repository
git clone https://gitlab.com/mabodu/pluck.git
cd pluck

# Install via pip
pip install -e .

# Or run directly
./src/gh_install.py install https://gitlab.com/user/project

Via pip (not yet on PyPI)

# Once published to PyPI:
pip install pluck-cli

Note: pluck-cli is not yet published to PyPI. Install from source above, or use the Docker image.

Via Docker

docker build -t pluck .
docker run pluck install https://gitlab.com/user/project

⚙️ Configuration

Default Paths

Constant macOS Linux Description
DEFAULT_INSTALL_DIR ~/Applications ~/.local/opt Where apps are installed
APP_REGISTRY_FILE ~/.pluck-registry.json ~/.pluck-registry.json App registry
CONFIG_FILE ~/.config/pluck/config.json ~/.config/pluck/config.json User config

User Config File

{
  "install_dir": "/custom/path",
  "method_priority": ["script", "python", "node", "go", "rust", "make", "binary", "download"]
}

Manage via CLI:

pluck config install_dir ~/Apps
pluck config method_priority '["python","node","binary","download"]'

Post-Install Hooks

Create ~/.config/pluck/hooks/post-install.sh to run custom scripts after each install.

Available environment variables:

  • $PLUCK_APP — Repository name
  • $PLUCK_PATH — Installation path
  • $PLUCK_METHOD — Install method used

🖱️ Browser Integration

Pluck includes a right-click context menu integration. Install a repo from any forge without leaving your browser.

Quick Setup

# 1. Register the pluck:// protocol handler on your OS
bash scripts/install-protocol-handler.sh

# 2. Load the browser extension (Chrome/Chromium/Brave/Edge)
#    Open chrome://extensions → Developer mode → Load unpacked
#    Select assets/browser-extension/

# 3. Right-click any git repo link → "Install with pluck"

Works with GitHub, GitLab, Codeberg, Bitbucket, SourceHut — any forge.

No Extension? Use the Bookmarklet

If you prefer not to install an extension, create a bookmark with this URL:

javascript:location.href='pluck://install?url='+encodeURIComponent(location.href)

When you're on a git repo page, click the bookmark to install it.

How It Works

The protocol handler is a small shell script (scripts/pluck-protocol-handler.sh) that receives pluck://install?url=... calls from the browser, decodes the URL, and runs pluck install <url>. The browser extension adds the right-click menu item that triggers this protocol call.

📁 Project Structure

pluck/
├── src/
│   └── gh_install.py          # Main application (~1700 lines)
├── tests/
│   └── test_gh_install.py     # Test suite (111 tests)
├── assets/
│   ├── images/                # Logo and illustrations
│   └── browser-extension/     # Chrome/Chromium right-click extension
├── scripts/
│   ├── pluck-protocol-handler.sh    # pluck:// URL handler
│   └── install-protocol-handler.sh  # Protocol registration
├── docs/
│   └── IMPLEMENTATION.md      # Implementation details
├── man/
│   ├── pluck.1                # Man page
│   └── gh-install.1           # Legacy man page
├── .github/
│   └── workflows/
│       ├── ci.yml             # CI: test + lint
│       └── publish-pypi.yml   # PyPI publish
├── README.md                  # This file
├── CHANGELOG.md               # Version history
├── CONTRIBUTING.md            # Developer guide
├── LICENSE                    # MIT License
├── Dockerfile                 # Container image
├── pyproject.toml             # Package config
├── .pre-commit-config.yaml    # Pre-commit hooks
├── .gitignore                 # Git ignore patterns
└── .dockerignore              # Docker ignore patterns

🛠️ Development

# Install dev dependencies
pip install pytest ruff

# Run tests
python -m pytest tests/ -v

# Run linter
ruff check src/ tests/

# Install pre-commit hooks
pip install pre-commit
pre-commit install

Test Coverage

111 tests passing across 24 test classes:
├── TestParseRepoUrl (22 tests)
├── TestGistUrl (7 tests) — includes GitLab snippets
├── TestDetectInstallMethod (17 tests)
├── TestSharedPaths (2 tests)
├── TestValidMethods (2 tests)
├── TestSanitizeRepoName (4 tests)
├── TestIsExecutable (6 tests)
├── TestGetDiskSize (3 tests)
├── TestParseArgs (10 tests)
├── TestDryRun (1 test)
├── TestRegistryOperations (3 tests)
├── TestUpdateApp (2 tests)
├── TestInfoApp (2 tests)
├── TestDoctor (2 tests)
├── TestConfigCommand (2 tests)
├── TestExportImport (4 tests)
├── TestVerifyApps (3 tests)
├── TestStatsCommand (2 tests)
├── TestFormatBytes (5 tests)
├── TestExtractGlobalFlags (5 tests)
└── TestDownloadAndInstallMocked (4 tests)

📄 License

This project is licensed under the MIT License — see the LICENSE file for details.

🤝 Contributing

Contributions are welcome! Please read the Contributing Guide for details on our code of conduct and the process for submitting pull requests.


Made with ❤️ for non-technical users everywhere

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pluck_cli-0.1.0.tar.gz (30.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pluck_cli-0.1.0-py3-none-any.whl (20.4 kB view details)

Uploaded Python 3

File details

Details for the file pluck_cli-0.1.0.tar.gz.

File metadata

  • Download URL: pluck_cli-0.1.0.tar.gz
  • Upload date:
  • Size: 30.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for pluck_cli-0.1.0.tar.gz
Algorithm Hash digest
SHA256 039f0f755839624c3754ea7e3d933b2b3c6c2a826d55fa70c5ada37b70448f2e
MD5 4db25ae5376cfd229a72b4de88eb646c
BLAKE2b-256 b3278065fa93dfa21ab0f7135cf1058ccecad1ee7d2dd940e61eed4c28367578

See more details on using hashes here.

File details

Details for the file pluck_cli-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pluck_cli-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 20.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for pluck_cli-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 aef785e5888db3e53df1d01096464816263bccefe2d7ff6b51ac4c31bb175d8d
MD5 93702f15a65bace69e5ba20bbf1e8361
BLAKE2b-256 d9302a6dcf460cb1a01d9e9737877b986505e60a6ad2373bf0128a6699533f1a

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page