#task-runner #build #outputs #smart #run #script #hash

app faster-build

Simple and smart language-agnostic task runner

4 releases (breaking)

0.5.0 May 16, 2022
0.4.0 May 8, 2022
0.3.0 Apr 25, 2022
0.2.0 Apr 24, 2022

#1413 in Development tools

GPL-3.0-or-later

75KB
2K SLoC

Faster – Language-agnostic task runner

GitHub Actions workflow status Code coverage report Crates.io version

Faster is a language-agnostic task runner for repositories with many moving parts. It's meant to be simple and transparent, but very configurable for all sorts of purposes.

Faster is similar to make in that you can define targets and dependencies between them, but it will hash all your dependencies and selectively rerun only changed targets, intelligently run non-conflicting tasks in parallel, and keep recent build artifacts and logs around for you to inspect.

Oh, and it's fast.

Installation

Using asdf-vm:

asdf plugin add faster https://github.com/happenslol/asdf-faster
asdf install faster latest
asdf global faster latest

To install faster manually, you can download one of the binaries from the latest release and move it into your path:

# Make sure you have `jq` installed!
export FASTER_VERSION=curl -s https://api.github.com/repos/happenslol/faster/releases/latest | jq -r '.tag_name'
export FASTER_ARCH=x86_64-unknown-linux-musl
curl -Lo faster.tar.gz https://github.com/happenslol/faster/releases/download/${FASTER_VERSION}/faster-${FASTER_ARCH}.tar.gz
tar xvf faster.tar.gz
sudo mv faster /usr/local/bin/

You can also install faster through cargo:

cargo install faster-build --locked

Usage

Create a faster.yaml file in the root of your repository to configure your tasks. Here's an example file with explanations:

environment:
  # Globally set env variables for
  # all tasks that can be run
  FOO: "literal value"
  BAR: "${VALUE_FROM_HOST_ENV}"
  BAZ: "$(echo 'value from a command')"

tasks:
  generate:
    # Shell script which will generate your outputs
    script: |
      echo "Outputting code into testfile"
      echo "foo" > gen/my-output
      echo "Succeeded!"

    # Outputs that will be generated by your script
    # Globs are possible here
    outputs:
      - gen/**

    # Input files that should trigger a rerun of the task
    # Globs are possible here
    inputs:
      - go.mod
      - go.sum
      - ./**/*.go

  # Tasks without any outputs are also possible
  lint:
    script: ./run-linter.sh
    inputs:
      - ./**/*.go

  build:
    script: go build -o foo
    inputs:
      - ./**/*.go
      - go.mod
      - go.sum

    # Define other tasks that must be up-to-date before
    # this task can be run
    dependencies:
      - generate

    environment:
      # Set an env variable just for this task
      FOO: "bar"

  # Tasks without any outputs or files can be
  # used to group other tasks as a meta-target
  all:
    dependencies:
      - lint
      - build

With this config, faster run all will build a dependency graph and build all targets.

Run faster help to see all cli options.

Environment variables

You can set environment variables globally and per task that will be available in the task script. The values will be evaluated using the shell, which means that you can include commands using $(my_command) or defaults using ${FOO:-default}.

Note that the evaluated variables will be included in the hash, which means that global env variables should be used sparingly as they can invalidate all stored task results.

Contributing

Pull requests are welcome. For major changes, please open an issue first to discuss what you would like to change.

Please make sure to update tests as appropriate.

License

GPL 3.0

Dependencies

~10–20MB
~290K SLoC