User Tools

Site Tools


pub:tech:dosh

# dosh - The Simplest Build Tool on Earth

dosh is a minimal task runner pattern for shell scripts. Each dosh script is a standalone bash file where functions become tasks you can run from the command line.

Based on [8gears/do](https://github.com/8gears/do).

## How It Works

A dosh script defines functions, then uses `“$@“` to execute whatever function name is passed as an argument:

```bash #!/usr/bin/env bash

build() {

  echo "Building..."

}

test() {

  echo "Testing..."

}

“$@” ```

Run it with: ```bash ./dosh build # runs build() ./dosh test # runs test() ```

## Sample Script

A complete sample dosh script is available: [dosh.sh](dosh.sh)

## Convention: Private Functions

Functions starting with `_` are considered private/helper functions and won't appear in usage output or tab completion:

```bash _helper() {

  echo "I'm a helper"

}

build() {

  _helper
  echo "Building..."

} ```

## Usage Output

Add this at the end of your dosh script to show available tasks when run without arguments:

```bash “$@” [ “$#” -gt 0 ] || printf “Usage:\n\t./${SCRIPTNAME} %s\n” ”($(compgen -A function | grep '^[^_]' | paste -sd '|' -))” ```

## Tab Completion

### Bash

Add the `–completions` handler to your dosh script, just before the `“$@“` line:

```bash if "$1" == "--completions"; then

  compgen -A function | grep '^[^_]'
  exit 0

fi

“$@” ```

Then add this to your `~/.bashrc`:

```bash _dosh_complete() {

  local cur="${COMP_WORDS[COMP_CWORD]}"
  local script="${COMP_WORDS[0]}"
  COMPREPLY=($(compgen -W "$($script --completions 2>/dev/null)" -- "$cur"))

} complete -F _dosh_complete dosh complete -F _dosh_complete ./dosh ```

After reloading your shell (`source ~/.bashrc`), tab completion will work: ```bash ./dosh bu<TAB> # completes to ./dosh build ```

### Zsh

The same `–completions` handler in your dosh script works for zsh. Add this to your `~/.zshrc`:

```zsh _dosh_complete() {

  local completions
  completions=(${(f)"$($words[1] --completions 2>/dev/null)"})
  _describe 'tasks' completions

} compdef _dosh_complete dosh compdef _dosh_complete ./dosh ```

## direnv Integration

A common pattern is to put dosh in `bin/dosh` and add `bin` to your PATH using direnv. This lets you run `dosh build` instead of `./bin/dosh build` from anywhere in the project.

Example `.envrc`: ```bash PATH_add bin ```

See [envrc](https://code.librehq.com/james/envrc) for a more complete direnv setup.

With this pattern, add a completion registration for `dosh` (without the `./`):

```bash complete -F _dosh_complete dosh # bash compdef _dosh_complete dosh # zsh ```

## Tips

- Root access: Functions needing root should check for it and fail early - Working directory: Use `BASEDIR` to ensure consistent paths regardless of where the script is invoked from - Dependencies: Consider a `deps` or `setup-dev` task to install required tools

pub/tech/dosh.txt · Last modified: by james

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki