Metadata-Version: 2.2
Name: pearl
Version: 2.3.6
Summary: 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.
Home-page: http://github.com/pearl-core/pearl
Download-URL: https://github.com/pearl-core/pearl/releases
Author: Filippo Squillace
Author-email: feel.sqoox@gmail.com
License: GNU General Public License v3
Keywords: pearl,shell,dotfiles,package manager
Classifier: Development Status :: 5 - Production/Stable
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.6
Classifier: Programming Language :: Python :: 3.7
Classifier: Programming Language :: Python :: 3.8
Classifier: Natural Language :: English
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
Classifier: Operating System :: MacOS
Classifier: Operating System :: POSIX :: Linux
Classifier: Topic :: Software Development :: Build Tools
Classifier: Topic :: System :: Software Distribution
Classifier: Topic :: System :: Shells
Classifier: Topic :: Utilities
Requires-Python: >=3.6
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: AUTHORS.md
Provides-Extra: dev
Requires-Dist: coverage; extra == "dev"
Requires-Dist: flake8; extra == "dev"
Requires-Dist: pip; extra == "dev"
Requires-Dist: pytest; extra == "dev"
Requires-Dist: Sphinx; extra == "dev"
Requires-Dist: tox; extra == "dev"
Requires-Dist: twine; extra == "dev"
Requires-Dist: watchdog; extra == "dev"
Dynamic: author
Dynamic: author-email
Dynamic: classifier
Dynamic: description
Dynamic: description-content-type
Dynamic: download-url
Dynamic: home-page
Dynamic: keywords
Dynamic: license
Dynamic: provides-extra
Dynamic: requires-python
Dynamic: summary

Pearl
=====

<h1 align="center">
    <a href="https://github.com/pearl-core/pearl"><img
        alt="Pearl"
        width=250px
        src="https://rawgit.com/pearl-core/logo/master/pearl.png"></a>
</h1>

|Project Status|Donation|Communication|
|:-----------:|:--------:|:-----------:|
|[![Build status](https://api.travis-ci.org/pearl-core/pearl.png?branch=master)](https://travis-ci.org/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/) [![PyPi downloads](https://img.shields.io/pypi/dm/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&hosted_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&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) |

**Table of Contents**
- [Description](#description)
- [Quickstart](#quickstart)
- [Installation](#installation)
  - [Dependencies](#dependencies)
  - [Linux](#linux)
  - [OSX](#osx)
- [Create your own Pearl package](#create-your-own-pearl-package)
- [Create your own Pearl repository](#create-your-own-pearl-repository)
- [Comparison with alternative solutions](#comparison-with-alternative-solutions)
- [Troubleshooting](#troubleshooting)
- [Contributing](#contributing)
- [Donating](#donating)
- [Authors](#authors)

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.

As soon as a package gets installed, its content can be activated out of the box
according to certain events, like, for instance, a shell startup (Bash, Zsh or Fish) or
an editor startup (Vim or Emacs). This is possible via a smart and simple
[hook mechanism](#create-your-own-pearl-package)
that integrates the package content within the Pearl ecosystem.

The main advantages on using Pearl are:

- Create your own Pearl package in a very simple way.
- Full control and sync of your dotfiles across different systems.
- Automatic bootstrap of the package content whenever shells or editors get started.
- Access to a wide range of existing packages via the [OPH (Official Pearl Hub)](https://github.com/pearl-hub).
- Allows to create your own shareable package repository.
- [Comparison](#comparison-with-alternative-solutions) with alternative solutions
- Stable codebase with 100+ unit tests and exhaustive integration tests via [Travis](https://travis-ci.org/pearl-core/pearl) for Linux and OSX.
- Small number of [dependencies](#dependencies) needed in order to ensure compatibility with most of the systems.

Quickstart
==========
There are two main use cases for Pearl which will be explained here below:

Use case 1: Create custom package
---------------------
The following example creates a Pearl package containing dotfiles. In this example we are going to create a very simple
dotfile for `git`.

```sh
$> pearl create mydotfiles ~/dotfiles
```
This will create a directory `pearl-config` in `~/dotfiles` containing all the templates to help you
start writing a Pearl package. `~/dotfiles` does not need to be an empty directory.

Additionally, the local repository in `$XDG_CONFIG_HOME/pearl/pearl.conf` (defaults to `~/.config/pearl/pearl.conf`)
will be updated with the new package entry called `mydotfiles`.
This tells to Pearl where to look for the package:

```sh
$> cat ~/.config/pearl/pearl.conf
...
...
PEARL_PACKAGES["mydotfiles"] = {"url": "~/dotfiles"}
```

Place the git config inside `~/dotfiles` directory:

```sh
$> cd ~/dotfiles
$> echo -e "[alias]\n    cfg = config" > gitconfig
```

You need now to give instructions about how to link the `gitconfig` into the system.
This is possible through the `pearl-config/hooks.sh` file. Just update it with the following:

```bash
post_install() {
    link git "${PEARL_PKGDIR}/gitconfig"
    return 0
}

post_update() {
    post_install
}

pre_remove() {
    unlink git "${PEARL_PKGDIR}/gitconfig"
    return 0
}
```

This tells to Pearl to `link` the git config located in `"${PEARL_PKGDIR}/gitconfig"` (`${PEARL_PKGDIR}` is a builtin variable)
to the `git` program just after the package installation. Conversely, before removal, this tells to `unlink` the same config file.

Now, just install the package and you will see the changes already reflected:

```sh
$> pearl install mydotfiles
$> # The new git config is ready!
$> git cfg -l
```

Once the package is completed, you can upload it to a git repository and
just fetch it from there by updating `~/.config/pearl/pearl.conf`:
```sh
$> cat ~/.config/pearl/pearl.conf
...
...
PEARL_PACKAGES["mydotfiles"] = {"url": "https://github.com/pearluser/mydotfiles.git"}
```

There are way more things you can do with Pearl!
For more details about the `pearl-config` content, look at the [section](#create-your-own-pearl-package) below.

Use case 2: Use Pearl Hub repository
------------------------
You can just use existing packages from the Pearl Hub repository.
It contains a big list of packages about dotfiles, programs and plugins for many known applications.

For instance, look to the entire list of packages:

```sh
$> pearl list
```

If interested to search only for dotfiles:

```sh
$> pearl search dotfiles
pearl/dot-gtk 
    Awesome gtk dotfiles
pearl/kyrat 
    20 lines script that brings dotfiles in a ssh session
pearl/dot-mutt 
    Awesome Mutt dotfiles
pearl/dot-emacs 
    Awesome emacs dotfiles
pearl/dot-git 
    Awesome git dotfiles
pearl/dot-screen 
    Awesome screen dotfiles
pearl/dot-tmux
    Awesome Tmux dotfiles
pearl/dot-vim
    Awesome vim dotfiles
pearl/dot-firefox
    Awesome Firefox dotfiles
pearl/dot-terms
    Awesome terms dotfiles (i.e. urxvt)
pearl/dot-bash
    Awesome bash dotfiles
```

### Recommended Pearl Hub packages to install:

- [cmd](https://github.com/pearl-hub/cmd)
- [kyrat](https://github.com/pearl-hub/kyrat)
- [ranger](https://github.com/pearl-hub/ranger)
- [sesaila](https://github.com/pearl-hub/sesaila)
- [trash-cli](https://github.com/pearl-hub/trash-cli)
- [txum](https://github.com/pearl-hub/txum)

Installation
============

Dependencies
------------
Before installing Pearl be sure that all dependencies are properly installed in your system.
The Pearl dependencies are the following:

### Mandatory
- [python (>=3.6)](https://www.python.org/)
- [bash (>=4.1)](https://www.gnu.org/software/bash/)
- [git (>=1.8.5)](https://git-scm.com/)

### Optional
The following are not mandatory dependencies but can be handy to have for the hook functions in Pearl package.
All the Linux distributions have these dependencies already installed.

- [GNU coreutils](https://www.gnu.org/software/coreutils/)
- [grep](https://www.gnu.org/software/grep/) 
- [sed](https://www.gnu.org/software/sed/) 

### Additional shells supported
Pearl supports also the following shells:

- [fish (>=2.2.0)](https://fishshell.com/)
- [zsh (>=5.2)](http://www.zsh.org/)


Linux
-----

### Arch Linux

Pearl can be installed in Arch Linux through AUR.
The package is [pearl-git](https://aur.archlinux.org/packages/pearl-git/).

For example, to install Pearl via [yay](https://github.com/Jguer/yay) AUR helper:
```
$> yay -S pearl-git
```

Any other AUR helpers can be found [here](https://wiki.archlinux.org/index.php/AUR_helpers).

### Other Linux distributions

Assuming all Pearl [dependencies](#dependencies) are properly installed
in the system, to install Pearl you can use the `pip` command:

```
$> sudo /usr/bin/pip install pearl
$> pearl init
```

`pearl` executable will be located to `/usr/bin`.
The idempotent `init` command will create the `$PEARL_HOME` directory and
the new pearl configuration files from template.

OSX
---
In order to install all Pearl dependencies, you first need to install [Homebrew](http://brew.sh/).

To install all the needed dependencies via Homebrew:
```sh
$> brew update
$> brew install bash git coreutils grep gnu-sed python
```

To install Pearl you can use the `pip` command:
```sh
$> pip3 install pearl
$> pearl init
```

`pearl` executable will be located to `/usr/local/bin`.
The idempotent `init` command will create the `$PEARL_HOME` directory and
the new pearl configuration files from template.

**IMPORTANT NOTE**: Pearl gets loaded through `~/.bashrc`. The problem is that in OSX,
the terminal opens a login shell and only `~/.bash_profile` will get executed.
Run the following only if `~/.bashrc` is not loaded within `~/.bash_profile` file:

```sh
$> echo "[[ -f $HOME/.bashrc ]] && source $HOME/.bashrc" >> ~/.bash_profile
```

This will make sure that `~/.bashrc` will run at shell startup.

Create your own Pearl package
===============
**Any git repository is already a Pearl package**. For instance, in order
to manage a dotfiles repository in Pearl, you just need to change
the Pearl configuration file located in `$XDG_CONFIG_HOME/pearl/pearl.conf`.

Add the following line to `pearl.conf` file:

```python
PEARL_PACKAGES = {
    "mydotfiles": {
        "url": "https://github.com/user/mydotfiles.git",
        "description": "My dotfiles"
    },
}
```

In other words, update the `PEARL_PACKAGES` dictionary with a new entry containing the
name of the package (i.e. `mydotfiles`),
the git url (i.e. `https://github.com/user/mydotfiles.git`) and an optional description.

***That's it!*** The package will be ready to be managed by the Pearl system.

## Structure of a Pearl package ##
Your own git repository can contain an **optional** directory
named `pearl-config` used by Pearl to integrate the package with the Pearl environment.

    / (package root)
    │
    ├── pearl-config (optional directory)
    │   │
    │   ├── hooks.sh
    │   ├── config.sh
    │   ├── config.bash
    │   ├── config.zsh
    │   ├── config.fish
    │   ├── config.vim
    │   ├── config.el
    │   └── package.conf
    │
    └── (additional package content)

The files inside `pearl-config` are also **optional** script/configuration files:

- `hooks.sh` - contains the [hooks functions](#hook-functions) executed during the `install`, `update` and `remove` events.
- `config.sh` - will be sourced whenever a new Bash/Zsh shell is starting up.
- `config.bash` - will be sourced whenever a new Bash shell is starting up.
- `config.zsh` - will be sourced whenever a new Zsh shell is starting up.
- `config.fish` - will be sourced whenever a new Fish shell is starting up.
- `config.vim` - will be executed whenever Vim editor is starting up.
- `config.el` - will be sourced whenever Emacs editor is starting up.
- `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.

The order in which the `config.*` files are sourced among multiple installed packages depends on the closure dependency tree,
in 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.

The following variables can be used in any of the previous scripts:

- `PEARL_HOME`          - Pearl location (`$XDG_DATA_HOME/pearl` which by default is `$HOME/.local/share/pearl`)
- `PEARL_PKGDIR`        - Pearl package location
- `PEARL_PKGVARDIR`     - Pearl package location containing data needed for package
- `PEARL_PKGNAME`       - Pearl package name
- `PEARL_PKGREPONAME`   - Pearl package repo name (useful to detect and interact with packages within the same repo)

Additionally, the script `hooks.sh` can use the utility functions available in
[Buava](https://github.com/fsquillace/buava) and Pearl [*utils*](lib/utils) directory that
make easier the integration with Pearl ecosystem.

Useful examples of Pearl packages can be checked in the
[Official Pearl Hub](https://github.com/pearl-hub).

### The hooks.sh script ###
#### Hook functions ####
- `post_install`  - Called *after* an installation of the package occurs.
- `pre_update`    - Called *before* an update of the package occurs.
- `post_update`   - Called *after* an update of the package occurs.
- `pre_remove`    - Called *before* a removal of the package occurs.

#### An hooks.sh script example ####

```bash
post_install() {
    warn "Remember to setup your config located in: ~/.dotfile"
    # Do a smart backup before modifying the file
    backup ${HOME}/.dotfile
    "# New dotfile" > ${HOME}/.dotfile
    if ask "Are you sure to link the tmux config?" "Y"
    then
        link tmux "$PEARL_PKGDIR/mytmux.conf"
    fi

    info "Awesome - new package installed!"
    return 0
}
post_update() {
    post_install
    return 0
}
pre_remove() {
    info "dotfiles package removed"
    unlink tmux "$PEARL_PKGDIR/mytmux.conf"

    # Do an idempotent delete
    delete ${HOME}/.dotfile
    return 0
}
```

The `info` and `warn` are functions that print a message
using different colors (namely cyan and yellow).

The `link` `unlink` are idempotent functions (the result will not change
if the function will be called multiple times) that are able
to link/unlink a config file in order to be loaded at startup by a certain program.

The `ask` function will make installation interactive, asking user whether to link tmux config or not.

The `backup` keeps the last three backups of the file and do not perform backup
if the file has not been modified since the latest backup. The `delete` is a
function for idempotent remove (it will not raise an error if the file
no longer exist).

All these functions belong to the [Buava](https://github.com/fsquillace/buava) package
in [`utils.sh`](https://github.com/fsquillace/buava/blob/master/lib/utils.sh)
and to the Pearl [`utils.sh`](lib/utils/utils.sh) script. You can use them
inside the `hooks.sh` to any hook function.

**Very important note**: All the hook functions **must** be
[**idempotent**](https://en.wikipedia.org/wiki/Idempotence)
(the commands of each hook function must produce the same result even if
the command gets executed multiple times).
All buava commands are idempotent and this will help to write hook functions
very quickly.

**Note**: For OSX system, the GNU version `sed` and `grep` are automatically
imported in `hooks.sh` and can be directly used if needed.

### The package.conf file
`package.conf` is located in `pearl-config` directory and is meant to contain package metadata.
To simplify the creation of new packages, this file is completely optional.
This file may contain name of the package, description, author, os compatibility, license and more.
It can be also used to establish dependencies between packages.

Please **note** that `package.conf` is only meant to encapsulate package information within the package itself
but they are not directly consumed by the Pearl program. In fact, Pearl only reads from the `pearl.conf` file which is
where the metadata information can be also stored.

To give a better idea, take a look at the Pearl Hub
[repo.conf](https://github.com/pearl-hub/repo-v2/blob/master/pearl-config/repo.conf).
The [repo-builder](https://github.com/pearl-core/repo-builder/) is the script responsible to periodically
extract the `package.conf` metadata from each package and update the Pearl Hub `repo.conf`.

For a local package you can manually include such information directly in the `pearl.conf` file. This is an example of
package defined in `pearl.conf` which depends on the `pearl/cmd` package:

```python
PEARL_PACKAGES = {
    'mydotfiles': {
        "url": '/home/user/my/folder/dotfiles/',
        "description": "This package contains dotfiles",
        "author": "David Smith <dsmith@abc.com>",
        "depends": (
            "pearl/cmd",
        )
    },
}
```

If you do not need such features for your package, just ignore this file.

## Create a Pearl package from a local directory ##
Pearl package system will work even for local directories. This is particularly useful
whenever a Pearl package needs to be tested before pushing to a git repository.

For instance, the following lines in `pearl.conf` file will add a package located in
`/home/joe/dotfiles`:

```python
PEARL_PACKAGES = {
    "mydotfiles": {
        "url": "/home/user/mydotfiles",
        "description": "My dotfiles"
    },
}
```

The directory path must be an absolute path.

The package will be ready to be managed by the Pearl system.

The directory content can be structured in the exact way as described
in the [section](#structure-of-a-pearl-package) above.

## Use third-party git repository not available in Pearl Hub ##
If you want to use a third-party git repository
that is not available in the [Official Pearl Hub](https://github.com/pearl-hub),
you can:

* Create your own git repository and use the `PEARL_PKGVARDIR` directory (recommended)
* Create your own git repository and use [git submodule](https://git-scm.com/docs/git-submodule)
* Point directly to the third-party git repository

To see examples of Pearl packages from third-party git repos take a look at the
[Official Pearl Hub](https://github.com/pearl-hub).

### Create your own git repository and use the `PEARL_PKGVARDIR` directory (recommended) ###
You can use the `PEARL_PKGVARDIR` directory during the installation phase to install the third-party git repository.
This is the best way to incorporate third-party project into Pearl ecosystem.

Here it is an example of `hooks.sh` file which install the ranger file manager into the directory `${PEARL_PKGVARDIR}/ranger`:

```bash
function post_install(){
    install_or_update_git_repo https://github.com/ranger/ranger.git "${PEARL_PKGVARDIR}/ranger" master
}

function post_update(){
    post_install
}

function pre_remove(){
    rm -rf ${PEARL_PKGVARDIR}/ranger
}
```

The function `install_or_update_git_repo` comes from the [Buava](https://github.com/fsquillace/buava)
library in [`utils.sh`](https://github.com/fsquillace/buava/blob/master/lib/utils.sh)
which is natively available in Pearl during the installation.
You can even use the functions `install_git_repo` or `update_git_repo` which respectively install or update the git repository.

For a full example take a look at the [ranger](https://github.com/pearl-hub/ranger) Pearl Hub package.

### Create your own git repository and use git submodule ###
Inside your git repository, you just need to add the third-party git repo as a
[git submodule](https://git-scm.com/docs/git-submodule).
For instance, to add the [powerline](https://github.com/powerline/powerline) in your Pearl package,
you can introduce a submodule in the `module` directory:

```sh
$> git submodule add https://github.com/powerline/powerline.git module
```

The filesystem structure of the package will become something like this:

    / (package root)
    │
    ├── pearl-config   (optional directory)
    ├── module/        (contains third-party code)
    └── (additional package content)

Then, you just need to modify the config scripts in order to integrate the third-party
project inside Pearl environment.

### Point directly to the third-party git repository ###
Let's suppose you want to install the [vim-rails](https://github.com/tpope/vim-rails) plugin.
In your Pearl configuration (`$XDG_CONFIG_HOME/pearl/pearl.conf`), add your new Pearl package:

```python
PEARL_PACKAGES = {
    "vim-rails": {
        "url": "https://github.com/tpope/vim-rails.git",
        "description": "Ruby on Rails power tools"
    },
}
```

Install the package:

```sh
$> pearl install vim-rails
```

Voila', your new vim plugin is ready to be used!

This approach is particularly useful whenever you do not need to specify
any pearl config to *"enrich"* the third-party project inside
the Pearl environment.


Create your own Pearl repository
===============
A Pearl repository is just a git repository containing a file located in `pearl-config/pearl.conf`
with a list of packages. For instance, the *OPH* repository is available
[here](https://github.com/pearl-hub/repo-v2).

In order to use the new repository (i.e. "https://github.com/myrepo/pearl-repo.git"),
update the `pearl.conf` file by adding the following line:

```python
PEARL_REPOS += ("https://github.com/myrepo/pearl-repo.git",)
```

Comparison with alternative solutions
=====================================
Here we are going to compare Pearl with other solutions according to the following dimensions:

**Modular**

Ability of the tool to split configurations and/or programs into different modules.
Its importance is because in case configs are broken you can still manage other modules which you are more confident they works.
For instance, if your `vim` config does not work you are still able to manage all other dotfiles because they are independent from each other.
Obviously, Pearl, by design, allows modularization through packages.
              
**General purpose**

Tools can be either `general` (manage any kind of programs) or `dotfiles-specific` (limited to dotfiles only).

**Simple**

Indicates how easy is to setup and use the tool. Between all tools, [Ansible](https://www.ansible.com/)
is the one which has a steep learning curve. Ansible is a powerful software for IT
automation which can be widely used for many use cases.
Despite of this, Ansible has few drawbacks when using it for lightweight forms of automation compared to Pearl:

- Pearl uses bash for writing simple scripts for automation:
  - it makes easier the integration with other programs in the system (without existing Playbooks may be hard and tedious to achieve this in Ansible);
  - bash is a powerful, accessible and well-known language;
- Ansible requires way more dependencies than Pearl;
- Ansible requires knowledge about how Ansible Playbooks works;
- 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;
- Pearl makes easier to remove packages and restore the system to an initial state;

**Diversity**

Indicates whether the tool handles diverse management for configurations/programs when dealing with heterogeneous machines.
There are multiple ways to handle diversity through Pearl:

- one way is to create just one package and write bash functions which handle specific logic for each machine.
- Alternatively, you can create a base package containing common functionality and use a package specific for each machine.
This is possible thanks to the ability to define dependencies between packages.

**Portable**

Ability of the tools to be used in multiple platforms. Pearl can be used on both Linux and OSX.

Comparison
----------

|                 | Pearl | Ansible | yadm | vcsh | homesick |
| --------------- | ----- | ------- | ---- | ---- | -------- |
| Modular         | Yes   | Yes     | No   | Yes  | Yes      |
| General purpose | Yes   | Yes     | No   | No   | No       |
| Diversity       | Yes   | Yes     | Yes  | Yes  | Yes      |
| Simple          | Yes   | No      | Yes  | Yes  | Yes      |
| Portable        | Yes   | Yes     | Yes  | Yes  | Yes      |

Troubleshooting
===============

## Corrupted Pearl Home directory ##

> **Q**: What should I do if I accidentally removed files/packages in `$PEARL_HOME`?

> **A**: You can recover the structure of the `$PEARL_HOME` by running:

```sh
$> pearl init
```

> The command will create all the essential directories and symlinks in `$PEARL_HOME`.
> It is harmless to run the `init` command multiple times since it is idempotent.

## Corrupted package ##

> **Q**: Why I can no longer update/remove a package?

> **A**: This is probably because either one of the hook functions
> is failing or the package content is corrupted. You can forcely remove the package:

```sh
$> pearl --force remove <packagename>
```

> which bypass hook functions that are failing. If that does not even work,
> you can delete a package by simply removing its directory:

```sh
$> rm -rf $PEARL_HOME/packages/pearl/<packagename>
```

> After that, you can reinstall the package again.
> The Pearl packages contain a dedicated directory `var` for storing
> data needed for the package itself.
> The `var` data are always managed by the package and they never gets deleted by Pearl
> during the package removal.
> If you want to delete the content in `var` package:

```sh
$> rm -rf $PEARL_HOME/var/pearl/<packagename>
```

## Package shell variables/functions not visible in current shell after installation ##

> **Q**: Why are not package's environment variables/functions visible in
> my current shell after installing/updating the package?

> **A**: After package install/update, the variables or
> functions related to the current shell and defined in `pearl-config/config.*`
> may not be available because a reload of Pearl configuration file is required.
> You can fix this by simply run the function:

```sh
pearl-source
```
    
> which reloads the configuration.
> The use of such function is not always required but depends on
> whether the variables/functions involve the current shell where the
> package `install`/`update` occurred (i.e. a new variable defined in `config.sh`
> and the current shell is a bash or zsh). Alternatively, user can always
> create a new shell and the package resources will be available as
> expected.

## Error during package install

> Q: Why Do I get the following error:

```sh
Error on executing 'post_install' hook. Rolling back...
```

> A: This occurs when the `post_install` hook function fails.
> Pearl will attempt to roll back and force a removal of the package. In this way
> you can attempt to install the package again once the hook function gets
> fixed.

## Debugging config files

> Q: How do I debug `config.*` files when running the corresponding program (i.e. `emacs`, `vim`, `bash`, `zsh`, `fish`)?

> A: Set the environment variable `PEARL_DEBUG` before running the program. For example, to check the `config.vim` files run
> when starting up `vim` program:

```sh
PEARL_DEBUG=1 vim
```

## Pearl executable not found

> Q: Why do I get this message when opening shells (bash, zsh, fish) or editors (vim, emacs):

```
Pearl error: Could not load pearl package config files. `pearl` executable not found. Please update the PATH variable first."
```

> A: This is because `pearl` executable is required for properly sourcing the pearl package `config.*` files.
> Make sure to add the path location to the `PATH` in your
> favorite shell config file (i.e. `~/.bashrc`, `~/.zshrc`, `~/.config/fish/config`).

Contributing
============

You could help improving Pearl and the [OPH](https://github.com/pearl-hub) in the following ways:

- [Reporting Bugs](CONTRIBUTING.md#reporting-bugs)
- [Suggesting Enhancements](CONTRIBUTING.md#suggesting-enhancements)
- [Writing Code](CONTRIBUTING.md#your-first-code-contribution)

Donating
========
To sustain the project please consider funding by donations through
the [GitHub Sponsors page](https://github.com/sponsors/fsquillace/).

Authors
=======
Pearl was originally created by [Filippo Squillace (feel.sqoox@gmail.com)](https://github.com/fsquillace).

Here is a list of [**really appreciated contributors**](https://github.com/pearl-core/pearl/graphs/contributors)!

[![](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)


# Change Log #

## [2.3.6][v236] - 2020-12-16 ##

* Add `add_to_path` function to sh and fish boot scripts
* Improve README installation section

## [2.3.5][v235] - 2020-12-14 ##

* Source `config.*` files according to dependency tree order
* Deprecate support for Python 3.5
* Add `PEARL_DEBUG` environment variable
* Fix integ tests for OSX

## [2.3.4][v234] - 2020-06-28 ##

* Fix when URL change local/git package

## [2.3.3][v233] - 2020-02-20 ##

* Add FUNDING file
* Add new sections in README
* Add PyPi badges in README

## [2.3.2][v232] - 2020-02-15 ##

* Show traceback only on unexpected exception
  * To see traceback about pearl error, use the `-v` option
* Add ability to remove packages even when they do not exist in repository anymore

## [2.3.1][v231] - 2020-01-29 ##

* Fix bug when removing packages
* Refactor README.md

## [2.3.0][v230] - 2020-01-25 ##

* Handle dependencies between packages
  * During `install`, `update` and `emerge` packages dependencies will be included as well.
  * During `remove` only packages not required by others can be removed.
* Include `Required by` in `info` command

## [2.2.0][v220] - 2020-01-17 ##

* Add `info` command
* Make `search` looking at keywords field

## [2.1.2][v212] - 2020-01-14 ##

* Change name PyPI package from `pearcli` to `pearl`
* Add `package.conf`

## [2.1.1][v211] - 2020-01-13 ##

* Replace `install.sh` with `hooks.sh`
  * `install.sh` will still be valid until next releases
* Fail if no command is specified

## [2.1.0][v210] - 2020-01-12 ##

* Add `create` command
* Fix procedure to install Pearl in OSX
* Fix ci to upload to PyPI

## [2.0.2][v202] - 2020-01-11 ##

* Add instructions to install Pearl in Arch Linux
* Fix bug for version option

## [2.0.1][v201] - 2020-01-11 ##

* Manual intervention to switch to Pearl v2
  * [Migration page](https://github.com/pearl-core/pearl/wiki/Migration-to-Pearl-version-2)
* Codebase re-written in Python
* Remove the `post_remove`
* `pearl.conf` is not a python script. This requires manual intervention. Take a look at the `pearl.conf.template` file in codebase
* `pearl-metadata` directory is finally deprecated
* Add `--no-confirm` option
* Add `--force` option
  * This option bypasses failures even during the hook function execution
* Add `--verbose` option
  * `-vv` allows to enable xtrace in hook functions
* Add `--update-repos` option
* Shortcut commands (i.e. `i` to specify `install` command) are no longer available
* Pearl file locations change drastically in order to be complaint with the
[XDG Base Directory Specification](https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html)
  * As of now, `pearl.conf` resides in `$XDG_CONFIG_HOME/pearl` (default `~/.config/pearl`)
  * The new location for `$PEARL_HOME` is `$XDG_DATA_HOME/pearl` (default `~/.local/share/pearl`)
* Remove the variables `$PEARL_ROOT` and `$PEARL_TEMPORARY`

## [1.8.2][v182] - 2019-10-13 ##

* Update `README.md` file

## [1.8.1][v181] - 2019-07-13 ##

* Update `buava`:
  * New view action for `setup_configuration` helper function

## [1.8.0][v180] - 2019-06-03 ##

* Add roll back mechanism during install package
* Add `grep` and `sed` as optional dependencies since they may be used in hook functions
* Add newer `buava`:
  * `backup` function
  * `delete` function
  * `ideavim` and `gvim` dotfiles for (`un`)`link` functions
  * `install_or_update_vim_plugin_git_repo` function
  *  Add GNU `sed` and `grep` for OSX compat functions

## [1.7.2][v172] - 2019-01-15 ##

* Fix variables `PEARL_PKGNAME` `PEARL_PKGREPONAME` for vim and emacs boot

## [1.7.1][v171] - 2018-08-11 ##

* Deprecate pathogen
* Ensure to `cd` when updating package pointing to local directory
* Fix when package specified with full name does not exist
* More log info when Git URL package change
* Proceed even if `install.sh` is syntatically incorrect (prevent block for fixing the broken package)
* Improve doc and add section about comparison with Ansible

## [1.7.0][v170] - 2018-07-05 ##

* Add the idempotent `emerge` command which update/install packages.
* No longer support the use of USR1 signal to source the Pearl config to the parent process. To explictly do that run `pearl-source` command instead.

## [1.6.3][v163] - 2018-06-22 ##

* Location of the repo file is `pearl-config/pearl.conf`. Backward compatibility will be kept until 2.0.0
* Make the branch name inferred from repo's HEAD rather than hardcode the branch with `master`

## [1.6.2][v162] - 2018-06-09 ##

* Add variables `PEARL_PKGNAME` `PEARL_PKGREPONAME`
* Fix boot vim for deprecating `pearl-metadata`
* Update doc to use dynamic updates for third-party git repos
* Add the buava git repo helpers

## [1.6.1][v161] - 2018-02-04 ##

* Fix import `osx-compat.sh`
* Fix update Pearl submodules during updates

## [1.6.0][v160] - 2018-02-03 ##

* Change directory name to `pearl-config`. Pearl version `2.0.0` will deprecate `pearl-metadata`
* `link_to_path` to customize symlink name
* Changes in `buava` for Pearl configs:
  * `osx_detect` function to detect the OS platform
  * Improved `choose` function with indexes
  * Add `ssh` for `[un]link` function

## [1.5.6][v156] - 2017-08-31 ##

* Fix Integ tests

## [1.5.5][v155] - 2017-08-31 ##

* Update Buava:
  * Update `download` function
  * Add `choose`, `input` and `contain_elements` functions

## [1.5.4][v154] - 2017-08-28 ##

* Update Buava:
  * Add `download` function
  * vimperator gtk2 programs for `[un]link` functions

## [1.5.3][v153] - 2017-06-29 ##

* Add [Pear test utils](https://github.com/pearl-core/test-utils) as new dependency
* Add [Bunit](https://github.com/fsquillace/bunit) as new dependency
* Add [Buava](https://github.com/fsquillace/buava) as new dependency
* Inform about the trap on USR1 signal

## [1.5.2][v152] - 2017-01-07 ##

* Add support for new OSX image in Travis
* Fallback to a default temp directory if `tty` does not work

## [1.5.1][v151] - 2016-11-15 ##

* Fix git --no-parser log for missing newline

## [1.5.0][v150] - 2016-11-13 ##

* Provide (un)link from/to in utils.sh
* Provide list of last commits during add/update package
* Fix `unlink_from_path` when source file is a symlink

## [1.4.5][v145] - 2016-11-11 ##

* Provide (un)link from/to PATH variable in utils.sh

## [1.4.4][v144] - 2016-09-26 ##

* Improving doc and add checkstyle

## [1.4.3][v143] - 2016-05-25 ##

* Remove the requirement of updating the PATH on OSX

## [1.4.2][v142] - 2016-05-10 ##

* Add support for OSX
* Add check for existing `PEARL_HOME` variable for emacs/vim boot scripts
* Add `PEARL_HOME/bin` directory to have symlinks for the Pearl packages executables
* Avoid polluting `PATH` variable by introducing a check first

## [1.4.1][v141] - 2016-04-30 ##

* Introduce `$PEARL_PKGVARDIR` on boot scripts
* Packages do not need to have `master` as default branch
* Change the installation process to avoid [pipe bash problem](https://www.idontplaydarts.com/2016/04/detecting-curl-pipe-bash-server-side/)
* Ensure to get the most updated `post_update` function
* Refactor unit tests in `test-package.sh`

## [1.4.0][v140] - 2016-04-23 ##

* Add a dedicated directory `$PEARL_PKGVARDIR` for the Pearl packages in order to store data
  needed during the execution of the package itself
* Add warning in case of an old version of git or bash
* Introduce `$PEARL_PKGDIR` environment variable for emacs and vim config files
* Change the definition of public API

## [1.3.1][v131] - 2016-04-21 ##

* Fix compatibility with Bash 4.1
* Integration tests with fixed Bash and Git versions

## [1.3.0][v130] - 2016-04-20 ##

* Provide the definition of public API
* Add the emacs hook
* Use a better approach to return values from bash functions
* Change location of the boot files for pearl.fish and pearl.sh
* Introduce the standard documentation for functions
* Use try/catch approach to handle errors

## [1.2.0][v120] - 2016-04-14 ##

* Fix the removal of packages by querying the local directory
* Add (un)link functions for utils.sh

## [1.1.0][v110] - 2016-04-09 ##

* Check if Git URL changed during updates
* Introduce the template for new Pearl packages
* Local directories can be used as Pearl packages
* Add VERSION file

## [1.0.1][v101] - 2016-04-08 ##

* Update docs
* Add travis and integration tests
* Introduce the installer

## [1.0.0][v100] - 2016-04-03 ##

* Initial commit.

<!--  Links -->

[v100]: https://github.com/pearl-core/pearl/releases/tag/1.0.0
[v101]: https://github.com/pearl-core/pearl/releases/tag/1.0.1
[v110]: https://github.com/pearl-core/pearl/releases/tag/1.1.0
[v120]: https://github.com/pearl-core/pearl/releases/tag/1.2.0
[v130]: https://github.com/pearl-core/pearl/releases/tag/1.3.0
[v131]: https://github.com/pearl-core/pearl/releases/tag/1.3.1
[v140]: https://github.com/pearl-core/pearl/releases/tag/1.4.0
[v141]: https://github.com/pearl-core/pearl/releases/tag/1.4.1
[v142]: https://github.com/pearl-core/pearl/releases/tag/1.4.2
[v143]: https://github.com/pearl-core/pearl/releases/tag/1.4.3
[v144]: https://github.com/pearl-core/pearl/releases/tag/1.4.4
[v145]: https://github.com/pearl-core/pearl/releases/tag/1.4.5
[v150]: https://github.com/pearl-core/pearl/releases/tag/1.5.0
[v151]: https://github.com/pearl-core/pearl/releases/tag/1.5.1
[v152]: https://github.com/pearl-core/pearl/releases/tag/1.5.2
[v153]: https://github.com/pearl-core/pearl/releases/tag/1.5.3
[v154]: https://github.com/pearl-core/pearl/releases/tag/1.5.4
[v155]: https://github.com/pearl-core/pearl/releases/tag/1.5.5
[v156]: https://github.com/pearl-core/pearl/releases/tag/1.5.6
[v160]: https://github.com/pearl-core/pearl/releases/tag/1.6.0
[v161]: https://github.com/pearl-core/pearl/releases/tag/1.6.1
[v162]: https://github.com/pearl-core/pearl/releases/tag/1.6.2
[v163]: https://github.com/pearl-core/pearl/releases/tag/1.6.3
[v170]: https://github.com/pearl-core/pearl/releases/tag/1.7.0
[v171]: https://github.com/pearl-core/pearl/releases/tag/1.7.1
[v172]: https://github.com/pearl-core/pearl/releases/tag/1.7.2
[v180]: https://github.com/pearl-core/pearl/releases/tag/1.8.0
[v181]: https://github.com/pearl-core/pearl/releases/tag/1.8.1
[v182]: https://github.com/pearl-core/pearl/releases/tag/1.8.2
[v201]: https://github.com/pearl-core/pearl/releases/tag/2.0.1
[v202]: https://github.com/pearl-core/pearl/releases/tag/2.0.2
[v210]: https://github.com/pearl-core/pearl/releases/tag/2.1.0
[v211]: https://github.com/pearl-core/pearl/releases/tag/2.1.1
[v212]: https://github.com/pearl-core/pearl/releases/tag/2.1.2
[v220]: https://github.com/pearl-core/pearl/releases/tag/2.2.0
[v230]: https://github.com/pearl-core/pearl/releases/tag/2.3.0
[v231]: https://github.com/pearl-core/pearl/releases/tag/2.3.1
[v232]: https://github.com/pearl-core/pearl/releases/tag/2.3.2
[v233]: https://github.com/pearl-core/pearl/releases/tag/2.3.3
[v234]: https://github.com/pearl-core/pearl/releases/tag/2.3.4
[v235]: https://github.com/pearl-core/pearl/releases/tag/2.3.5
[v236]: https://github.com/pearl-core/pearl/releases/tag/2.3.6
