#source #shell #direnv

bin+lib sauce

A tool for managing directory-specific state

16 releases (5 breaking)

0.6.6 Feb 22, 2021
0.6.5 Feb 15, 2021
0.5.1 Feb 1, 2021
0.5.0 Jan 27, 2021
0.0.1 Dec 23, 2020

#313 in Command line utilities

Download history 42/week @ 2021-01-14 28/week @ 2021-01-21 26/week @ 2021-01-28 79/week @ 2021-02-04 108/week @ 2021-02-11 48/week @ 2021-02-18 5/week @ 2021-02-25 20/week @ 2021-03-04 1/week @ 2021-03-11 1/week @ 2021-03-18 64/week @ 2021-03-25 16/week @ 2021-04-01 16/week @ 2021-04-08 37/week @ 2021-04-15 9/week @ 2021-04-22 20/week @ 2021-04-29

136 downloads per month

Apache-2.0 and GPL-3.0-only

99KB
2.5K SLoC

Sauce

license Version info Build Status

The central truth is the central truth, and nothing that I care about is relative

A tool to help manage context/project specific shell-things like environment variables.

Table of Contents

Example Workflow

# Suppose you've got some directory structure
❯ mkdir -p projects/foo
❯ cd projects

# In "projects", you want some shorthand for quickly pushing your branches
❯ sauce new
Created /Users/danc/.local/share/sauce/projects.toml

❯ sauce set alias push='git push origin "$(git rev-parse --abbrev-ref HEAD)"'
Setting push = git push origin "$(git rev-parse --abbrev-ref HEAD)"

# Your project is, naturally, using 12-factor methodology, so you've got some
# project specific environment variables you need to load!
❯ cd foo
❯ sauce set env foo=bar AWS_PROFILE=meow
Setting foo = bar
Setting AWS_PROFILE = meow

# The core purpose!
❯ sauce
Sourced ~/.local/share/sauce/projects/foo.toml

❯ env
...
AWS_PROFILE=meow
foo=bar

# Note the cascaded loading of upstream values!
❯ push

Setup

Install

With Cargo

  • cargo install sauce

Download Release

  • Download Linux/Mac binary from Releases

Shell Hook

Currently explicitly supported shells include: zsh, bash, and fish. The scaffolding exists to support other shells, which should make supporting other common shells that might require "$SHELL" specific behavior.

Loading things into the environment requires a minimal amount of shell code to be executed, so after installing the binary (suggestion below), you will need to add add a hook to your bashrc/zshrc/config.fish, etc.

  • bash eval "$(sauce --shell bash shell init)"
  • zsh eval "$(sauce --shell zsh shell init)"
  • fish sauce --shell fish shell init | source

Depending on the level of similarity to the above shells, you may be able to get away with using one of the above shell init hooks until explicit support is added

Targets

A thing which sauce can load/unload is called a “target”.

Currently supported targets include:

  • environment variables

    sauce set env FOO=bar
    
  • aliases

    sauce set alias g=git
    
  • functions

    sauce set function add 'echo $(expr $1 + $2)'
    

Features

sauce command

This is primary usecase is the sauce command, no subcommand, no arguments. This loads the current shell with all sauce targets (env vars, aliases, and function) which apply to the current directory.

There are also a bunch of options to allow you to customize the behavior of sauce, for example sauce --glob DATABASE*, sauce --filter env:AWS_PROFILE, or sauce --path ~.

Central Storage

The original motivation for central storage was due to getting a new computer and needing to comb through ~50 repos to find all the random .env files and gitignored notes and whatnot littered all over the place to make sure nothing got left behind.

However just generally, colocating the sauce data with the actual folder introduces a number of technical, security, and usability issues that are circumvented through central storage.

Cascaded loading

A key feature of sauce is that values are loaded in a cascading fashion relative to the home directory.

This makes it easier to compose targets (env vars, aliases, and shell functions) among various locations, likely by utilizing the natural directory structure you might already have.

Given a directory structure

~/
  work/
    project/
      repo/
      repo2/
        src/
    otherproject/

Support you run sauce at any folder level/depth, say ~/work/project/repo/. The values saved for the folders: ~, ~/work, ~/work/project, and ~/work/project/repo will all be loaded.

The more specific/deep folder’s values will take precedence over the values of more general/shallow folders.

All saucefiles are located in the $XDG_DATA_HOME/sauce folder, after which the folder structure mirrors that of the folders who’s values are being tracked. Given the above example, if every folder had a saucefile, you might see:

~/.local/share/
  sauce.toml
  sauce/
    project.toml
    project/
      repo.toml
      repo2.toml
      repo2/
        src.toml
    otherproject.toml

Autoloading

See the Configuration Reference on autoload-hook and autoload.

Local development

For local development, it can be useful to enable the --feature dev. This alters the behavior so that the shell hook(s) point to the absolute location of the debug build.

An example alias that might be helpful could be:

[alias]
build = 'cargo build --features dev && eval "$(./target/debug/sauce shell init)"'

At which point, you’re a quick build away from being able to cd around to test sauce, while always pointing at your project version of sauce for the current shell.

Dependencies

~7.5MB
~135K SLoC