{"id":13506433,"url":"https://github.com/pearl-core/pearl","last_synced_at":"2025-04-05T11:08:18.406Z","repository":{"id":53120134,"uuid":"55340666","full_name":"pearl-core/pearl","owner":"pearl-core","description":"Pearl is a lightweight package manager for automating reproducible environments between different systems (Linux and OSX). It can be used for dotfiles, plugins, programs and any form of code accessible via git.","archived":false,"fork":false,"pushed_at":"2024-03-23T16:55:50.000Z","size":648,"stargazers_count":230,"open_issues_count":15,"forks_count":24,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-29T10:08:01.820Z","etag":null,"topics":["ansible","configuration-management","dotfiles","dotfiles-manager","hook-functions","linux","osx","package-manager","python","shell"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pearl-core.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":"AUTHORS.md","dei":null},"funding":{"github":"fsquillace","custom":"https://github.com/pearl/pearl-core/blob/master/README.md#donating"}},"created_at":"2016-04-03T10:15:29.000Z","updated_at":"2025-03-26T23:04:11.000Z","dependencies_parsed_at":"2023-01-29T20:01:04.010Z","dependency_job_id":"f279e0cc-460d-4116-b02e-39604f41321c","html_url":"https://github.com/pearl-core/pearl","commit_stats":{"total_commits":134,"total_committers":3,"mean_commits":"44.666666666666664","dds":0.3955223880597015,"last_synced_commit":"e504230af24dd8daf346d9b11f57822de2d5884a"},"previous_names":[],"tags_count":46,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pearl-core%2Fpearl","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pearl-core%2Fpearl/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pearl-core%2Fpearl/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pearl-core%2Fpearl/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pearl-core","download_url":"https://codeload.github.com/pearl-core/pearl/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247325693,"owners_count":20920714,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ansible","configuration-management","dotfiles","dotfiles-manager","hook-functions","linux","osx","package-manager","python","shell"],"created_at":"2024-08-01T01:00:49.440Z","updated_at":"2025-04-05T11:08:18.381Z","avatar_url":"https://github.com/pearl-core.png","language":"Python","funding_links":["https://github.com/sponsors/fsquillace","https://github.com/pearl/pearl-core/blob/master/README.md#donating","https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=8LEHQKBCYTACY","https://github.com/sponsors/fsquillace/"],"categories":["Repositories","Python","ansible","Tools"],"sub_categories":["Ansible"],"readme":"Pearl\n=====\n\n\u003ch1 align=\"center\"\u003e\n    \u003ca href=\"https://github.com/pearl-core/pearl\"\u003e\u003cimg\n        alt=\"Pearl\"\n        width=250px\n        src=\"https://rawgit.com/pearl-core/logo/master/pearl.png\"\u003e\u003c/a\u003e\n\u003c/h1\u003e\n\n|Project Status|Donation|Communication|\n|:-----------:|:--------:|:-----------:|\n|[![Build status](https://api.travis-ci.com/pearl-core/pearl.png?branch=master)](https://travis-ci.com/github/pearl-core/pearl) [![PyPi version](https://img.shields.io/pypi/v/pearl)](https://pypi.org/project/pearl/) [![PyPi status](https://img.shields.io/pypi/status/pearl)](https://pypi.org/project/pearl/) | [![Github Sponsors](https://img.shields.io/badge/GitHub-Sponsors-orange.svg)](https://github.com/sponsors/fsquillace) [![PayPal](https://img.shields.io/badge/PayPal-Donation-blue.svg)](https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick\u0026hosted_button_id=8LEHQKBCYTACY) | [![Join the gitter chat at https://gitter.im/pearl-core/pearl](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/pearl-core/pearl?utm_source=badge\u0026utm_medium=badge\u0026utm_campaign=pr-badge\u0026utm_content=badge) |\n\n**Table of Contents**\n- [Description](#description)\n- [Quickstart](#quickstart)\n- [Installation](#installation)\n  - [Dependencies](#dependencies)\n  - [Linux](#linux)\n  - [OSX](#osx)\n- [Create your own Pearl package](#create-your-own-pearl-package)\n- [Create your own Pearl repository](#create-your-own-pearl-repository)\n- [Comparison with alternative solutions](#comparison-with-alternative-solutions)\n- [Troubleshooting](#troubleshooting)\n- [Contributing](#contributing)\n- [Donating](#donating)\n- [Authors](#authors)\n\nDescription\n===========\n**Pearl** is a lightweight package manager for automating reproducible environments\nbetween different systems (Linux and OSX).\nIt can be used for dotfiles, plugins, programs and any form of code\naccessible via git.\n\nAs soon as a package gets installed, its content can be activated out of the box\naccording to certain events, like, for instance, a shell startup (Bash, Zsh or Fish) or\nan editor startup (Vim or Emacs). This is possible via a smart and simple\n[hook mechanism](#create-your-own-pearl-package)\nthat integrates the package content within the Pearl ecosystem.\n\nThe main advantages on using Pearl are:\n\n- Create your own Pearl package in a very simple way.\n- Full control and sync of your dotfiles across different systems.\n- Automatic bootstrap of the package content whenever shells or editors get started.\n- Access to a wide range of existing packages via the [OPH (Official Pearl Hub)](https://github.com/pearl-hub).\n- Allows to create your own shareable package repository.\n- [Comparison](#comparison-with-alternative-solutions) with alternative solutions\n- Stable codebase with 100+ unit tests and exhaustive integration tests via [Travis](https://travis-ci.org/pearl-core/pearl) for Linux and OSX.\n- Small number of [dependencies](#dependencies) needed in order to ensure compatibility with most of the systems.\n\nQuickstart\n==========\nThere are two main use cases for Pearl which will be explained here below:\n\nUse case 1: Create custom package\n---------------------\nThe following example creates a Pearl package containing\na `git` dotfile and a simple executable available as soon\nas the package gets installed.\n\n```sh\n$\u003e pearl create mydotfiles ~/dotfiles\n```\nThis will create a directory `pearl-config` in `~/dotfiles`\ncontaining all the templates to help you\nstart writing a Pearl package. `~/dotfiles` does not need to be an empty directory.\n\nAdditionally, the local repository in `$XDG_CONFIG_HOME/pearl/pearl.conf` (defaults to `~/.config/pearl/pearl.conf`)\nwill be updated with the new package entry called `mydotfiles`.\nThis tells to Pearl where to look for the package:\n\n```sh\n$\u003e cat ~/.config/pearl/pearl.conf\n...\n...\nPEARL_PACKAGES[\"mydotfiles\"] = {\"url\": \"~/dotfiles\"}\n```\n\nPlace the git config inside `~/dotfiles` directory:\n\n```sh\n$\u003e cd ~/dotfiles\n$\u003e echo -e \"[alias]\\n    cfg = config\" \u003e gitconfig\n$\u003e echo -e \"#!/bin/bash\\necho Hello World!\" \u003e hello\n$\u003e chmod +x hello\n```\n\nYou need now to give instructions about how to link the `gitconfig` file into the system and make the executable available in `PATH`.\nThis is possible through the `pearl-config/hooks.sh` file. Just update it with the following:\n\n```bash\npost_install() {\n    link git \"${PEARL_PKGDIR}/gitconfig\"\n    link_to_path \"${PEARL_PKGDIR}/hello\"\n    return 0\n}\n\npost_update() {\n    post_install\n}\n\npre_remove() {\n    unlink git \"${PEARL_PKGDIR}/gitconfig\"\n    unlink_from_path \"${PEARL_PKGDIR}/hello\"\n    return 0\n}\n```\n\nThis tells to Pearl to `link` the git config located in `\"${PEARL_PKGDIR}/gitconfig\"` (`${PEARL_PKGDIR}` is a builtin variable)\nto the `git` program just after the package installation.\nAlso, `hooks.sh` will link the executable `hello` by creating\na symlink and make it visible to `PATH` env variable.\nConversely, before removal, the hooks file tells to\n`unlink` the git config file and remove the symlink.\n\nNow, just install the package and you will see the changes already reflected:\n\n```sh\n$\u003e pearl install mydotfiles\n$\u003e git cfg -l\n...\n...\n$\u003e hello\nHello World!\n```\n\nOnce the package is completed, you can upload it to a git repository and\njust fetch it from there by updating `~/.config/pearl/pearl.conf`:\n```sh\n$\u003e cat ~/.config/pearl/pearl.conf\n...\n...\nPEARL_PACKAGES[\"mydotfiles\"] = {\"url\": \"https://github.com/pearluser/mydotfiles.git\"}\n```\n\nThere are way more things you can do with Pearl!\nFor more details about the `pearl-config` content, look at the [section](#create-your-own-pearl-package) below.\n\nUse case 2: Use Pearl Hub repository\n------------------------\nYou can just use existing packages from the Pearl Hub repository.\nIt contains a big list of packages about dotfiles, programs and plugins for many known applications.\n\nFor instance, look to the entire list of packages:\n\n```sh\n$\u003e pearl list\n```\n\nIf interested to search only for dotfiles:\n\n```sh\n$\u003e pearl search dotfiles\npearl/dot-gtk \n    Awesome gtk dotfiles\npearl/kyrat \n    20 lines script that brings dotfiles in a ssh session\npearl/dot-mutt \n    Awesome Mutt dotfiles\npearl/dot-emacs \n    Awesome emacs dotfiles\npearl/dot-git \n    Awesome git dotfiles\npearl/dot-screen \n    Awesome screen dotfiles\npearl/dot-tmux\n    Awesome Tmux dotfiles\npearl/dot-vim\n    Awesome vim dotfiles\npearl/dot-firefox\n    Awesome Firefox dotfiles\npearl/dot-terms\n    Awesome terms dotfiles (i.e. urxvt)\npearl/dot-bash\n    Awesome bash dotfiles\n```\n\n### Recommended Pearl Hub packages to install:\n\n- [cmd](https://github.com/pearl-hub/cmd)\n- [kyrat](https://github.com/pearl-hub/kyrat)\n- [ranger](https://github.com/pearl-hub/ranger)\n- [sesaila](https://github.com/pearl-hub/sesaila)\n- [trash-cli](https://github.com/pearl-hub/trash-cli)\n- [txum](https://github.com/pearl-hub/txum)\n\nInstallation\n============\n\nDependencies\n------------\nBefore installing Pearl be sure that all dependencies are properly installed in your system.\nThe Pearl dependencies are the following:\n\n### Mandatory\n- [python (\u003e=3.7)](https://www.python.org/)\n- [bash (\u003e=4.1)](https://www.gnu.org/software/bash/)\n- [git (\u003e=1.8.5)](https://git-scm.com/)\n\n**PLEASE NOTE**: Tests may be performed on different versions from the ones listed above.\nTo know which versions are truly tested have a look at latest Travis executions [here](https://travis-ci.com/pearl-core/pearl).\n\n### Optional\nThe following are not mandatory dependencies but can be handy to have for the hook functions in Pearl package.\nAll the Linux distributions have these dependencies already installed.\n\n- [GNU coreutils](https://www.gnu.org/software/coreutils/)\n- [grep](https://www.gnu.org/software/grep/) \n- [sed](https://www.gnu.org/software/sed/) \n\n### Shells supported\nPearl supports the following shells:\n\n- [bash (\u003e=4.1)](https://www.gnu.org/software/bash/)\n- [fish (\u003e=2.2.0)](https://fishshell.com/)\n- [zsh (\u003e=5.2)](http://www.zsh.org/)\n\n**PLEASE NOTE**: Tests may be performed on different versions from the ones listed above.\nTo know which versions are truly tested have a look at latest Travis executions [here](https://travis-ci.com/pearl-core/pearl).\n\nLinux\n-----\n\n### Arch Linux\n\nPearl can be installed in Arch Linux through AUR.\nThe package is [pearl-git](https://aur.archlinux.org/packages/pearl-git/).\n\nFor example, to install Pearl via [yay](https://github.com/Jguer/yay) AUR helper:\n```\n$\u003e yay -S pearl-git\n```\n\nAny other AUR helpers can be found [here](https://wiki.archlinux.org/index.php/AUR_helpers).\n\n### Other Linux distributions\n\nAssuming all Pearl [dependencies](#dependencies) are properly installed\nin the system, to install Pearl you can use the `pip` command:\n\n```\n$\u003e sudo python3 -m pip install pearl\n$\u003e pearl init\n```\n\nMake sure to update `PATH` environment variable if needed\n(`pearl` is typically located to `/usr/bin`).\nThe idempotent `init` command will create the `$PEARL_HOME` directory and\nthe new pearl configuration files from template.\n\nOSX\n---\nIn order to install all Pearl dependencies, you first need to install [Homebrew](http://brew.sh/).\n\nTo install all the needed dependencies via Homebrew:\n```sh\n$\u003e brew update\n$\u003e brew install bash git coreutils grep gnu-sed python\n```\n\nTo install Pearl you can use the `pip` command:\n```sh\n$\u003e pip3 install pearl\n$\u003e pearl init\n```\n\nMake sure to update `PATH` environment variable if needed\n(`pearl` is typically located to `/usr/bin`).\nThe idempotent `init` command will create the `$PEARL_HOME` directory and\nthe new pearl configuration files from template.\n\n**IMPORTANT NOTE**: Pearl gets loaded through `~/.bashrc`. The problem is that in OSX,\nthe terminal opens a login shell and only `~/.bash_profile` will get executed.\nRun the following only if `~/.bashrc` is not loaded within `~/.bash_profile` file:\n\n```sh\n$\u003e echo \"[[ -f $HOME/.bashrc ]] \u0026\u0026 source $HOME/.bashrc\" \u003e\u003e ~/.bash_profile\n```\n\nThis will make sure that `~/.bashrc` will run at shell startup.\n\nCreate your own Pearl package\n===============\n**Any git repository is already a Pearl package**. For instance, in order\nto manage a dotfiles repository in Pearl, you just need to change\nthe Pearl configuration file located in `$XDG_CONFIG_HOME/pearl/pearl.conf`.\n\nAdd the following line to `pearl.conf` file:\n\n```python\nPEARL_PACKAGES = {\n    \"mydotfiles\": {\n        \"url\": \"https://github.com/user/mydotfiles.git\",\n        \"description\": \"My dotfiles\"\n    },\n}\n```\n\nIn other words, update the `PEARL_PACKAGES` dictionary with a new entry containing the\nname of the package (i.e. `mydotfiles`),\nthe git url (i.e. `https://github.com/user/mydotfiles.git`) and an optional description.\n\n***That's it!*** The package will be ready to be managed by the Pearl system.\n\n## Structure of a Pearl package ##\nYour own git repository can contain an **optional** directory\nnamed `pearl-config` used by Pearl to integrate the package with the Pearl environment.\n\n    / (package root)\n    │\n    ├── pearl-config (optional directory)\n    │   │\n    │   ├── hooks.sh\n    │   ├── config.sh\n    │   ├── config.bash\n    │   ├── config.zsh\n    │   ├── config.fish\n    │   ├── config.vim\n    │   ├── config.el\n    │   └── package.conf\n    │\n    └── (additional package content)\n\nThe files inside `pearl-config` are also **optional** script/configuration files:\n\n- `hooks.sh` - contains the [hooks functions](#hook-functions) executed during the `install`, `update` and `remove` events.\n- `config.sh` - will be sourced whenever a new Bash/Zsh shell is starting up.\n- `config.bash` - will be sourced whenever a new Bash shell is starting up.\n- `config.zsh` - will be sourced whenever a new Zsh shell is starting up.\n- `config.fish` - will be sourced whenever a new Fish shell is starting up.\n- `config.vim` - will be executed whenever Vim editor is starting up.\n- `config.el` - will be sourced whenever Emacs editor is starting up.\n- `package.conf` - contains optional metadata information (name, author, description, keywords, etc) about the package that are useful when indexing the package in a repository list.\n\nThe order in which the `config.*` files are sourced among multiple installed packages depends on the closure dependency tree,\nin other words, if package `A` depends on package `B` and both have `config.vim` files, the parent package `B` config file will be sourced first.\n\nThe following variables can be used in any of the previous scripts:\n\n- `PEARL_HOME`          - Pearl location (`$XDG_DATA_HOME/pearl` which by default is `$HOME/.local/share/pearl`)\n- `PEARL_PKGDIR`        - Pearl package location\n- `PEARL_PKGVARDIR`     - Pearl package location containing data needed for package\n- `PEARL_PKGNAME`       - Pearl package name\n- `PEARL_PKGREPONAME`   - Pearl package repo name (useful to detect and interact with packages within the same repo)\n\nAdditionally, the script `hooks.sh` can use the utility functions available in\n[Buava](https://github.com/fsquillace/buava) and Pearl [*utils*](lib/utils) directory that\nmake easier the integration with Pearl ecosystem.\n\nUseful examples of Pearl packages can be checked in the\n[Official Pearl Hub](https://github.com/pearl-hub).\n\n### The hooks.sh script ###\n#### Hook functions ####\n- `post_install`  - Called *after* an installation of the package occurs.\n- `pre_update`    - Called *before* an update of the package occurs.\n- `post_update`   - Called *after* an update of the package occurs.\n- `pre_remove`    - Called *before* a removal of the package occurs.\n\n#### An hooks.sh script example ####\n\n```bash\npost_install() {\n    warn \"Remember to setup your config located in: ~/.dotfile\"\n    # Do a smart backup before modifying the file\n    backup ${HOME}/.dotfile\n    \"# New dotfile\" \u003e ${HOME}/.dotfile\n    if ask \"Are you sure to link the tmux config?\" \"Y\"\n    then\n        link tmux \"$PEARL_PKGDIR/mytmux.conf\"\n    fi\n\n    info \"Awesome - new package installed!\"\n    return 0\n}\npost_update() {\n    post_install\n    return 0\n}\npre_remove() {\n    info \"dotfiles package removed\"\n    unlink tmux \"$PEARL_PKGDIR/mytmux.conf\"\n\n    # Do an idempotent delete\n    delete ${HOME}/.dotfile\n    return 0\n}\n```\n\nThe `info` and `warn` are functions that print a message\nusing different colors (namely cyan and yellow).\n\nThe `link` `unlink` are idempotent functions (the result will not change\nif the function will be called multiple times) that are able\nto link/unlink a config file in order to be loaded at startup by a certain program.\n\nThe `ask` function will make installation interactive, asking user whether to link tmux config or not.\n\nThe `backup` keeps the last three backups of the file and do not perform backup\nif the file has not been modified since the latest backup. The `delete` is a\nfunction for idempotent remove (it will not raise an error if the file\nno longer exist).\n\nAll these functions belong to the [Buava](https://github.com/fsquillace/buava) package\nin [`utils.sh`](https://github.com/fsquillace/buava/blob/master/lib/utils.sh)\nand to the Pearl [`utils.sh`](lib/utils/utils.sh) script. You can use them\ninside the `hooks.sh` to any hook function.\n\n**Very important note**: All the hook functions **must** be\n[**idempotent**](https://en.wikipedia.org/wiki/Idempotence)\n(the commands of each hook function must produce the same result even if\nthe command gets executed multiple times).\nAll buava commands are idempotent and this will help to write hook functions\nvery quickly.\n\n**Note**: For OSX system, the GNU version `sed` and `grep` are automatically\nimported in `hooks.sh` and can be directly used if needed.\n\n### The package.conf file\n`package.conf` is located in `pearl-config` directory and is meant to contain package metadata.\nTo simplify the creation of new packages, this file is completely optional.\nThis file may contain name of the package, description, author, os compatibility, license and more.\nIt can be also used to establish dependencies between packages.\n\nPlease **note** that `package.conf` is only meant to encapsulate package information within the package itself\nbut they are not directly consumed by the Pearl program. In fact, Pearl only reads from the `pearl.conf` file which is\nwhere the metadata information can be also stored.\n\nTo give a better idea, take a look at the Pearl Hub\n[repo.conf](https://github.com/pearl-hub/repo-v2/blob/master/pearl-config/repo.conf).\nThe [repo-builder](https://github.com/pearl-core/repo-builder/) is the script responsible to periodically\nextract the `package.conf` metadata from each package and update the Pearl Hub `repo.conf`.\n\nFor a local package you can manually include such information directly in the `pearl.conf` file. This is an example of\npackage defined in `pearl.conf` which depends on the `pearl/cmd` package:\n\n```python\nPEARL_PACKAGES = {\n    'mydotfiles': {\n        \"url\": '/home/user/my/folder/dotfiles/',\n        \"description\": \"This package contains dotfiles\",\n        \"author\": \"David Smith \u003cdsmith@abc.com\u003e\",\n        \"depends\": (\n            \"pearl/cmd\",\n        )\n    },\n}\n```\n\nIf you do not need such features for your package, just ignore this file.\n\n## Create a Pearl package from a local directory ##\nPearl package system will work even for local directories. This is particularly useful\nwhenever a Pearl package needs to be tested before pushing to a git repository.\n\nFor instance, the following lines in `pearl.conf` file will add a package located in\n`/home/joe/dotfiles`:\n\n```python\nPEARL_PACKAGES = {\n    \"mydotfiles\": {\n        \"url\": \"/home/user/mydotfiles\",\n        \"description\": \"My dotfiles\"\n    },\n}\n```\n\nThe directory path must be an absolute path.\n\nThe package will be ready to be managed by the Pearl system.\n\nThe directory content can be structured in the exact way as described\nin the [section](#structure-of-a-pearl-package) above.\n\n## Use third-party git repository not available in Pearl Hub ##\nIf you want to use a third-party git repository\nthat is not available in the [Official Pearl Hub](https://github.com/pearl-hub),\nyou can:\n\n* Create your own git repository and use the `PEARL_PKGVARDIR` directory (recommended)\n* Create your own git repository and use [git submodule](https://git-scm.com/docs/git-submodule)\n* Point directly to the third-party git repository\n\nTo see examples of Pearl packages from third-party git repos take a look at the\n[Official Pearl Hub](https://github.com/pearl-hub).\n\n### Create your own git repository and use the `PEARL_PKGVARDIR` directory (recommended) ###\nYou can use the `PEARL_PKGVARDIR` directory during the installation phase to install the third-party git repository.\nThis is the best way to incorporate third-party project into Pearl ecosystem.\n\nHere it is an example of `hooks.sh` file which install the ranger file manager into the directory `${PEARL_PKGVARDIR}/ranger`:\n\n```bash\nfunction post_install(){\n    install_or_update_git_repo https://github.com/ranger/ranger.git \"${PEARL_PKGVARDIR}/ranger\" master\n}\n\nfunction post_update(){\n    post_install\n}\n\nfunction pre_remove(){\n    rm -rf ${PEARL_PKGVARDIR}/ranger\n}\n```\n\nThe function `install_or_update_git_repo` comes from the [Buava](https://github.com/fsquillace/buava)\nlibrary in [`utils.sh`](https://github.com/fsquillace/buava/blob/master/lib/utils.sh)\nwhich is natively available in Pearl during the installation.\nYou can even use the functions `install_git_repo` or `update_git_repo` which respectively install or update the git repository.\n\nFor a full example take a look at the [ranger](https://github.com/pearl-hub/ranger) Pearl Hub package.\n\n### Create your own git repository and use git submodule ###\nInside your git repository, you just need to add the third-party git repo as a\n[git submodule](https://git-scm.com/docs/git-submodule).\nFor instance, to add the [powerline](https://github.com/powerline/powerline) in your Pearl package,\nyou can introduce a submodule in the `module` directory:\n\n```sh\n$\u003e git submodule add https://github.com/powerline/powerline.git module\n```\n\nThe filesystem structure of the package will become something like this:\n\n    / (package root)\n    │\n    ├── pearl-config   (optional directory)\n    ├── module/        (contains third-party code)\n    └── (additional package content)\n\nThen, you just need to modify the config scripts in order to integrate the third-party\nproject inside Pearl environment.\n\n### Point directly to the third-party git repository ###\nLet's suppose you want to install the [vim-rails](https://github.com/tpope/vim-rails) plugin.\nIn your Pearl configuration (`$XDG_CONFIG_HOME/pearl/pearl.conf`), add your new Pearl package:\n\n```python\nPEARL_PACKAGES = {\n    \"vim-rails\": {\n        \"url\": \"https://github.com/tpope/vim-rails.git\",\n        \"description\": \"Ruby on Rails power tools\"\n    },\n}\n```\n\nInstall the package:\n\n```sh\n$\u003e pearl install vim-rails\n```\n\nVoila', your new vim plugin is ready to be used!\n\nThis approach is particularly useful whenever you do not need to specify\nany pearl config to *\"enrich\"* the third-party project inside\nthe Pearl environment.\n\n\nCreate your own Pearl repository\n===============\nA Pearl repository is just a git repository containing a file located in `pearl-config/pearl.conf`\nwith a list of packages. For instance, the *OPH* repository is available\n[here](https://github.com/pearl-hub/repo-v2).\n\nIn order to use the new repository (i.e. \"https://github.com/myrepo/pearl-repo.git\"),\nupdate the `pearl.conf` file by adding the following line:\n\n```python\nPEARL_REPOS += (\"https://github.com/myrepo/pearl-repo.git\",)\n```\n\nComparison with alternative solutions\n=====================================\nHere we are going to compare Pearl with other solutions according to the following dimensions:\n\n**Modular**\n\nAbility of the tool to split configurations and/or programs into different modules.\nIts importance is because in case configs are broken you can still manage other modules which you are more confident they works.\nFor instance, if your `vim` config does not work you are still able to manage all other dotfiles because they are independent from each other.\nObviously, Pearl, by design, allows modularization through packages.\n              \n**General purpose**\n\nTools can be either `general` (manage any kind of programs) or `dotfiles-specific` (limited to dotfiles only).\n\n**Simple**\n\nIndicates how easy is to setup and use the tool. Between all tools, [Ansible](https://www.ansible.com/)\nis the one which has a steep learning curve. Ansible is a powerful software for IT\nautomation which can be widely used for many use cases.\nDespite of this, Ansible has few drawbacks when using it for lightweight forms of automation compared to Pearl:\n\n- Pearl uses bash for writing simple scripts for automation:\n  - it makes easier the integration with other programs in the system (without existing Playbooks may be hard and tedious to achieve this in Ansible);\n  - bash is a powerful, accessible and well-known language;\n- Ansible requires way more dependencies than Pearl;\n- Ansible requires knowledge about how Ansible Playbooks works;\n- Pearl uses built-in [functions](https://github.com/fsquillace/buava/blob/master/README.md#table-of-buava-functions) and [variables](#structure-of-a-pearl-package) which heavily simplify construction of scripts for automation;\n- Pearl makes easier to remove packages and restore the system to an initial state;\n\n**Diversity**\n\nIndicates whether the tool handles diverse management for configurations/programs when dealing with heterogeneous machines.\nThere are multiple ways to handle diversity through Pearl:\n\n- one way is to create just one package and write bash functions which handle specific logic for each machine.\n- Alternatively, you can create a base package containing common functionality and use a package specific for each machine.\nThis is possible thanks to the ability to define dependencies between packages.\n\n**Portable**\n\nAbility of the tools to be used in multiple platforms. Pearl can be used on both Linux and OSX.\n\nComparison\n----------\n\n|                 | Pearl | Ansible | yadm | vcsh | homesick |\n| --------------- | ----- | ------- | ---- | ---- | -------- |\n| Modular         | Yes   | Yes     | No   | Yes  | Yes      |\n| General purpose | Yes   | Yes     | No   | No   | No       |\n| Diversity       | Yes   | Yes     | Yes  | Yes  | Yes      |\n| Simple          | Yes   | No      | Yes  | Yes  | Yes      |\n| Portable        | Yes   | Yes     | Yes  | Yes  | Yes      |\n\nTroubleshooting\n===============\n\n## Corrupted Pearl Home directory ##\n\n\u003e **Q**: What should I do if I accidentally removed files/packages in `$PEARL_HOME`?\n\n\u003e **A**: You can recover the structure of the `$PEARL_HOME` by running:\n\n```sh\n$\u003e pearl init\n```\n\n\u003e The command will create all the essential directories and symlinks in `$PEARL_HOME`.\n\u003e It is harmless to run the `init` command multiple times since it is idempotent.\n\n## Corrupted package ##\n\n\u003e **Q**: Why I can no longer update/remove a package?\n\n\u003e **A**: This is probably because either one of the hook functions\n\u003e is failing or the package content is corrupted. You can forcely remove the package:\n\n```sh\n$\u003e pearl --force remove \u003cpackagename\u003e\n```\n\n\u003e which bypass hook functions that are failing. If that does not even work,\n\u003e you can delete a package by simply removing its directory:\n\n```sh\n$\u003e rm -rf $PEARL_HOME/packages/pearl/\u003cpackagename\u003e\n```\n\n\u003e After that, you can reinstall the package again.\n\u003e The Pearl packages contain a dedicated directory `var` for storing\n\u003e data needed for the package itself.\n\u003e The `var` data are always managed by the package and they never gets deleted by Pearl\n\u003e during the package removal.\n\u003e If you want to delete the content in `var` package:\n\n```sh\n$\u003e rm -rf $PEARL_HOME/var/pearl/\u003cpackagename\u003e\n```\n\n## Package shell variables/functions not visible in current shell after installation ##\n\n\u003e **Q**: Why are not package's environment variables/functions visible in\n\u003e my current shell after installing/updating the package?\n\n\u003e **A**: After package install/update, the variables or\n\u003e functions related to the current shell and defined in `pearl-config/config.*`\n\u003e may not be available because a reload of Pearl configuration file is required.\n\u003e You can fix this by simply run the function:\n\n```sh\npearl-source\n```\n    \n\u003e which reloads the configuration.\n\u003e The use of such function is not always required but depends on\n\u003e whether the variables/functions involve the current shell where the\n\u003e package `install`/`update` occurred (i.e. a new variable defined in `config.sh`\n\u003e and the current shell is a bash or zsh). Alternatively, user can always\n\u003e create a new shell and the package resources will be available as\n\u003e expected.\n\n## Error during package install\n\n\u003e Q: Why Do I get the following error:\n\n```sh\nError on executing 'post_install' hook. Rolling back...\n```\n\n\u003e A: This occurs when the `post_install` hook function fails.\n\u003e Pearl will attempt to roll back and force a removal of the package. In this way\n\u003e you can attempt to install the package again once the hook function gets\n\u003e fixed.\n\n## Debugging config files\n\n\u003e Q: How do I debug `config.*` files when running the corresponding program (i.e. `emacs`, `vim`, `bash`, `zsh`, `fish`)?\n\n\u003e A: Set the environment variable `PEARL_DEBUG` before running the program. For example, to check the `config.vim` files run\n\u003e when starting up `vim` program:\n\n```sh\nPEARL_DEBUG=1 vim\n```\n\n## Pearl executable not found\n\n\u003e Q: Why do I get this message when opening shells (bash, zsh, fish) or editors (vim, emacs):\n\n```\nPearl error: Could not load pearl package config files. `pearl` executable not found. Please update the PATH variable first.\"\n```\n\n\u003e A: This is because `pearl` executable is required for properly sourcing the pearl package `config.*` files.\n\u003e Make sure to add the path location to the `PATH` in your\n\u003e favorite shell config file (i.e. `~/.bashrc`, `~/.zshrc`, `~/.config/fish/config`).\n\nContributing\n============\n\nYou could help improving Pearl and the [OPH](https://github.com/pearl-hub) in the following ways:\n\n- [Reporting Bugs](CONTRIBUTING.md#reporting-bugs)\n- [Suggesting Enhancements](CONTRIBUTING.md#suggesting-enhancements)\n- [Writing Code](CONTRIBUTING.md#your-first-code-contribution)\n\nDonating\n========\nTo sustain the project please consider funding by donations through\nthe [GitHub Sponsors page](https://github.com/sponsors/fsquillace/).\n\nAuthors\n=======\nPearl was originally created by [Filippo Squillace (feel.sqoox@gmail.com)](https://github.com/fsquillace).\n\nHere is a list of [**really appreciated contributors**](https://github.com/pearl-core/pearl/graphs/contributors)!\n\n[![](https://sourcerer.io/fame/fsquillace/pearl-core/pearl/images/0)](https://sourcerer.io/fame/fsquillace/pearl-core/pearl/links/0)[![](https://sourcerer.io/fame/fsquillace/pearl-core/pearl/images/1)](https://sourcerer.io/fame/fsquillace/pearl-core/pearl/links/1)[![](https://sourcerer.io/fame/fsquillace/pearl-core/pearl/images/2)](https://sourcerer.io/fame/fsquillace/pearl-core/pearl/links/2)[![](https://sourcerer.io/fame/fsquillace/pearl-core/pearl/images/3)](https://sourcerer.io/fame/fsquillace/pearl-core/pearl/links/3)[![](https://sourcerer.io/fame/fsquillace/pearl-core/pearl/images/4)](https://sourcerer.io/fame/fsquillace/pearl-core/pearl/links/4)[![](https://sourcerer.io/fame/fsquillace/pearl-core/pearl/images/5)](https://sourcerer.io/fame/fsquillace/pearl-core/pearl/links/5)[![](https://sourcerer.io/fame/fsquillace/pearl-core/pearl/images/6)](https://sourcerer.io/fame/fsquillace/pearl-core/pearl/links/6)[![](https://sourcerer.io/fame/fsquillace/pearl-core/pearl/images/7)](https://sourcerer.io/fame/fsquillace/pearl-core/pearl/links/7)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpearl-core%2Fpearl","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpearl-core%2Fpearl","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpearl-core%2Fpearl/lists"}