Skip to content

Releases: TekWizely/run

Bug: RUNFILE_ROOTS - v0.11.2

25 Feb 18:56
f9f22c9
Compare
Choose a tag to compare

Fixes a bug introduced in #69 which ended up breaking RUNFILE_ROOTS logic :(

See #73 for details of the bug and #74 for the PR

Thanks to @xkcd386at for reporting the issue !

Bug: Commands With Dash In Name - v0.11.1

24 Jan 17:09
8cd6243
Compare
Choose a tag to compare

This is quick bug-fix to re-enable support for commands with - in their names.

See #70 for details of the bug and #71 for the PR

Thanks to @brunk for reporting the issue !

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

23 Jan 01:13
7a52e08
Compare
Choose a tag to compare

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

Support Required Options; Support Default Option Values - v0.10.0

10 Nov 19:52
7d7ca43
Compare
Choose a tag to compare

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.10.0

  • feat: Support required options; Support default option values by @TekWizely in #62

Full Changelog: v0.9.1...v0.10.0

Making Options Required

You can now use ! to indicate that an option is required:

Runfile

##
# Hello world example.
# Prints "Hello, <name>".
# OPTION NAME! -n,--name <name> Name to say hello to
hello:
  echo "Hello, ${NAME}"

Required Indicator on Help Text

Required options will be indicated in help text:

$ run help hello

hello:
  Hello world example.
  Prints "Hello, <name>".
Options:
  -h, --help
        Show full help screen
  -n, --name <name> (required)
        Name to say hello to

Error When Required Option Not Provided

An error will be generated if a required option is not provided:

$ run hello

hello: ERROR: Missing required option:
  -n, --name <name>
        Name to say hello to

Providing A Default Option Value

You can now use ?= to specify a default value for an option, which will be used if the option is not provided:

# OPTION NAME ?= Newman -n,--name <name> Name to say hello to

The default value will be used if you invoke the command without explicitly providing the option:

output with default value

$ run hello

Hello, Newman

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

Default Indicator on Help Text

Default values will be indicated in help text:

  -n, --name <name> (default: Newman)

Boolean Default Option Values

You can specify a default value for boolean options, but they behave slightly different from standard options:

# OPTION NEWMAN ?= enabled --newman Say hello to Newman

Defaulted Value Always Assumed to be True

The content of the default value text is not used to determine the option's default true/false value.

Why?

Since boolean values are already always false by default, providing a "default value" can only have the effect of defaulting the value to true.

output with defaulted boolean option

$ run hello

Hello, Newman

Default Indicator on Help Text

Even though a boolean option with provided default is always assumed to default to true, the default value text is still useful in that it will be displayed in the help text:

  --newman (default: enabled)

This allows you to give better messaging than just "true" or "1" (i.e "enabled" in this example)

Misc

Explicitly Marking Options as "Optional"

Although options are already optional by default, you can now use ? to explicitly indicate that an option is optional:

# OPTION NAME? -n,--name <name> Name to say hello to

NOTE: This exists mostly for parity with ! and behaves the same as when it is not used

Includes; Overriding Commands; Easily Export Attributes; Mac Arm64 Binary - v0.9.0

04 Sep 00:18
5565ed9
Compare
Choose a tag to compare

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.9.0

Full Changelog: v0.8.0...v0.9.0

Mac ARM64 Binary

In addition to code changes, this release also introduces a darwin_arm64 binary in the pre-compiled assets.

Includes

Includes let you organize commands across multiple Runfiles.

Simple example:

file layout

Runfile
Runfile-hello

Runfile

INCLUDE Runfile-hello

Runfile-hello

hello:
    echo "Hello from Runfile-hello"

output

$ run hello

Hello from Runfile-hello

learn more

Overriding Commands

This release now allows you override commands, as long as they were originally registered in a different Runfile.

Runfile

## defined in Runfile
command1:
  echo command1 from Runfile

INCLUDE Runfile-include

## defined in Runfile
command2:
  echo command2 from Runfile

Runfile-include

## defined in Runfile-include
command1:
  echo command1 from Runfile-include

## defined in Runfile-include
command2:
  echo command2 from Runfile-include

list commands

$ run list

Commands:
  ...
  command1    defined in Runfile-include
  command2    defined in Runfile

Notice that the included runfile overrides command1, but the primary runfile overrides command2.

learn more

.RUNFILE.DIR, .SELF, .SELF.DIR

This release includes a few extra attributes to help Runfiles know where they exist in the file system. In addition to already present .RUNFILE attribute, we now also have:

Attribute Description
.RUNFILE Contains the absolute path of the primary Runfile.
.RUNFILE.DIR Contains the absolute path of the parent folder of the primary runfile.
.SELF Contains the absolute path of the current (primary or included) runfile.
.SELF.DIR Contains the absolute path of the parent folder of the current runfile.

Dynamic Content in Simple Titles

This release fixes a bug that now allows you to use dynamic data within simple one-line titles:

Runfile

EXPORT HELLO ?= "World"

## Prints "Hello, ${HELLO}"
hello:
    echo Hello, ${HELLO}

usage

$ HELLO=Newman run help hello

hello:
  Prints "Hello, Newman"

Easily Export Attributes

This release makes it easier to export attributes as variables for use in your own commands:

Simple Export

You can quickly export an attribute with a default variable name:

Runfile

EXPORT .RUNFILE, .RUNFILE.DIR

## Prints the value of .RUNFILE
runfile:
    echo "${RUNFILE}"

## Prints the value of .RUNFILE.DIR
runfile-dir:
    echo "${RUNFILE_DIR}"

With this technique, Run uses the attribute's name to determine the exported variable's name by:

  • Removing the leading . character
  • Substituting any remaining . characters with _

Export With Name

If you want to export an attribute with a non-default variable name, you can use the AS syntax:

EXPORT .RUNFILE     AS RF
EXPORT .RUNFILE.DIR AS RFD

## Prints the value of .RUNFILE
runfile:
    echo "${RF}"

## Prints the value of .RUNFILE.DIR
runfile-dir:
    echo "${RFD}"

Exit Codes; $RUNFILE; $RUNFILE_ROOTS - v0.8.0

11 Dec 08:13
0061dfd
Compare
Choose a tag to compare

What's Changed

  • run: Plumb the exit code of a command back to run by @rburchell in #35
  • exec: Provide a way to cleanup the temporary dir by @rburchell in #37
  • run: Show a better error on duplicate command by @rburchell in #38
  • feature: Adds support for RUNFILE env variable by @TekWizely in #40
  • feat(find runfile): Adds support for $RUNFILE_ROOTS path variable by @TekWizely in #41
  • refactor: Simplify messaging, remove calls to os.Exit and log.Fatal by @TekWizely in #42

Capture Command Exit Code

Runfile

exit:
	exit ${1:-0}

usage

run exit; echo $?
0

run exit 1; echo $?
1

run exit 127; echo $?
127

$RUNFILE Environment Variable

You can specify a runfile using the $RUNFILE environment variable:

$ export RUNFILE="/path/to/my/Runfile"

$ run <command>

For some other interesting uses of $RUNFILE, see:

NOTE: When specifying a runfile, the file does not have to be named "Runfile".

$RUNFILE_ROOTS Path Variable

You can instruct run to look up the directory path in search of a runfile.

You do this using the $RUNFILE_ROOTS path variable.

  • $RUNFILE_ROOTS is treated as a list of path entries (using standard os path separator)
  • Behaves largely similar to GIT_CEILING_DIRECTORIES
  • If $PWD is a child of a root entry, run walks-up looking for Runfile
  • Roots themselves are generally treated as exclusive (ie not checked)
  • $HOME, if a configured root, is treated as inclusive (ie it is checked)

general usage

export RUNFILE_ROOTS="${HOME}"  # Will walk up to $HOME (inclusively)

most permissive

export RUNFILE_ROOTS="/"  # Will walk up to / (exclusively)

NOTE: $HOME is given special treatment to support the case where a project is given its own user account and lives in the home folder of that user.

For the case of creating globally available tasks, see the Special Modes section.

New Contributors

Full Changelog: v0.7.2...v0.8.0

Assertions + Ignoring Script Lines - v0.7.2

15 Mar 23:35
d984f4f
Compare
Choose a tag to compare

Changelog

0da0b32 Add support for assertions (#33)
a73a61a Add ability to ignore script lines (#34)

Assertions

Assertions let you check against expected conditions, exiting with an error message when checks fail.

Assertions have the following syntax:

ASSERT <condition> [ "<error message>" | '<error message>' ]

Note: The error message is optional and will default to "Assertion failed" if not provided

Condition

The following condition patterns are supported:

  • [ ... ]
  • [[ ... ]]
  • ( ... )
  • (( ... ))

Assertion Example

Runfile

##
# Not subject to any assertions
world:
	echo Hello, World

# Assertion applies to ALL following commands
ASSERT [ -n "${HELLO}" ] "Variable HELLO not defined"

##
# Subject to HELLO assertion, even though it doesn't use it
newman:
	echo Hello, Newman

##
# Subject to HELLO assertion, and adds another
# ASSERT [ -n "${NAME}" ] 'Variable NAME not defined'
name:
	echo ${HELLO}, ${NAME}

example with no vars

$ run world

Hello, World

$ run newman

run: Variable HELLO not defined

$ run name

run: Variable HELLO not defined

example with HELLO

$ HELLO=Hello run newman

Hello, Newman

$ HELLO=Hello run name

run: Variable NAME not defined

example with HELLO and NAME

$ HELLO=Hello NAME=Everybody run name

Hello, Everybody

Note: Assertions only apply to commands and are only checked when a command is invoked. Any globally-defined assertions will apply to ALL commands defined after the assertion.

Ignoring Script Lines

You can use a # on the first column of a command script to ignore a line:

Runfile

hello:
    # This comment WILL be present in the executed command script
    echo "Hello, Newman"
# This comment block WILL NOT be present in the executed command script
#   echo "Hello, World"
    echo "Goodbye, now"

Note: Run detects and skips these comment lines when parsing the runfile, so the # will work regardless of what language the script text is written in (i.e even if the target language doesn't support # for comments).

No Empty Command Scripts - v0.7.1

09 Feb 20:21
8ab62c8
Compare
Choose a tag to compare
Pre-release

Changelog

c0a123e Errors on empty command script
53fdc75 Adds line:col to parse errors; Adds TokenUnknownRune
9537f38 Updates install section for brew and compiled binaries
5f20709 Adds NPM Package + Updates README
8fefa67 Adds an Archlinux PKGBUILD (#2)
bbeca28 Adds Archlinux Installation Info to README
9a1b3bb Add Archlinux installation info

No Empty Command Scripts

Adds a check to ensure that command scripts are not empty.

Runfile

##
# Empty command script 
empty:

hello:
    echo "Hello, World"

output

$ run hello

run: 5.0: command 'empty' contains an empty script.

.RUN & .RUNFILE - v0.7.0

06 Jan 01:19
9870a67
Compare
Choose a tag to compare
Pre-release

Changelog

4cd9fd0 Adds .RUN and .RUNFILE attributes (#21)
584e19b Renames version as run-version in shebang mode (#19)
5eda761 Makes .SHELL available for read (#17)
e466d2a Makes attributes available to command exports (#15)
14598e7 Adds brew core section to README
3792b87 Updates version string wit[h] BuildTool/builder
0c9ebbe Adds initial goreleaser config

.RUN & .RUNFILE Attributes

Adds .RUN and .RUNFILE attributes to make it possible to invoke other commands / runfiles from within your command script.

Runfile

##
# Invokes hello
# EXPORT RUN := ${.RUN}
# EXPORT RUNFILE := ${.RUNFILE}
test:
    "${RUN}" -r "${RUNFILE}" hello
hello:
    echo "Hello, World"

output

$ run test

Hello, World

Breaking Changes

This release is considered a breaking change since it now resolves the absolute path of the Runfile and uses that to process the file.

Version Command : v0.6.5

23 Dec 05:06
07daf00
Compare
Choose a tag to compare
Pre-release

This release adds a version command (already prepped for v0.6.5)

$ run version

run v0.6.5

NOTE: There are no feature changes - If you have installed v0.6.2 or later, then there is no need to grab this version.