Skip to content

Running Other Commands & Including .ENV Files - v0.11.0

Pre-release
Pre-release

Choose a tag to compare

@TekWizely TekWizely released this 23 Jan 01:13
· 11 commits to master since this release
7a52e08

About

Run is task runner that helps you easily manage and invoke small scripts and wrappers.

Do you find yourself using tools like make to manage non build-related scripts?

Build tools are great, but they are not optimized for general script management.

Run aims to be better at managing small scripts and wrappers, while incorporating a familiar make-like syntax.

What's Changed in v0.11.0

  • feat: Allow commands to RUN other commands (#63)
  • feat: Add support for Hidden and Private Commands (#64)
  • feat: Add support for RUN.ENV (#65)
  • feat: Add support for INCLUDE.ENV (#66)
  • feat: Use $RUNFILE in $RUNFILE_ROOTS Logic (#69)
  • feat: Explicitly make single-file INCLUDE optional
  • feat: Explicitly make .env includes required
  • bug: Sets config.CurrentRunfile for Primary runfile
  • bug: No-longer prints cmd not found error when Runfile could not be loaded.

Full Changelog: v0.10.0...v0.11.0

Running Other Commands

You can invoke other commands (with arguments) from your Runfile before or after your command executes:

Runfile

##
# RUN hello "Newman"
# RUN.AFTER goodbye
test:
    echo "How are you?"

hello:
    echo "Hello, ${1:-World}"

goodbye:
    echo "Goodbye, now"

output

$ run test

Hello, Newman
How are you?
Goodbye, now

Note: Any standard variable assignment value can be used (quoted strings, variable references, etc)

Exported Variables

Your command's exported environment variables are also exported to the invoked command:

exported variable example

##
# EXPORT NAME := "Newman"
# RUN hello
test:
    echo "Goodbye, now"

hello:
  echo "Hello, ${NAME:-world}"

output

$ run test

Hello, Newman
Goodbye, now

Notes:

  • RUN.BEFORE is also supported, and behaves just like RUN
  • Commands are invoked in the order they are defined
  • Your command only runs if all before commands return exit code zero (0)
  • After commands only run if your command returns exit code zero (0)
  • Execution halts if any RUN returns a non-zero exit code
  • You cannot invoke builtin commands (help, version, etc)

Setting Variables via RUN.ENV

A common occurrence in Runfiles is to have a central command which computes a set of variables, which is then invoked by multiple other commands that need to use those variables:

eval example

##
# export .RUN, .RUNFILE
test:
    eval $( "$RUN" newman )
    echo "Hello, ${HELLO:-World}"

## Generates script suitable for 'eval' by caller
newman:
    echo "HELLO=Newman"

This technique works well, but Run also supports a similar feature using RUN.ENV:

run.env example

##
# RUN.ENV newman
# ASSERT [ -n "${HELLO}" ] "HELLO not defined"
test:
    echo "Hello, ${HELLO:-World}"

## Generates output compatible with simplified .env assignments
newman:
    echo "# Let's say hi to Newman"
    echo "export HELLO=Newman"

output

$ run newman

# Let's say hi to Newman
export HELLO=Newman
$ run test

Hello, Newman

Notes:

  • RUN.ENV commands are run after EXPORTS
  • RUN.ENV commands are run before ASSERTS
  • Commands invoked via RUN.ENV are expected to generate relatively simple variable assignments
  • Run uses the subosito/gotenv library to parse command output
  • # comments are supported and will be safely ignored
  • export keyword is optional and will be safely ignored
  • Simple variable references in assignments are supported, but variables defined within your Runfile are not (currently) accessible - This may be addressed in a future release
  • Visit the gotenv project page to learn more about which .env features are supported

Including .ENV Files

.env files allow users to manage runfile configuration without modifying the Runfile directly.

Your Runfile can include .env files using the following syntax:

INCLUDE.ENV <file pattern> | "<file pattern>" | '<file pattern>'

Simple example:

Runfile.env

HELLO=Newman

Runfile

INCLUDE.ENV Runfile.env

##
# export HELLO
hello:
    echo "Hello, ${HELLO:-World}"

output

$ run hello

Hello, Newman

Notes:

  • Variables are immediately available, as if they had been defined in the same place in the Runfile.
  • Variables are not automatically exported.
  • Run uses the subosito/gotenv library to parse command output
  • # comments are supported and will be safely ignored
  • export keyword is optional and is (currently) ignored - This may be addressed in a future release
  • Simple variable references in assignments are supported, but variables defined within your Runfile are not (currently) accessible - This may be addressed in a future release
  • Visit the gotenv project page to learn more about which .env features are supported

File(s) Not Found

By default, Run considers it OK no .env file is found (using either a single filename or a globbing pattern).

To force an error if no file(s) are found, use !:

Runfile

INCLUDE.ENV ! Runfile-might-not-exist.env # ERROR if no file(s) found

Hidden / Private Commands

Hidden Commands

You can mark a command as Hidden using a leading .:

hidden command example

##
# Prints 'Hello, Newman', then 'Goodbye, now'
# RUN hello Newman
test:
    echo "Goodbye, now"

## Hello command is hidden
.hello:
    echo "Hello, ${1:-world}"

Hidden commands don't show up when listing commands:

list commands

$ run list

Commands:
  ...
  test       Prints 'Hello, Newman', then 'Goodbye, now'

But they can still be invoked by using their full name, with .:

run hidden command

$ run .hello

Hello, world

Private Commands

You can mark a command as Private using a leading !:

private command example

##
# Prints 'Hello, Newman', then 'Goodbye, now'
# RUN hello Newman
test:
    echo "Goodbye, now"

## Hello command is private
!hello:
    echo "Hello, ${1:-world}"

Private commands don't show up when listing commands:

list commands

$ run list

Commands:
  ...
  test       Prints 'Hello, Newman', then 'Goodbye, now'

And they cannot be invoked from outside the Runfile:

try to run private command

$ run hello

run: command not found: hello

$ run '!hello'

run: command not found: !hello