Automatically provide external dependencies for software projects

LanguagesRust🦀
Version1.0.3
# Enter a shell with external dependencies provided
riff shell
# Run a command with dependencies provided
riff run cargo build

Riff

Introduction

Riff is a tool that automatically provides external dependencies for software projects. To enter a shell environment with all your project's external dependencies installed, run this at the project root:

riff shell

You can also directly run commands with the shell environment applied but without entering the shell:

riff run cargo build

Supported languages

Riff currently supports Rust projects. Support for other languages will be added soon, so stay tuned for updates.

What Riff provides

Most programming languages use language-specific package managers to handle dependencies, such as Cargo for the Rust language. But these language-specific tools typically don't handle dependencies written in other languages so well. They expect you to install those dependencies using some other tool and fail in mysterious ways when they're missing. Here's an example error from trying to build the octocrab crate without OpenSSL installed:

--- stderr
thread 'main' panicked at '

Could not find directory of OpenSSL installation, and this `-sys` crate cannot
proceed without this knowledge. If OpenSSL is installed and this crate had
trouble finding it,  you can set the `OPENSSL_DIR` environment variable for the
compilation process.

Make sure you also have the development packages of openssl installed.
For example, `libssl-dev` on Ubuntu or `openssl-devel` on Fedora.

In cases like this, it's up to you to install missing external dependencies, which can be laborious, error prone, and hard to reproduce.

Riff enables you to bypass this problem entirely. It uses your project's language-specific configuration to infer which external dependencies are required and creates a shell environment with those dependencies both installed and properly linked. In cases where those dependencies can't be inferred, for example in your build.rs script, you can explicitly declare them in your Cargo.toml.

These environments are transient in the sense that they don't affect anything outside the shell; they install dependencies neither globally nor in your current project, so you don't have to worry about Riff breaking anything on your system. When you exit the Riff shell, the dependencies are gone.

Example usage

In this example, we'll build the Prost project from source. Prost has an external dependency on OpenSSL, without which commands like cargo build and cargo run are doomed to fail. Riff provides those dependencies automatically, without you needing to install them in your regular environment. Follow these steps to see dependency inference in action:

git clone https://github.com/tokio-rs/prost.git
cd prost

# Enter the Riff shell environment
riff shell
# ✓ 🦀 rust: cargo, cmake, curl, openssl, pkg-config, rustc, rustfmt, zlib

# Check for the presence of openssl
which openssl
# The path should look like this:
# /nix/store/f3xbf94zykbh6drw6wfg9hdrfgwrkck7-openssl-1.1.1q-bin/bin/openssl
# This means that Riff is using the Nix-provided openssl

# Build the project
cargo build

# Leave the shell environment
exit

# Check for openssl again
which openssl
# This should either point to an openssl executable on your PATH or fail

Copyright © 2023 Determinate Systems