shellx

shellx: the (almost) shell-independent plugin manager

ZSH/BASH or any other shell has their own plugin managers and configuration managers which, for me:

A minimal example could be, installing pyenv, it will require to enables it on the session that you want to use, in a minimal scenario, include these lines in .bashrc and .zshrc.

Initially i was using a generic shell file and just including a source of that file which do all of this, and was working fine, but i found that:

So, i have ended, which probably could be called a generic script/plugin loader. It doesn’t do anything special at all but allows me:

Requirements

ShellX requires Bash 4.0+ or Zsh 4.0+ for full functionality. For detailed information about shell compatibility and supported shells, see SHELL_COMPATIBILITY.md.

Use it

Clone this repo to your disk

git clone https://github.com/0ghny/shellx ~/.shellx

Once cloned, modify your .zshrc or .bashrc or any *rc from a compatible shell to start shellx bootstrap with your shell. Below, an example to use it with ZSHell (add lines to end of your .zshrc file)

[[ -f ~/.shellx/shellx.sh ]] && source ~/.shellx/shellx.sh

Once you starts a new shell (or exec zsh to start a new one) you can check ShellX is in action with the shellx init output

ShellX initalised for oghny in Hostname
Session information:
  Started at 20 hr 10 min 34 sec
  Loaded in: 00 hr 00 min 01 sec
Libraries:
    [*] colors.sh           [*] io.sh               [*] stopwatch.sh        [*] user.sh             [*] debug.sh            [*] plugins.sh
    [*] command.sh          [*] path.sh             [*] sysinfo.sh          [*] cli.sh              [*] feature.sh          [*] session.sh
    [*] env.sh              [*] shell.sh            [*] time.sh             [*] config.sh           [*] log.sh              [*] update.sh
Plugins:
  Applied filter: @all
  Packages:
    [*] [@plugins] ~/.shellx/plugins
  Loaded:
    [*] @plugins/shellx_update.sh                                   [*] @plugins/wellcome.sh

Wellcome is the bundled plugin as of demo purposes and shellx_update is the one that enables AUTO_UPDATE feature.

Default features

Shellx CLI

Shellx once initialized, has his own CLI to make easier to interact with shellx functionalities, below you will find the same output as shellx help

MANAGE SESSION
-----------------------------------------------------------------------------
shellx list                             List loaded plugins in current session
shellx status                           Display current session information
                                        (start time, load time, plugins, etc)
shellx reset                            Resets current shell session
                                        it does a /bin/zsh reset or exec /bin/zsh
shellx reload                           Reload plugins and configuration at once
shellx info                             Print Shell,OS and Host information
                                        current session info
                                        (start time, load time, plugins, etc)

MANAGE VERSION
-----------------------------------------------------------------------------
shellx version                          Prints current ShellX version
shellx version info                     Prints version with release notes
shellx version notes [N]                Prints last N release notes (default: 3)
shellx version check                    Checks if a new version is available
shellx self-update                      Updates ShellX to latest release
shellx check-update                     Shows update availability and changelog

TOOLS
-----------------------------------------------------------------------------
shellx debug enabled                    Enabled shellx debug output to stdout
shellx debug disabled                   Disable shellx debug output to stdout

CONFIGURATION
-----------------------------------------------------------------------------
shellx config print                     Print config file contents
shellx config runtime                   Print active SHELLX_* session variables
shellx config set <KEY> <VALUE>         Set a configuration key
shellx config unset <KEY>               Remove a configuration key
shellx config reload                    Reload configuration from file

MANAGE PLUGINS
-----------------------------------------------------------------------------
shellx plugins list                     List available plugin packages
                                        from configured repositories
shellx plugins install <name|url>       Install plugin by package name
                                        or direct git URL
shellx plugins installed                List installed plugin packages
shellx plugins uninstall <name>         Uninstall the specified plugin package
shellx plugins update <name>            Update an installed plugin (git pull)
shellx plugins reload                   Reload plugins into current session

**NEW in v2.0+**: Plugin Registry System
  - Install plugins by name instead of full URL
  - Browse available packages with `shellx plugins list`
  - See [Plugin Registry System](#plugin-registry-system) section for details

Note: All CLI commands under the hood calls to a shellx shell function in the form of shellx::<namespace>::<function> <parameters>. Below in this documentation you will find some internal library functions that can be used, and can be translated of invoked using this cli even if it’s not documented in this help. You just need to follow this convention, as example:

# Gets the full path for shellx-community-plugins package
$ shellx::plugins::path shellx-community-plugins
~/.shellx.plugins.d/shellx-community-plugins

# The same using shellx cli
shellx plugins path shellx-community-plugins
~/.shellx.plugins.d/shellx-community-plugins

Configuration Options

ShellX can be customized in behaviour using a configuration file which can be located in different places (in order or priority):

This file is loaded at bootstrapping time, so it’s useful to avoid having to export variables before starting shellx in your shell session.

Current configuration options are:

KEY DESCRIPTION
SHELLX_CONFIG If you wanna specify an specific location for your shellx configuration file
SHELLX_PLUGINS_D By default it’s HOME/.shellx.plugins.d but in case you wanna set another special location for searching for external plugins directory, you can use this variable
SHELLX_NO_BANNER If declared with any value, summary banner that contains session information, plugins loaded, etc. won’t be displayed
SHELLX_DEBUG If declared with any value, debug mode is enabled, lot’s of output in your console
SHELLX_PLUGINS By default value is @all which means all plugins, it controls the plugin loading feature, you can read more about it in this documentation in Selective plugin loading section
SHELLX_HOME If you wanna move shellx to another location, you can set that location in this variable, by default it will use the place where the shellx.sh script is.

Reload configuration from the CLI

Now you can reload configuration from file in your current environment session just running

$ shellx config reload
$ shellx config print
SHELLX_NO_BANNER=yes
SHELLX_PATH_BACKUP=....
SHELLX_DEBUG=           # <- it means disabled

Bundled session variables

When shellx is bootstrapped, there’s some variables that can be used inside the session that belongs to shellx, it’s quite important that you don’t modify them if you don’t want unexpected behaviours, but sometimes could be useful to use them in your scripts

NAME DESCRIPTION
__shellx_plugins_loaded array with list of loaded plugins by name
__shellx_homedir home directory for shellx installation
__shellx_bindir shellx installation bin directory
__shellx_libdir shellx installation lib directory
__shellx_plugins_d shellx extended plugins directory
__shellx_pluginsdir shellx installation bundled plugins directory

Bundled library of functions

Shellx includes and load a library of functions that can be used inside any plugin but also from your shell session

LIB FUNC NAME DESCRIPTION
command command::get_type returns the type (as string) of a command by name, like “command,alias,function,builtin”
command command::exists returns true if specified command exists as command,alias or function
env env::export export a variable with a value
env env::is_defined checks if a variable is already defined, returns true or false
io io::exists returns true if the path (file or directory) exists, false if not
path path::add adds a new path to the PATH variable (if not already added)
path path::exists checks if a path is already in PATH variable
path path::export alias of path::add with a different implementation
path path::backup backups current PATH content into a variable (default PATH_BAK)
shell shell::alias_exists checks if an alias is already defined, returns 0 if exists, 1 if not (POSIX-compatible)
stopwatch stopwatch::capture returns the current date to use in stopwatch::elapsed operation
stopwatch stopwatch::elapsed elapsed time between startdate and enddate
sysinfo env::arch returns os architecture (386, amd64, arm, unknown)
sysinfo env::platform returns os platform (linux, darwin, unknown)
sysinfo env::uptime human readable and cross-os uptime
time time::to_human_readable from elapsed to human readable
user user::current returns the name of the current user

Community plugins

Community Plugins repo

to installs them, or any other repository with plugins:

git clone https://github.com/0ghny/shellx-community-plugins ~/.shellx.plugins.d/shellx-community-plugins
# then, just restart your shell (e.g: exec zsh)

Plugins Management

Shellx offer different functions that allows you to install/uninstall plugins created using ShellX Plugin Framework guidelines (read in sections below). Remember that by default all plugin commands operates with SHELLX_PLUGINS_D variable, which is the directory that contains plugins installed.

CLI LIB FUNC NAME DESCRIPTION
shellx plugins install shellx/plugins shellx::plugins::install with a git repository as parameter installs the plugin and reload plugins
shellx plugins uninstall shellx/plugins shellx::plugins::uninstall with a plugin name as parameter uninstall the plugin from your shellx installation
shellx plugins installed shellx/plugins shellx::plugins::installed prints current installed plugins and their location
  shellx/plugins shellx::plugins::is_installed with plugin name as parameter returns true or false if plugins is installed
shellx plugins loaded shellx/plugins shellx::plugins::loaded prints current loaded plugins into shellx
shellx plugins reload shellx/plugins shellx::plugins::reload reload all plugins
shellx plugins update shellx/plugins shellx::plugins::update update specified plugin by name, or all plugins installed

Get current installed plugins

$ shellx installed
Plugins Installed:
  [*] plugins (~/.shellx/plugins)
  [*] shellx-community-plugins (~/.shellx.plugins.d/shellx-community-plugins)
  [*] shellx-plugins-arch (~/.shellx.plugins.d/shellx-plugins-arch)

Installing a plugin

Next example installs shellx-plugins-arch which contains plugins for arch linux

$ shellx install https://github.com/0ghny/shellx-plugins-arch
[PLUGIN] Cloning plugin into shellx plugins directory... OK
[PLUGIN] Reloading plugins...

Uninstalling a plugin

Next example uninstall shellx-plugins-arch plugin

$ shellx uninstall shellx-plugins-arch
[PLUGIN] shellx-plugins-arch uninstalling... OK

Updating Plugins (or a single Plugin)

$ shellx plugins update [PLUGIN_NAME]
  where PLUGIN_NAME is an optional parameter with one of the plugin names.

  If provided, it should be an existing installed plugin name, to retrieve list of plugins installed you can execute
    shellx plugins installed
  and pick a proper name.

  If not provided it will try to update ALL plugins.

  The update method is using git pull under plugin directory, it will check also if directory contains a .git directory.

To update our shellx-plugins-arch plugin

$ shellx plugins update shellx-plugins-arch
[+] Updating shellx-plugins-arch... OK

Selective plugins loading

The core of shellx is to be able to add or remove functionality by plugins. Some or the allready existing community plugins are ready to skip their functionality if as example the tool is not present into the system. If dotnet is not installed, doesn’t makes sense to export the OPTOUT variables to disable telemetry.

But, even doing this, as much plugins you have, in some way, slower the bootstrap process will be.

To avoid this, shellx offer a selective plugin feature, that, as default is load all plugins. But, remember that all bundled plugins will be always loaded.

This configuration is done using the previously defined SHELLX_PLUGINS configuration property, which is an array that contains the plugins to be loaded. BUT, since a plugin can be named the same in different locations, we have offer different ways of specify what to load.

Some examples:

# Loads all plugins, in this case variable can be defined in this way, or not be defined
SHELLX_PLUGINS=( @all )

# Load all community plugins only (+ bundled)
SHELLX_PLUGINS=( @shellx-community-plugins )

# Load asdf from community plugins + custom cloned plugins repo in a folder called shellx-my-plugins
SHELLX_PLUGINS=( @shellx-community-plugins/asdf @shellx-my-plugins )

# Load just plugins with names asdf,pyenv,minikube, in ALL locations
SHELLX_PLUGINS=( asdf pyenv minikube )

Plugin framework Guidelines

Plugins may use all internal variables and functions bundled in ShellX (in fact, they are declared in session so, you can access to them from your shell anytime).

Specific plugin configuration

When you’re developing or using a plugin you may want to define certain “variables” that can affect to the plugin behaviour, like, as example, determine if you want to download a binary for a tool or not in case that doesn’t exists on the system.

This is done using Feature Flags inside your plugin, basically you can use any variable named that you want, and the user can include that configuration in ShellX configuration file or exporting them into the shell before bootstrapping shellx, BUT, we recommend to follow (as we do) a naming pattern for those variables. Following our previous example, imagine a plugin that will install minikube in case it’s not present into the system, you may create a variable called SHELLX_PLUGIN_MINIKUBE_INSTALL_IF_NOT_PRESENT or SHELLX_PLUGIN_MINIKUBE_INSTALL so basically SHELLX_PLUGIN_MINIKUBE_ will be the prefix for your plugin variables. We do this to avoid conflicts with other tools or other plugins (even if this is almost impossible to ensure 100%), some people don’t like LONG variable names, but, sometimes could be necessary.

Extend with plugins

You can see some examples in folder plugin-examples or take a look or use Community Plugins repo.

Create your own repository with your plugins and clone them inside SHELLX_PLUGINS_D directory (usually ~/.shellx.plugins.d/folder_name).

Some ideas for plugins:

Debugging ShellX

Shellx offers some internal logging mechanishm that may help to understand what’s happening behind a command or operation. Debug can be enabled in two ways:

if you have it declared in shellxrc file you will see lot of outputs everytime you start a shell, that’s why it’s not recommented.

If you want to debug the shellx initialization process it’s better to do:

$ shellx debug enable
$ shellx reset
....
... lot of output
....

... once you finish debugging
$ shellx debug disable

Plugin Registry System

ShellX includes a Plugin Registry System that enables easy plugin discovery and installation. Instead of remembering full GitHub URLs, users can install plugins by simple names from registered repositories.

Quick Start

# List available plugin packages
shellx plugins list

# Install by package name (much simpler!)
shellx plugins install community

# Still works with direct URLs
shellx plugins install https://github.com/user/my-plugin.git

Registry File

The plugin registry is located at: plugins.repositories (in ShellX root directory)

Format: NAME|URL|DESCRIPTION

community|https://github.com/0ghny/shellx-community-plugins|Community-supported plugins
examples|https://github.com/0ghny/shellx-plugin-examples|Plugin examples and templates
enterprise|https://github.com/0ghny/shellx-enterprise-plugins|Enterprise-grade plugins

Registry Configuration

Priority order for registry file location:

  1. Environment variable: SHELLX_PLUGINS_REGISTRY (if set)
  2. User config: ~/.config/shellx/plugins.repositories
  3. Repository root: plugins.repositories
  4. Bundled: lib/shellx/plugins.repositories (backwards compatibility)

Plugin Management Commands

Command Description
shellx plugins list List all available plugin packages from registered repositories
shellx plugins add <name> <url> [description] Add a custom plugin repository
shellx plugins repositories List all configured plugin repositories
shellx plugins install <name\|url> Install plugin by package name or direct git URL
shellx plugins installed List installed plugin packages
shellx plugins uninstall <plugin_name> Uninstall a specific plugin
shellx plugins update [plugin_name] Update installed plugins or specific plugin
shellx plugins reload Reload all plugins in current session

Managing Custom Repositories

Add your own plugin repository:

# Add custom repository
shellx plugins add myrepo https://github.com/me/my-plugins "My personal plugins"

# Now you can install from it
shellx plugins install myrepo

This creates ~/.config/shellx/plugins.repositories extending the default registry.

For Plugin Authors

To publish your plugins for ShellX:

  1. Create a repository with this structure:
    my-awesome-plugins/
    ├── plugins/
    │   ├── 00-first-plugin.sh
    │   ├── 10-second-plugin.sh
    │   └── README.md
    └── README.md
    
  2. Request registration by opening an issue on the ShellX repository

  3. Once approved, users can install with:
    shellx plugins install your-package-name
    

Usage Examples

Install from official repositories:

# Install community plugins
shellx plugins install community

# Install plugin examples
shellx plugins install examples

Direct URL (backward compatible):

# Old way still works
shellx plugins install https://github.com/0ghny/shellx-community-plugins.git

Provision new systems:

# In your ~/.shellxrc or setup script
eval "$(shellx plugins list | grep community)" && \
  shellx plugins install community

Environment Variables

Variable Description
SHELLX_PLUGINS_REGISTRY Path to custom registry file (overrides default lookup)
SHELLX_CONFIG_DIR Base directory for user config files (default: .config/shellx)