Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Tuesday, March 31, 2026

List outdated packages in Python's pipx without upgrading

pipx does not currently provide a built in method of listing outdated packages. A short bash function shared in an open GitHub issue provides a workaround.

Introduction

I've been using pipx to manage my Python application for roughly three years. As the documentation states, "pipx installs and runs end-user Python apllications(and their respective dependencies) in isolated environments". I'm able to keep my pip list relatively clean as well as isolate my installed applications in separate virtual environments(venvs). Being able to minimize dependency conflicts has alleviated some of the headaches that previously came with installing all my applications and libraries via pip. Since I'm also using pyenv, I can also install them using different Python versions, if necessary.

I do, however, have one nit to pick with pipx. Currently, there is no way to check for available upgrades without actually performing the upgrades. That is, by running pipx upgrade-all and, potentially, upgrading all installed applications. This is time consuming as pipx needs to go through my entire list of installed applications and does not allow me to review upgradeable packages individually. pip has this functionality built in with the command pip list --outdated. There is also a separate package for managing pip package installations called pip-check which I use often and have installed via pipx.

Fortunately, a few years ago, I came across this issue: Feature request: Option to list available upgrades without performing them. While the issue remains open after almost seven years, there is some interesting discussion there as well a couple posts containing workable solutions. I've chosen to implement @StaticPH's comment as my preferred solution.

Solution


pipx-outdated() {
    # See: https://github.com/pypa/pipx/issues/149#issuecomment-684042303
    echo "OUTDATED PACKAGES:"
    while read -sr pyPkgName pyPkgVersion; do
        pyPkgURL="https://pypi.org/pypi/${pyPkgName}/json"
        pypi_latest="$(curl -sS "${pyPkgURL}" | jq --raw-output '.info.version')"
        [ "$pyPkgVersion" != "$pypi_latest" ] && printf "%s\n\tCurrent: \
        %s\tLatest: %s\n" "$pyPkgName" "$pyPkgVersion" "$pypi_latest"
    done <<( pipx list | grep -o 'package.*,' | tr -d ',' | cut -d ' ' -f 2- )
}

The pipx-outdated function greps through the output of pipx list to get the package name and its currently installed version. Next, using curl, it constructs the PyPi package URL and extracts the latest version from the available json file and compares the installed version to the latest. If there is a difference between the two, a list of outdated packages is print out to the console. While this function may ignore dev or alpha release, it is adequate for my use.

At this point, I can selectively upgrade the packages that I am interested or pass pipx upgrade only the packages I choose to upgrade at this time. Adding this to my .bash_aliases file allows me to run this whenever its needed.

Here's an example of the output of the pipx-outdated function showing two packages that have updates available.

  
    ~$ pipx-outdated
    OUTDATED PACKAGES:
    glances
        Current: 4.5.2  Latest: 4.5.3
    hike
        Current: 1.3.0  Latest: 1.4.0
  

I could choose either to upgrade a single package pipx upgrade ruff or I could upgrade both simultaneously with the command pipx upgrade glances ruff.

While it may be convenient to have this feature eventually integrated into the pipx package proper, I'm grateful to the folks who create and share solutions to paper-cuts as well as the developers who maintain and support the pipx package.

Resources

Saturday, January 31, 2026

Managing Ruby installations using rbenv and ruby-build

Installing rbenv and ruby-build on Debian-based systems to manage Ruby versions

"rbenv is a version manager tool for the Ruby programming language on Unix-like systems. It is useful for switching between multiple Ruby versions on the same machine and for ensuring that each project you are working on always runs on the correct Ruby version." -- rbenv's README

Introduction

In this article, I will provide steps to install and configure rbenv and ruby-build on a Debian-based Linux system.

Similar to other programming languages(e.g. Python, Perl, and Rust, etc.), I prefer to keep the version of Ruby I use separate from the version installed by my system. This includes any plugins, or packages(in Ruby's case gems). Aside from giving me more granular control, it also helps prevent me from potentially breaking my system by installing an incompatible version of the language.

I've chosen to use rbenv and ruby-build to provide me with a user-controlled environment in which to manage my Ruby installations. There are several other tools(e.g. rvm and asdf that provide similar functionality. My reasoning for selecting rbenv as my tool of choice is simple. I've been using pyenv for several years to manage my Python installations. Pyenv is a direct fork of rbenv, their developers contribute upstream to rbenv and has a familiar command set. Among other features, rbenv provides support for specifying application-specific Ruby versions(via the rbenv local command).

See rbenv's README for additional details on installation and functionality.

For additional information on rbenv, managing gems, or installing Ruby on Rails, take a look a the links provided in the Further Reading section.

Installation

Installing System Prerequisites

Before installing rbenv, we need to ensure that the system has some necessary dependencies installed. From the command line, enter the following commands:


sudo apt update
sudo apt install git curl libssl-dev \
    libreadline-dev zlib1g-dev autoconf \
    bison build-essential libyaml-dev \
    libreadline-dev libncurses5-dev \
    libffi-dev libgdbm-dev libsqlite3-dev

Depending on your system, you may already have some of these packages installed, or you may need to install additional dependencies. The output from sudo apt install should provide additional guidance. system.

Installing rbenv

  1. Clone rbenv into ~/.rbenv.
    • git clone https://github.com/rbenv/rbenv.git ~/.rbenv
  2. Configure your shell to load rbenv when starting the terminal:
    • echo 'export PATH="$HOME/.rbenv/bin:$PATH"' >> ~/.bashrc
    • echo 'eval"$(rbenv init - bash)"' >> ~/.bashrc
  3. Reload your shell configuration for changes to take effect. source ~/.bashrc

NOTE: If you are using a shell other than bash, replace ~/.bashrc in the above commands with the appropriate filename(e.g. ~/.zshrc or ~/.config/fish/config.fish)

Installing ruby-build

ruby-build will need to be installed to help compile Ruby binaries. Run the following commands to create a directory for the ruby-build plugin and then download it to the proper directory:


mkdir -p "$(rbenv root)"/plugins
git clone https://github.com/rbenv/ruby-build.git "$(rbenv root)"/plugins/ruby-build

Verifying installation

  1. Check installed version of rbenv

~$rbenv -v (or --version)
rbenv 1.3.2-16-gba96d7e

To check which version of Ruby is installed, use rbenv version(no dashes).

  1. Run rbenv-doctor

The rbenv-doctor script analyzes your system setup for common problems. Run this script to verify that the installation was successful.

curl -fsSL https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-doctor | bash

or

wget -q https://github.com/rbenv/rbenv-installer/raw/HEAD/bin/rbenv-doctor -O- | bash

Either of the commands should produce output similar to the following:


Checking for rbenv shims in PATH: OK
Checking `rbenv install' support: ~/.rbenv/plugins/ruby-build/bin/rbenv-install (ruby-build 20260121)
Counting installed Ruby versions: 1 versions
Auditing installed plugins: OK

For additional troubleshooting assistance, refer to the rbenv wiki

Installing Ruby

With rbenv installed, an updated list of the available Ruby versions can be viewed with the command:


rbenv install -l

#Output

3.2.10
3.3.10
3.4.8
4.0.1
jruby-10.0.2.0
mruby-3.4.0
picoruby-3.0.0
truffleruby-33.0.1
truffleruby+graalvm-33.0.1

Only latest stable releases for each Ruby implementation are shown. Use `rbenv install --list-all' to show all local versions.

As of this writing(20260128), the latest version of Ruby is 4.0.1.


    rbenv install 4.0.1 --verbose

This command should take roughly fifteen minutes to complete. Using the --verbose flag will produce output to the console so that the installation progress can be observed.

Set Default Ruby Version

Once Ruby is installed, set the default version using the global option:


rbenv global 4.0.1

Next, verify that Ruby was properly installed by checking its version number:


ruby --version

#Output

ruby 4.0.1 (2026-01-13 revision e04267a14b) +PRISM [x86_64-linux]

To install and use a different version of Ruby, run the rbenv commands with a different version number, such as rbenv install 3.4.8 and rbenv global 3.4.8.

Removing unneeded Ruby versions

The rbenv uninstall command can be used to remove old versions of Ruby that are no longer needed.


rbenv uninstall 4.0.1

Updating rbenv and ruby-build

Updating rbenv


cd ~/.rbenv
git pull

Updating ruby-build


cd ~/.rbenv
git -C plugins/ruby-build pull

Further Reading

rbenv alternatives

Tuesday, May 13, 2025

Adding GitHub labels using the gh CLI

A short guide and template for GitHub issue labels

Basic notes and template for creating labels for GitHub issues using the gh command line tool.

Jump directly to the new label template.

Introduction

This post is mostly about one command. Specifically, it's about one sub-command available with the gh CLI tool: gh label create. It's not because I think that it's a particularly interesting or complicated command. It's mostly because I rarely use the command infrequently and I need a reference for the "standard" that I have casually set up for myself. I work with git and gh commands daily. Many have been successfully committed to muscle memory. With other lengthy gh commands, I've turned a few of them into memorable aliases. I should probably make use of gh alias set; but, that's for another day.

As stated in GitHub's documentation on managing labels:

You can manage your work on GitHub by creating labels to categorize issues, pull requests, and discussions. You can apply labels in the repository the label was created in. Once a label exists, you can use the label on any issue, pull request, or discussion within that repository.

I only use the gh label create command when I create a new repository. The time between creating a new project varies from anywhere between a couple of weeks and several months. So, naturally, I tend to forget commands that haven't entered my muscle memory. With my projects using Python web frameworks, I've mostly standardized on my issue labels and can use the gh label clone command for these projects.

The GitHub organizations feature could also help facilitate the management of default labels across repositories. I, personally, have no plans on using it for now; but, it may be of use for some.

gh CLI label syntax

From the gh CLI manual:

  • USAGE

    • gh label [flags]
  • AVAILABLE COMMANDS

    • clone: Clones labels from one repository to another
    • create: Create a new label
    • delete: Delete a label from a repository
    • edit: Edit a label
    • list: List labels in a repository
  • FLAGS

    • -R, --repo [HOST/]OWNER/REPO Select another repository using the [HOST/]OWNER/REPO format

gh label create command format

gh label create <name> [flags]
gh label create <name> -d "description_string" -c "color_string"

Interlude: Color Selection

According to the gh manual, the label color needs to be specified as a six character hex value. Despite my working in desktop publishing and pre-press in a prior life, I don't have many hex color values memorized; so, I tend to rely on a color chart or a color picker application to help me in my color decisions. The availability of color charts and hex color codes on the internet is abundant. Plentiful even. There must be at least 10 color charts available online for reference. Here are two that I use frequently:

I'm also partial to using a locally installed color picker application. I've been using gcolor3 lately. It's simple and meets my basic needs. For alternatives, here is an OK list of other color picker applications available on Linux distros for installation:

Default Issue Labels

Label Name Description Color
bug Something isn't working #d73a4a
documentation Improvements/additions to documentation #0075ca
duplicate This issue or pull request already exists #cfd3d7
enhancement New feature of request #a2eeef
help wanted Extra attention is needed #008672
good first issue Good for newcomers #7057ff
invalid This doesn't seem right #e4e669
question Further information is requested #d876e3
wontfix This will not be worked on #ffffff

New Issue Labels

Label Name Description Color
build system Issues related to building and packaging #f95f13
deployment project release & publishing #52794f
performance Issues related to application performance #cb738a
security bug reports, fixes, vulnerability issues #7057ff
testing project testing & validation #5319e7

Cloning labels from another project

If there is a repository that has a set of labels that can be used as a template for a new project, one can clone all of its existing labels to the new project with the command:

gh label clone -f kevinbowen777/django-start

Issue Label Examples

If you want to be selective, the labels can be individually added as follows:

gh label create "build system" -c F95F13 -d "Issues related to building, packaging"
gh label create deployment -c 52794F -d "project release & publishing"
gh label create performance -c CB738A -d "Issues related to application performance"
gh label create security -c 7057ff -d "bug reports, fixes, vulnerability issues"
gh label create testing -c 5319e7 -d "project testing & validation"

Other examples of gh label usage

As you can see, my usage of issue labels is pretty simple. Here are a couple of examples of label usage in more complex projects:

gh aliases

Some frequently used gh commands that I have converted to bash aliases:

alias ghicb='gh issue create --label bug --assignee @me'
alias ghicd='gh issue create --label documentation --assignee @me'
alias ghice='gh issue create --label enhancement --assignee @me'
alias ghict='gh issue create --label testing --assignee @me'
alias ghil='gh issue list --limit 100'

Resources

Thursday, February 20, 2025

Rust and Cargo Cheat sheet

Installing Rust, its crates and how to keep them up to date

Jump to the rust and crate management section for a list of commonly used commands.

Introduction

A couple of years ago, I found a utility called bat that I wanted to try out and possibly use as a partial replacement to the venerable print and concatenation tool named cat. It was written in a program language called Rust which I had heard about in passing and was curious about its rising popularity. The version that was currently available for my Debian system, at the time, lagged a few versions behind the one that I had read about and lacked some of the features that had initially piqued my interest.

I was already using pyenv to manage my Python releases and, I wondered if I could do the same for Rust. I haven’t really had the time, or inclination to become a Rust programmer; but, there were some applications written in Rust that I wanted to use. I wasn’t planning on installing many applications or updating them very frequently, so I needed a place to keep commands that my muscle memory hadn’t yet absorbed.

That’s how this cheat sheet initally started.

This is a very brief guide for installing Rust and managing those crates(applications, packages, or libraries) for people who are not Rust developers and who do not use Rust on a daily basis. It is not intended as a tutorial(see the Resources section for helpful links).

Getting Started

  • The Rust Getting Started page is a good place to begin learning about Rust, its eco-system, and how to create new Rust projects. Here, I’m just going to focus on getting Rust installed and the basics of using cargo, the Rust package manager, to install and upgrade crates. I’ve only used the commands on this page with Debian Linux. So, if you have any issues using them, I would strongly recommend looking at the official Getting Started page for additional information.

Common Rust applications

  • rustc - Rust interpreter
  • rustup - Rust tool chain installer & version management tool
  • cargo - Rust build tool & package manager
  • crates.io - A Rust community registry of libraries and applications

Rust Installation

From your command prompt, run the following:

~$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

By installing this way, rustup will install itself, the Rust tool chain, as well as the cargo package manager. Rust can be uninstalled at any time using the rustup self uninstall command and these changes will be reverted.

Default directories

Rustup metadata and toolchains are installed into the Rustup home directory, located at ~/.rustup. This location can be modified with the RUSTUP_HOME environment variable.

The Cargo home directory is located at ~/.cargo. This location can be modified using the CARGO_HOME environment variable.

The cargo, rustc, rustup and other binaries are added to Cargo’s bin directory, located at ~/.cargo/bin.

Rust and crate management

Steps for upgrading Rust

  • Check the currently installed Rust version
    rustc -V
  • Update Rust
    rustup update
  • Update rustup
    rustup self update

Updating crates

As of Rust 1.41.0, cargo install <crate> will detect if a package is installed. It will upgrade if there is a newer version, or do nothing if the crate is considered up to date. The command will always uninstall, download, and compile the latest version of the crate - even if there is no newer version available.

The cargo-update crate

This crate creates a cargo subcommand for checking and applying updates to installed executables. It helps simplify crate management.

  • cargo-update home page
  • Install cargo-update
    cargo install cargo-update
  • Check for newer versions and update selected packages
    cargo install-update -a

Steps for installing and upgrading crates

  • List installed crates
    cargo install --list
    • Or, add an alias to .bashrc or bash_aliases:
      alias rust_list='cargo install --list
  • Install a crate
    cargo install <package_name>
  • Update all crates
    cargo install-update -a
  • Check for newer versions and update selected packages
    cargo install-update crate1 crate2 ...

Currently Installed Crates

Crates that I have currently on my system and find useful

  • bat A cat(1) clone with syntax highlighting and Git integration.
  • cargo Cargo downloads your Rust project’s dependencies and compiles your project.
  • cargo-update A cargo subcommand for checking and applying updates to installed executables
  • csview A high performance csv viewer with cjk/emoji support
  • htmlq A lightweight, command-line HTML processor
  • iamb A Matrix chat client that uses Vim keybindings
  • zizmor A Static analysis tool for GitHub Actions

Resources