Skip to main content

No project description provided

Project description

Barrel

Python command line tools that are easy to install, repo-isolated, and update themselves.

Users install your package with:

$ curl -sSL https://barrel.dev/install.py | python3 - <pypi_package_name>

And update it with:

$ <cli_name> update

Overview

Python can be a great language for writing command line tools, but your users shouldn't have to be Python experts to use them.

For tools that are globally installed, people tend to do things like pip install --user <package>, write a custom installation script, or install and use a wrapper like pipx.

This works when you intend to use the same version of the CLI no matter what you're working on. But there are other things like static site generators and automation tools that should be installed specifically into a user's repository. The version installed needs to be isolated and pinned, so you can use the same tools on multiple repos/projects without worrying about update conflicts and forcing them all to use the same version.

There are obviously ways to deal with this today (see alternatives), but they all require a certain amount of Python-ecosystem knowledge that your users may not have. Especially if your CLI is written in Python, but the user doesn't actually use Python when interacting with it.

What Barrel is

Barrel is an installation script, embeddable package, and set of conventions for installing an isolated and versioned command line tool into a repo. As a bonus, Barrel makes it easy for you to have a self-updating CLI.

The goal is to simplify the process (especially for non-Pythonistas) and provide a developer experience that doesn't suck. It does this by being a lightweight wrapper around standard, known conventions that can be used as a "one-liner".

Using well-known conventions like requirements.txt also allows standard CI/CD workflows and other services/tools to "just work", without knowing or caring about Barrel itself. This makes it automatically compatible with hosting services like Netlify, and dependency management automation like Dependabot.

How Barrel works

The initial install of a command line tools is done with a script. A curl -> Python command is the easiest way to do this, and doesn't require any additional dependencies besides Python 3 (which your CLI requires anyway).

$ curl -sSL https://barrel.dev/install.py | python3 - <pypi_package_name>

This will create a virtual environment at .venv and requirements.txt file. The .venv should be in .gitignore but the requirements.txt should be committed. The install script will help point out these details for people that aren't familiar with them.

The requirements.txt file will look something like this and effectively "pins" the version in use until an update is made:

# This file is managed automatically by <package>
<package>==2.3.0

Once installed, updates can be done two ways.

  1. Barrel is integrated into the package/CLI itself, providing a command like <package> update. This is the most user-friendly way to do it, since they already have your CLI installed and don't have to remember or save the curl command.
  2. But if you don't include Barrel in your package, you can always run the curl command again to update the package (using the --reinstall option).

The only caveat at this point is that .venv/bin/ needs to be in the user's PATH, or they need to use ./.venv/bin/<package> directly. The install script will help point this out and how it can be done (ex. export PATH="./.venv/bin:$PATH").

Barrel for package authors

To use Barrel for the installation process, you just need a published package that is your CLI.

You can copy install.py to your own repo or site, but the we always keep an up-to-date hosted version at https://barrel.dev/install.py.

Your documentation should tell users how to use the curl command (including your package name as the argument).

$ curl -sSL https://barrel.dev/install.py | python3 - <pypi_package_name>

You should add "barrel" as a dependency in your package and provide a self-updating experience. To do this, you just need to call the update function with the name of your package. You can add it to your CLI like this example using click:

import barrel


@click.command()
def update():
    """Update your version of combine"""
    barrel.update("combine")

If you don't add "barrel" as a dependency, then you'll need to tell users to run the curl command again to update with the --reinstall option.

$ curl -sSL https://barrel.dev/install.py | python3 - <pypi_package_name> --reinstall

Things to know:

  • Barrel supports Python 3 only
  • Barrel expects your package to be the only direct dependency the user needs to install (i.e. their requirements.txt will only end up with your package in it -- nothing else)
  • Barrel expects your package to have an entrypoint (by default this should be the same as the package name)

What Barrel doesn't do

The primary goal of Barrel is to simplify the dependency installation/update process for people. So it shouldn't come as a surprise that certain features you know from full-fledged dependency managers are intentionally missing.

Freeze all dependency requirements

The requirements.txt won't include all of the pinned versions of indirect/transitive dependencies. While that would help with the predictability of an install, those details don't (and arguably shouldn't) matter to most people and can cause a lot of noise in automated dependency update tools.

If you're authoring a package that uses Barrel, you should take extra care to specify the ranges of your dependencies that you know work, and put a CI process in place to regularly test a fresh install just like your users would get.

Lock to a specific Python version

Barrel won't save the Python version it used during the install, and it won't force everyone on the repo to use the same Python version.

Managing multiple Python versions is not for everyone. There are tools and ways to do it, but it can get complicated fast.

Barrel only works with Python 3 since Python 2 was sunset in 2020. This makes it easier.

Similar to the point on frozen requirements, it should be the package authors responsiblity to define the range of Python3 versions you support and to make sure they work. Use a matrix in your CI tests to stay on top of it.

Alternatives

pip by itself

Barrel is a wrapper around standard pip processes and conventions, so you can obviously do the same thing with pip directly. The problem is, there are a series of steps that people either have to already know or have scripted. There are a lot of decisions to make along the way and you can easily lose people just by having an overly complicated install process for someone who isn't familiar with Python.

Barrel essentially does these steps for a new install:

$ python3 -m venv .venv
$ ./.venv/bin/pip install <package>
$ ./.venv/bin/pip freeze | grep <package> > requirements.txt

These steps for a fresh install of an existing repo:

$ python3 -m venv .venv
$ ./.venv/bin/pip install -r requirements.txt

And these steps for update:

$ ./.venv/bin/pip install -U <package>
$ ./.venv/bin/pip freeze | grep <package> > requirements.txt

Barrel makes the install step (new or existing) a curl one-liner, and the update step as simple as <package> update.

pipx

On the surface, pipx is pretty similar in goals. The difference is that pipx is aimed at tools that are installed globally on a user's machine. This is not exactly what you want if your package needs to be versioned to a specific user's repo.

If you try to use a globally installed command across multiple repos, you run into problems when a new version of the command is released and new features are added/removed that aren't compatible with all of your repos (build command changed syntax, YAML config settings changed, etc.). The only solution you have is to update all of them at once, which can be a pretty unpleasant experience depending on the changes required.

poetry, pipenv, etc.

In a lot of ways, Barrel is intended to be a simpler alternative to these. Both Poetry and Pipenv can be used for installing a specific version of a Python package into a repo. But they come with a lot of other baggage that you simply don't need for a single-dependency repo.

Both require you to install the tool itself first (which is a process of its own), and can force other decisions like locking to a specific Python version, new commands to learn, and extra headaches if poetry/pipenv themselves break! Which does happen (surprisinglyg frequently in the case of Pipenv) and can require a lot of difficult troubleshooting. Barrel largely avoids this by doing basic pip commands and requirements.txt flows that are unlikely to have any problems.

Project details


Download files

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

Source Distribution

barrel-0.3.0.tar.gz (9.9 kB view details)

Uploaded Source

Built Distribution

barrel-0.3.0-py3-none-any.whl (9.1 kB view details)

Uploaded Python 3

File details

Details for the file barrel-0.3.0.tar.gz.

File metadata

  • Download URL: barrel-0.3.0.tar.gz
  • Upload date:
  • Size: 9.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.13 CPython/3.10.2 Linux/5.11.0-1028-azure

File hashes

Hashes for barrel-0.3.0.tar.gz
Algorithm Hash digest
SHA256 b3c5cd79ebebc8e35d2dbf0a3ad4f5a01297100f0c87c0d44de6b87b344fd61f
MD5 37350dd5cf181877c8e92b5dc05d1422
BLAKE2b-256 cc7ee14d3af8e97beedb0508f2a0bdf8786c55c84b23fe73ac4fe043fba7f7ac

See more details on using hashes here.

File details

Details for the file barrel-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: barrel-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 9.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: poetry/1.1.13 CPython/3.10.2 Linux/5.11.0-1028-azure

File hashes

Hashes for barrel-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 12b9aafe5b76b807b8e56cf7ee53792ea6f09186a29b357a78d2114b33c1e935
MD5 32fd8d8b1277b5d0bc07483ab8c5340b
BLAKE2b-256 559f35f15f97d01b6aab97f8b6eaae13e77d052f0cf7220ce14bb13cee5ebb8d

See more details on using hashes here.

Supported by

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