# CLI GNOME Extension Manager πŸš€ [![GitHub Sponsors](https://img.shields.io/badge/Sponsor-GitHub%20Sponsors-blue?logo=github)](https://github.com/sponsors/kevinveenbirkenbach) [![Patreon](https://img.shields.io/badge/Support-Patreon-orange?logo=patreon)](https://www.patreon.com/c/kevinveenbirkenbach) [![Buy Me a Coffee](https://img.shields.io/badge/Buy%20me%20a%20Coffee-Funding-yellow?logo=buymeacoffee)](https://buymeacoffee.com/kevinveenbirkenbach) [![PayPal](https://img.shields.io/badge/Donate-PayPal-blue?logo=paypal)](https://s.veen.world/paypaldonate) [![License: AGPL v3](https://img.shields.io/badge/License-AGPL%20v3-blue.svg)](./LICENSE) [![Python Version](https://img.shields.io/badge/Python-3.10%2B-blue.svg)](https://www.python.org) [![GitHub stars](https://img.shields.io/github/stars/kevinveenbirkenbach/cli-gnome-extension-manager.svg?style=social)](https://github.com/kevinveenbirkenbach/cli-gnome-extension-manager/stargazers) Manage your GNOME extensions easily from the command line with **CLI GNOME Extension Manager**. This Python CLI lets you install, update, enable, and disable GNOME extensions directly from your terminal. ## How it works 🧭 ```mermaid flowchart TD A["cli-gnome-extension-manager ACTION NAME [REPO]"] --> B{"action"} B -- disable --> C["gnome-extensions disable"] B -- enable --> D{"REPO argument given?"} D -- no --> H["gnome-extensions enable"] D -- yes --> E{"extension folder already there?"} E -- no --> F["git clone into the extensions dir"] E -- yes --> G{"is it a git checkout?"} G -- yes --> G1["git pull"] G -- no --> G2["leave it untouched"] F --> I{"ships a Makefile?"} G1 --> I G2 --> I I -- yes --> J["move to a scratch dir, make install, drop the scratch dir"] I -- no --> H J --> H C --> Z["Installation complete"] H --> Z ``` Any failing step - `git`, `make` or `gnome-extensions` - stops the run and its exit code is passed through. ## Features ✨ - **Install & Update**: Clone extension repositories and update them if already installed. - **Compile**: Automatically compile the extension if a Makefile is provided. - **Activate/Deactivate**: Enable or disable GNOME extensions easily using the CLI. - **Automation-Friendly**: Perfect for power users and automation scripts. ## Requirements πŸ”§ - **Python 3.10+** 🐍 - **GNOME Shell** (version 3.36+) - **`gnome-extensions`** on `PATH` β€” always required - **`git`** on `PATH` β€” only when a repository argument is given - **`make`** on `PATH` β€” only when the extension ships a `Makefile` If a required command is missing, the tool exits with code `127` and a one‑line error instead of a traceback. ## Installation πŸ“¦ ```bash pip install cli-gnome-extension-manager ``` pip is the single supported installation path. The package installs **two** identical commands: `cli-gnome-extension-manager` (primary) and `goexma` (kept for older documentation and scripts). ## Usage βš™οΈ To **install and enable** an extension, run: ```bash cli-gnome-extension-manager enable ``` To **enable** an already installed extension, drop the repository argument: ```bash cli-gnome-extension-manager enable ``` To **disable** an extension, run: ```bash cli-gnome-extension-manager disable ``` The tool will: - Clone the repository if the extension isn't installed. - Pull updates if the extension is already a Git repository. - Compile the extension if a Makefile is present β€” the checkout is moved into a scratch directory, `make install` runs there, and the scratch directory is removed afterwards. - Enable or disable the extension using `gnome-extensions`. Extensions live in `~/.local/share/gnome-shell/extensions` by default; `--extensions-dir` points the tool elsewhere. ### Exit codes | Code | Meaning | | --- | --- | | `0` | Finished. | | `2` | Invalid command line arguments, including an action other than `enable` or `disable`. | | `127` | A required command is not installed. | | other | The exit code of the failing `git`, `make` or `gnome-extensions` call. | ## Development πŸ§ͺ ```bash make lint # ruff check + ruff format --check make format # apply ruff format make test # unit + integration tests make test-unit make test-integration make test-e2e # install the package in a container and exercise the CLI ``` Tests run against the working tree β€” the `Makefile` puts `src/` on `PYTHONPATH`, so no install is needed. The integration tests build a real throwaway git repository and stub `gnome-extensions` on `PATH`, so no extension of yours is ever touched. ## License πŸ“œ This project is licensed under the GNU Affero General Public License v3.0. See the [LICENSE](./LICENSE) file for details. ## Author πŸ‘¨β€πŸ’» Developed by **Kevin Veen-Birkenbach** - πŸ“§ [kevin@veen.world](mailto:kevin@veen.world) - 🌐 [https://www.veen.world/](https://www.veen.world/) --- Feel free to contribute, open issues, or suggest improvements. Enjoy managing your GNOME extensions effortlessly! 🌟