{"id":13537658,"url":"https://github.com/TekWizely/run","last_synced_at":"2025-04-02T04:31:16.428Z","repository":{"id":36348511,"uuid":"195097834","full_name":"TekWizely/run","owner":"TekWizely","description":"Task runner that helps you easily manage and invoke small scripts and wrappers","archived":false,"fork":false,"pushed_at":"2023-09-25T21:38:00.000Z","size":301,"stargazers_count":475,"open_issues_count":13,"forks_count":9,"subscribers_count":9,"default_branch":"master","last_synced_at":"2024-05-01T16:42:22.568Z","etag":null,"topics":["golang-application","make","makefile","run","runfile","scripting","task-runner","wrappers"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TekWizely.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-03T17:16:13.000Z","updated_at":"2024-05-28T07:26:13.332Z","dependencies_parsed_at":"2024-05-28T07:37:58.485Z","dependency_job_id":null,"html_url":"https://github.com/TekWizely/run","commit_stats":null,"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TekWizely%2Frun","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TekWizely%2Frun/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TekWizely%2Frun/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TekWizely%2Frun/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TekWizely","download_url":"https://codeload.github.com/TekWizely/run/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246757169,"owners_count":20828848,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang-application","make","makefile","run","runfile","scripting","task-runner","wrappers"],"created_at":"2024-08-01T09:01:01.734Z","updated_at":"2025-04-02T04:31:11.419Z","avatar_url":"https://github.com/TekWizely.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# Run: Easily manage and invoke small scripts and wrappers\n\n![GitHub repo size](https://img.shields.io/github/repo-size/TekWizely/run)\u003c!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section --\u003e\n[![All Contributors](https://img.shields.io/badge/all_contributors-5-orange.svg?style=flat-square)](#contributors-)\u003c!-- ALL-CONTRIBUTORS-BADGE:END --\u003e\n![GitHub stars](https://img.shields.io/github/stars/TekWizely/run?style=social)\n![GitHub forks](https://img.shields.io/github/forks/TekWizely/run?style=social)\n\nDo you find yourself using tools like `make` to manage non-build-related scripts?\n\nBuild tools are great, but they are not optimized for general script management.\n\nRun aims to be better at managing small scripts and wrappers, while incorporating a familiar make-like syntax.\n\n#### Runfile\n\nWhere make has the ubiquitous Makefile, run has the cleverly-named `\"Runfile\"`\n\nBy default, run will look for a file named `\"Runfile\"` in the current directory, exiting with error if not found.\n\nRead below for details on specifying alternative runfiles, as well as other special modes you might find useful.\n\n#### Commands\n\nIn place of make's targets, runfiles contain `'commands'`.\n\nSimilar to make, a command's label is used to invoke it from the command-line.\n\n#### Scripts\n\nInstead of recipes, each runfile command contains a `'script'` which is executed when the command is invoked.\n\nYou might be used to make's (default) behavior of executing each line of a recipe in a separate sub-shell.\n\nIn run, the entire script is executed within a single sub-shell.\n\n\n#### TOC\n\n- [Examples](#examples)\n- [Special Modes](#special-modes)\n- [Installing](#installing)\n- [Contributing](#contributing)\n- [Contact](#contact)\n- [License](#license)\n- [Just Looking for Bash Arg Parsing?](#just-looking-for-bash-arg-parsing)\n\n\n-----------\n## Examples\n\n - [Simple Command Definitions](#simple-command-definitions)\n   - [Naming Commands](#naming-commands)\n - [Simple Title Definitions](#simple-title-definitions)\n - [Title \u0026 Description](#title--description)\n - [Arguments](#arguments)\n - [Command-Line Options](#command-line-options)\n   - [Making Options Required](#making-options-required)\n   - [Providing A Default Option Value](#providing-a-default-option-value)\n   - [Boolean (Flag) Options](#boolean--flag--options)\n   - [Getting `-h` \u0026 `--help` For Free](#getting--h----help-for-free)\n   - [Passing Options Directly Through to the Command Script](#passing-options-directly-through-to-the-command-script)\n - [Run Tool Help](#run-tool-help)\n - [Using an Alternative Runfile](#using-an-alternative-runfile)\n   - [Via Command-Line](#via-command-line)\n   - [Via Environment Variables](#via-environment-variables)\n     - [`$RUNFILE`](#runfile-1)\n       - [Using Direnv](#using-direnv-to-auto-configure-runfile)\n     - [`$RUNFILE_ROOTS`](#runfileroots)\n - [Runfile Variables](#runfile-variables)\n   - [Local By Default](#local-by-default)\n   - [Exporting Variables](#exporting-variables)\n     - [Per-Command Variables](#per-command-variables)\n     - [Exporting Previously-Defined Variables](#exporting-previously-defined-variables)\n     - [Pre-Declaring Exports](#pre-declaring-exports)\n       - [Forgetting To Define An Exported Variable](#forgetting-to-define-an-exported-variable)\n   - [Referencing Other Variables](#referencing-other-variables)\n   - [Shell Substitution](#shell-substitution)\n   - [Conditional Assignment](#conditional-assignment)\n - [Runfile Attributes](#runfile-attributes)\n   - [`.SHELL`](#runfile-attributes)\n   - [`.RUN`](#runfile-attributes)\n   - [`.RUNFILE`](#runfile-attributes)\n   - [`.RUNFILE.DIR`](#runfile-attributes)\n   - [`.SELF`](#runfile-attributes)\n   - [`.SELF.DIR`](#runfile-attributes)\n   - [Exporting Attributes](#exporting-attributes)\n     - [Simple Export](#simple-export)\n     - [Export With Name](#export-with-name)\n - [Assertions](#assertions)\n - [Includes](#includes---runfiles)\n   - [File Globbing](#file-globbing)\n   - [Working Directory](#working-directory)\n   - [Required vs Optional](#file--s--not-found)\n   - [Avoiding Include Loops](#avoiding-include-loops)\n   - [Overriding Commands](#overriding-commands)\n     - [Cannot Re-Register Command In Same Runfile](#cannot-re-register-command-in-same-runfile)\n     - [Overrides Are Case-Insensitive](#overrides-are-case-insensitive)\n     - [First Registered Command Defines Case For Help](#first-registered-command-defines-case-for-help)\n     - [First Registered Command Defines Default Documentation](#first-registered-command-defines-default-documentation)\n     - [Commands Are Listed In The Order They Are Registered](#commands-are-listed-in-the-order-they-are-registered)\n - [Includes - .ENV](#includes---env)\n   - [Required vs Optional](#file--s--not-found-1)\n - [Invoking Other Commands \u0026 Runfiles](#invoking-other-commands--runfiles)\n   - [RUN / RUN.AFTER / RUN.ENV Actions](#run--runafter--runenv-actions)\n   - [.RUN / .RUNFILE Attributes](#run--runfile-attributes)\n - [Hidden / Private Commands](#hidden--private-commands)\n   - [Hidden Commands](#hidden-commands)\n   - [Private Commands](#private-commands)\n - [Script Shells](#script-shells)\n   - [Per-Command Shell Config](#per-command-shell-config)\n   - [Global Default Shell Config](#global-default-shell-config)\n   - [Other Executors](#other-executors)\n     - [Python Example](#python-example)\n   - [Custom `#!` Support](#custom--support)\n     - [C Example](#c-example)\n\n------------------------------\n### Simple Command Definitions\n\n_Runfile_\n\n```\nhello:\n  echo \"Hello, world\"\n```\n\nWe'll see that `hello` shows as an invokable command, but has no other help text.\n\n_list commands_\n\n```\n$ run list\n\nCommands:\n  list       (builtin) List available commands\n  help       (builtin) Show help for a command\n  version    (builtin) Show run version\n  hello\n```\n\n_show help for hello command_\n```\n$ run help hello\n\nhello: no help available.\n```\n\n_invoke hello command_\n```\n$ run hello\n\nHello, world\n```\n\n#### Naming Commands\n\nRun accepts the following pattern for command names:\n\n```\nalpha ::= 'a' .. 'z' | 'A' .. 'Z'\ndigit ::= '0' .. '9'\n\nCMD_NAME ::= [ alpha | '_' ] ( [ alpha | digit | '_' | '-' ] )*\n```\n\nSome examples:\n* `hello`\n* `hello_world`\n* `hello-world`\n* `HelloWorld`\n\n##### Case Sensitivity\n\n###### Registering Commands\n\nWhen registering commands, run treats the command name as case-insensitive and subject to [command override](#overriding-commands) rules.\n\n*case-insensitive override example*\n\nFor example, run will generate an error if a command name is defined multiple times in the same runfile, even if the names use different cases:\n\n_Runfile_\n```\nhello-world:\n  echo \"Hello, world\"\n\nHELLO-WORLD:\n  echo \"HELLO, WORLD\"\n```\n\n_list commands_\n\n```\n$ run list\n\nrun: Runfile: command hello-world defined multiple times in the same file: lines 1 and 4\n```\n\n###### Invoking Commands\n\nWhen invoking commands, run treats the command name as case-insensitive:\n\n_Runfile_\n```\nHello-World:\n  echo \"Hello, world\"\n```\n\n_output_\n```\n$ run Hello-World\n$ run Hello-world\n$ run hello-world\n\nHello, world\n```\n\n###### Displaying Help\n\nWhen displaying help text, run displays command names as they are originally defined:\n\n_list commands_\n\n```\n$ run list\n\nCommands:\n  ...\n  Hello-World\n  ...\n```\n\n_show help for Hello-World command_\n```\n$ run help hello-world\n\nHello-World: no help available.\n```\n\n----------------------------\n### Simple Title Definitions\n\nWe can add a simple title to our command, providing some help content.\n\n_Runfile_\n\n```\n## Hello world example.\nhello:\n  echo \"Hello, world\"\n```\n\n_output_\n\n```\n$ run list\n\nCommands:\n  list       (builtin) List available commands\n  help       (builtin) Show help for a command\n  version    (builtin) Show run version\n  hello      Hello world example.\n  ...\n```\n\n```\n$ run help hello\n\nhello:\n  Hello world example.\n```\n\n-----------------------\n### Title \u0026 Description\n\nWe can further flesh out the help content by adding a description.\n\n_Runfile_\n\n```\n##\n# Hello world example.\n# Prints \"Hello, world\".\nhello:\n  echo \"Hello, world\"\n```\n\n_output_\n\n```\n$ run list\n\nCommands:\n  list       (builtin) List available commands\n  help       (builtin) Show help for a command\n  version    (builtin) Show run version\n  hello      Hello world example.\n  ...\n```\n\n```\n$ run help hello\n\nhello:\n  Hello world example.\n  Prints \"Hello, world\".\n```\n\n-------------\n### Arguments\n\nPositional arguments are passed through to your command script.\n\n_Runfile_\n\n```\n##\n# Hello world example.\nhello:\n  echo \"Hello, ${1}\"\n```\n\n_output_\n\n```\n$ run hello Newman\n\nHello, Newman\n```\n\n------------------------\n### Command-Line Options\n\nYou can configure command-line options and access their values with environment variables.\n\n_Runfile_\n\n```\n##\n# Hello world example.\n# Prints \"Hello, \u003cname\u003e\".\n# OPTION NAME -n,--name \u003cname\u003e Name to say hello to\nhello:\n  echo \"Hello, ${NAME}\"\n```\n\n_output_\n\n```\n$ run help hello\n\nhello:\n  Hello world example.\n  Prints \"Hello, \u003cname\u003e\".\nOptions:\n  -h, --help\n        Show full help screen\n  -n, --name \u003cname\u003e\n        Name to say hello to\n```\n\n```\n$ run hello --name=Newman\n$ run hello -n Newman\n\nHello, Newman\n```\n\n#### Making Options Required\n\nYou can use `!` to indicate that an option is required:\n\n```\n# OPTION NAME! -n,--name \u003cname\u003e Name to say hello to\n```\n\n##### Required Indicator on Help Text\n\nRequired options will be indicated in help text:\n\n```\n  -n, --name \u003cname\u003e (required)\n        Name to say hello to\n```\n\n##### Error When Required Option Not Provided\n\nAn error will be generated if a required option is not provided:\n\n```\nhello: ERROR: Missing required option:\n  -n, --name \u003cname\u003e\n        Name to say hello to\n```\n\n#### Explicitly Marking Options as \"Optional\"\n\nAlthough options are already *optional* by default, you can use `?` to explicitly indicate that an option is optional:\n\n```\n# OPTION NAME? -n,--name \u003cname\u003e Name to say hello to\n```\n\n**NOTE**: This exists mostly for parity with `!` and behaves the same as when it is not used\n\n#### Providing A Default Option Value\n\nYou can use `?=` to specify a default value for an option, which will be used if the option is not provided:\n\n```\n# OPTION NAME ?= Newman -n,--name \u003cname\u003e Name to say hello to\n```\n\n_output_\n\n```\n$ run hello\n\nHello, Newman\n```\n\n**Note**: Any standard variable assignment value can be used (quoted strings, variable references, etc)\n\n##### Default Indicator on Help Text\n\nDefault values will be indicated in help text:\n\n```\n  -n, --name \u003cname\u003e (default: Newman)\n```\n\n#### Boolean (Flag) Options\n\nDeclare flag options by omitting the `'\u003c...\u003e'` segment.\n\n_Runfile_\n\n```\n##\n# Hello world example.\n# OPTION NEWMAN --newman Say hello to Newman\nhello:\n  NAME=\"World\"\n  [[ -n \"${NEWMAN}\" ]] \u0026\u0026 NAME=\"Newman\"\n  echo \"Hello, ${NAME}\"\n```\n\n_output_\n\n```\n$ run help hello\n\nhello:\n  Hello world example.\n  ...\n  --newman\n        Say hello to Newman\n```\n\n##### Boolean Default Option Values\n\nYou can specify a default value for boolean options, but they behave slightly different from standard options:\n\n```\n# OPTION NEWMAN ?= enabled --newman Say hello to Newman\n```\n\n###### Defaulted Value Always Assumed to be True\n\nThe content of the default value text is not used to determine the option's default true/false value.\n\nWhy?\n\nSince boolean values are already *always* `false` by default, providing a \"default value\" can *only* have the effect of defaulting the value to `true`.\n\n_output_\n\n```\n$ run hello\n\nHello, Newman\n```\n\n###### Default Indicator on Help Text\n\nEven 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:\n\n```\n  --newman (default: enabled)\n```\n\nThis allows you to give better messaging than just \"true\" or \"1\" (i.e \"enabled\" in this example)\n\n##### Setting a Flag Option to TRUE\n\n```\n$ run help --newman=true # true | True | TRUE\n$ run help --newman=1    # 1 | t | T\n$ run help --newman      # Empty value = true\n$ run help               # Default value = true if option has ?=\n\nHello, Newman\n```\n\n##### Setting a Flag Option to FALSE\n\n```\n$ run help --newman=false # false | False | FALSE\n$ run help --newman=0     # 0 | f | F\n$ run help                # Default value = false if option does not have ?=\n\nHello, World\n\n```\n\n#### Getting `-h` \u0026 `--help` For Free\n\nIf your command defines one or more options, but does not explicitly configure options `-h` or `--help`, then they are automatically registered to display the command's help text.\n\n_Runfile_\n```\n##\n# Hello world example.\n# Prints \"Hello, world\".\nhello:\n  echo \"Hello, world\"\n```\n\n_output_\n```\n$ run hello -h\n$ run hello --help\n\nhello:\n  Hello world example.\n  Prints \"Hello, world\".\n```\n\n#### Passing Options Directly Through to the Command Script\n\nIf your command does not define any options within the Runfile, then run will pass all command line arguments directly through to the command script.\n\n_Runfile_\n```\n##\n# Echo example\n# Prints the arguments passed into the script\n#\necho:\n  echo script arguments = \"${@}\"\n```\n\n_output_\n```\n$ run echo -h --help Hello Newman\n\nscript arguments = -h --help Hello Newman\n```\n\nNOTE: As you likely surmised, help options (`-h` \u0026 `--help`) are not automatically registered when the command does not define any other options.\n\n##### What if My Command Script DOES Define Options?\n\nIf your command script does define one or more options within the Runfile, you can still pass options directly through to the command script, but the syntax is a bit different:\n\n_Runfile_\n```\n##\n# Echo example\n# Prints the arguments passed into the script\n# Use -- to separate run options from script options\n# OPTION ARG -a \u003carg\u003e Contrived argument\n#\necho:\n  echo ARG = \"${ARG}\"\n  echo script arguments = \"${@}\"\n```\n\n_output_\n```\n$ run echo -a my-arg -- -h --help Hello Newman\n\nARG = my-arg\nscript arguments = -h --help Hello Newman\n```\n\nNotice the `'--'` in the argument list - Run will stop parsing options when it encounters the `'--'` and pass the rest of the arguments through to the command script.\n\n-----------------\n### Run Tool Help\n\nInvoking `-h` or `--help` with no command shows the help page for the run tool itself.\n\n```\n$ run --help\n\nUsage:\n       run \u003ccommand\u003e [option ...]\n          (run \u003ccommand\u003e)\n  or   run list\n          (list commands)\n  or   run help \u003ccommand\u003e\n          (show help for \u003ccommand\u003e)\nOptions:\n  -r, --runfile \u003cfile\u003e\n        Specify runfile (default='${RUNFILE:-Runfile}')\n        ex: run -r /my/runfile list\nNote:\n  Options accept '-' | '--'\n  Values can be given as:\n        -o value | -o=value\n  Flags (booleans) can be given as:\n        -f | -f=true | -f=false\n  Short options cannot be combined\n```\n\n--------------------------------\n### Using an Alternative Runfile\n\n#### Via Command Line\n\nYou can specify a runfile using the `-r | --runfile` option:\n\n```\n$ run --runfile /path/to/my/Runfile \u003ccommand\u003e\n```\n\nNOTE: When specifying a runfile, the file does **not** have to be named `\"Runfile\"`.\n\n#### Via Environment Variables\n\n##### $RUNFILE\n\nYou can specify a runfile using the `$RUNFILE` environment variable:\n\n```\n$ export RUNFILE=\"/path/to/my/Runfile\"\n\n$ run \u003ccommand\u003e\n```\n\nFor some other interesting uses of `$RUNFILE`, see:\n* [Invoking Other Commands \u0026 Runfiles](#invoking-other-commands--runfiles)\n* [Using direnv to auto-configure $RUNFILE](#using-direnv-to-auto-configure-runfile)\n\nNOTE: When specifying a runfile, the file does **not** have to be named `\"Runfile\"`.\n\n##### $RUNFILE_ROOTS\n\nYou can instruct run to look _up_ the directory path in search of a runfile.\n\nYou do this using the `$RUNFILE_ROOTS` path variable.\n\n* `$RUNFILE_ROOTS` is treated as a list of path entries (using standard os path separator)\n* Behaves largely similar to [GIT_CEILING_DIRECTORIES](https://git-scm.com/docs/git#Documentation/git.txt-codeGITCEILINGDIRECTORIEScode)\n* If `$PWD` is a child of a root entry, then run will walk up the folder hierarchy, checking each folder for the currently-configured Runfile.\n* Roots themselves are generally treated as _exclusive_ (ie not checked)\n* `$HOME`, if a configured root, is treated as _inclusive_ (ie it **is** checked)\n\n_general usage_\n\n    export RUNFILE_ROOTS=\"${HOME}\"  # Will walk up to $HOME (inclusively)\n\n_most permissive_\n\n    export RUNFILE_ROOTS=\"/\"  # Will walk up to / (exclusively)\n\nNOTE: `$HOME` is given special treatment to support the case where a project is given its own _user_ account and the Runfile lives in the _home_ folder of that user.\n\nFor the case of creating globally available tasks, see the [Special Modes](#special-modes) section.\n\n---------------------\n### Runfile Variables\n\nYou can define variables within your runfile:\n\n_Runfile_\n```\nNAME := \"Newman\"\n\n##\n# Hello world example.\n# Tries to print \"Hello, ${NAME}\"\nhello:\n  echo \"Hello, ${NAME:-world}\"\n```\n\n#### Local By Default\n\nBy default, variables are local to the runfile and are not part of your command's environment.\n\nFor example, you can access them within your command's description:\n\n```\n$ run help hello\n\nhello:\n  Hello world example.\n  Tries to print \"Hello, Newman\"\n```\n\nBut not within your commands script:\n\n```\n$ run hello\n\nHello, world\n```\n\n#### Exporting Variables\n\nTo make a variable available to your command script, you need to `export` it:\n\n_Runfile_\n```\nEXPORT NAME := \"Newman\"\n\n##\n# Hello world example.\n# Tries to print \"Hello, ${NAME}\"\nhello:\n  echo \"Hello, ${NAME:-world}\"\n```\n\n_output_\n```\n$ run hello\n\nHello, Newman\n```\n\n##### Per-Command Variables\n\nYou can create variables on a per-command basis:\n\n_Runfile_\n```\n##\n# Hello world example.\n# Prints \"Hello, ${NAME}\"\n# EXPORT NAME := \"world\"\nhello:\n  echo \"Hello, ${NAME}\"\n```\n\n_help output_\n```\n$ run help hello\n\nhello:\n  Hello world example.\n  Prints \"Hello, world\"\n```\n\n_command output_\n\n```\n$ run hello\n\nHello, world\n```\n\n##### Exporting Previously-Defined Variables\n\nYou can export previously-defined variables by name:\n\n_Runfile_\n```\nHELLO := \"Hello\"\nNAME  := \"world\"\n\n##\n# Hello world example.\n# EXPORT HELLO, NAME\nhello:\n  echo \"${HELLO}, ${NAME}\"\n```\n\n##### Pre-Declaring Exports\nYou can declare exported variables before they are defined:\n\n_Runfile_\n```\nEXPORT HELLO, NAME\n\nHELLO := \"Hello\"\nNAME  := \"world\"\n\n##\n# Hello world example.\nhello:\n  echo \"${HELLO}, ${NAME}\"\n```\n\n###### Forgetting To Define An Exported Variable\nIf you export a variable, but don't define it, you will get a `WARNING`\n\n_Runfile_\n```\nEXPORT HELLO, NAME\n\nNAME := \"world\"\n\n##\n# Hello world example.\nhello:\n  echo \"Hello, ${NAME}\"\n```\n\n_output_\n```\n$ run hello\n\nrun: WARNING: exported variable not defined: 'HELLO'\nHello, world\n```\n\n#### Referencing Other Variables\n\nYou can reference other variables within your assignment:\n\n_Runfile_\n```\nSALUTATION := \"Hello\"\nNAME       := \"Newman\"\n\nEXPORT MESSAGE := \"${SALUTATION}, ${NAME}\"\n\n##\n# Hello world example.\nhello:\n  echo \"${MESSAGE}\"\n```\n\n#### Shell Substitution\n\nYou can invoke sub-shells and capture their output within your assignment:\n\n_Runfile_\n```\nSALUTATION := \"Hello\"\nNAME       := \"$( echo 'Newman )\" # Trivial example\n\nEXPORT MESSAGE := \"${SALUTATION}, ${NAME}\"\n\n##\n# Hello world example.\nhello:\n  echo \"${MESSAGE}\"\n```\n\n#### Conditional Assignment\n\nYou can conditionally assign a variable, which only assigns a value if one does not already exist.\n\n_Runfile_\n```\nEXPORT NAME ?= \"world\"\n\n##\n# Hello world example.\nhello:\n  echo \"Hello, ${NAME}\"\n```\n\n_example with default_\n```\n$ run hello\n\nHello, world\n```\n\n_example with override_\n```\nNAME=\"Newman\" run hello\n\nHello, Newman\n```\n\n----------------------\n### Runfile Attributes\n\nAttributes are special variables used by the Run engine.\n\nTheir names start with `.` to avoid colliding with [runfile variables](#runfile-variables) and environment variables.\u003cbr/\u003e\n\nFollowing is the list of Run's attributes:\n\n| Attribute      | Description                                                                                                                                         |\n|----------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|\n| `.SHELL`       | Contains the shell command that will be used to execute command scripts. See [Script Shells](#script-shells) for more details.                      |\n| `.RUN`         | Contains the absolute path of the run binary currently in use. Useful for [Invoking Other Commands \u0026 Runfiles](#invoking-other-commands--runfiles). |\n| `.RUNFILE`     | Contains the absolute path of the **primary** Runfile.                                                                                              |\n| `.RUNFILE.DIR` | Contains the absolute path of the parent folder of the **primary** runfile.                                                                         |\n| `.SELF`        | Contains the absolute path of the **current** (primary or included) runfile.                                                                        |\n| `.SELF.DIR`    | Contains the absolute path of the parent folder of the **current** runfile.                                                                         |\n\n#### Exporting Attributes\n\nIn order to access an attribute's value within your commands, you'll need to assign them to an [exported variable](#exporting-variables).\n\nOlder versions of Run required you to use a variable assignment:\n\n_Runfile_\n```\nEXPORT RUNFILE     := ${.RUNFILE}\nEXPORT RUNFILE_DIR := ${.RUNFILE.DIR}\n\n## Prints the value of .RUNFILE\nrunfile:\n    echo \"${RUNFILE}\"\n\n## Prints the value of .RUNFILE.DIR\nrunfile-dir:\n    echo \"${RUNFILE_DIR}\"\n```\n\nNewer versions of Run now support less verbose options:\n\n##### Simple Export\n\nYou can quickly export an attribute with a default variable name:\n\n_Runfile_\n```\nEXPORT .RUNFILE, .RUNFILE.DIR\n\n## Prints the value of .RUNFILE\nrunfile:\n    echo \"${RUNFILE}\"\n\n## Prints the value of .RUNFILE.DIR\nrunfile-dir:\n    echo \"${RUNFILE_DIR}\"\n```\n\nWith this technique, Run uses the attribute's name to determine the exported variable's name by:\n* Removing the leading `.` character\n* Substituting any remaining `.` characters with `_`\n\n##### Export With Name\n\nIf you want to export an attribute with a non-default variable name, you can use the `AS` syntax:\n\n```\nEXPORT .RUNFILE     AS RF\nEXPORT .RUNFILE.DIR AS RFD\n\n## Prints the value of .RUNFILE\nrunfile:\n    echo \"${RF}\"\n\n## Prints the value of .RUNFILE.DIR\nrunfile-dir:\n    echo \"${RFD}\"\n```\n\n--------------\n### Assertions\n\nAssertions let you check against expected conditions, exiting with an error message when checks fail.\n\nAssertions have the following syntax:\n\n```\nASSERT \u003ccondition\u003e [ \"\u003cerror message\u003e\" | '\u003cerror message\u003e' ]\n```\n\n*Note:* The error message is optional and will default to `\"assertion failed\"` if not provided\n\n#### Condition\n\nThe following condition patterns are supported:\n\n* `[  ...  ]`\n* `[[ ... ]]`\n* `(  ...  )`\n* `(( ... ))`\n\n*Note:* Run does not interpret the condition.  The condition text will be executed, unmodified (including surrounding braces/parens/etc), by the configured shell. Run will inspect the exit status of the check and pass/fail the assertion accordingly.\n\n#### Assertion Example\n\nHere's an example that uses both global and command-level assertions:\n\n_Runfile_\n```\n##\n# Not subject to any assertions\nworld:\n\techo Hello, World\n\n# Assertion applies to ALL following commands\nASSERT [ -n \"${HELLO}\" ] \"Variable HELLO not defined\"\n\n##\n# Subject to HELLO assertion, even though it doesn't use it\nnewman:\n\techo Hello, Newman\n\n##\n# Subject to HELLO assertion, and adds another\n# ASSERT [ -n \"${NAME}\" ] 'Variable NAME not defined'\nname:\n\techo ${HELLO}, ${NAME}\n```\n\n_example with no vars_\n```\n$ run world\n\nHello, World\n\n$ run newman\n\nrun: ERROR: Runfile:7: Variable HELLO not defined\n\n$ run name\n\nrun: ERROR: Runfile:7: Variable HELLO not defined\n```\n\n_example with HELLO_\n```\n$ HELLO=Hello run newman\n\nHello, Newman\n\n$ HELLO=Hello run name\n\nrun: ERROR: Runfile:16: Variable NAME not defined\n```\n\n_example with HELLO and NAME_\n```\n$ HELLO=Hello NAME=Everybody run name\n\nHello, Everybody\n```\n\n*Note:* Assertions apply only to commands and are only checked when a command is invoked.  Any globally-defined assertions will apply to ALL commands defined after the assertion.\n\n-----------------------\n### Includes - Runfiles\n\nIncludes let you organize and configure commands across multiple Runfiles.\n\nYou can include other Runfiles using the following syntax:\n```\nINCLUDE \u003cfile pattern\u003e | \"\u003cfile pattern\u003e\" | '\u003cfile pattern\u003e'\n```\n\nSimple example:\n\n_file layout_\n```\nRunfile\nRunfile-hello\n```\n\n_Runfile_\n```\nINCLUDE Runfile-hello\n```\n\n_Runfile-hello_\n```\nhello:\n    echo \"Hello from Runfile-hello\"\n```\n\n_output_\n```\n$ run hello\n\nHello from Runfile-hello\n```\n\n#### File Globbing\n\nRun utilizes [goreleaser/fileglob](https://github.com/goreleaser/fileglob) in order support file globbing for includes.\n\nAccording to their README, `fileglob` supports:\n\n* Asterisk wildcards (`*`)\n* Super-asterisk wildcards (`**`)\n* Single symbol wildcards (`?`)\n* Character list matchers with negation and ranges (`[abc]`, `[!abc]`, `[a-c]`)\n* Alternative matchers (`{a,b}`)\n* Nested globbing (`{a,[bc]}`)\n* Escapable wildcards (`\\{a\\}/\\*`)\n\n**Fileglob Example:**\n\n_file layout_\n```\nRunfile\n1/1/Runfile-1\n2/2/Runfile-2\n3/3/Runfile-3\n```\n\n_Runfile_\n```\nINCLUDE **/Runfile-*\n```\n\n#### Working Directory\n\nInclude names / glob-patterns are resolved relative to the Primary runfile's containing directory.\n\n#### File(s) Not Found\n\n##### Default: OK For Glob\n\nWhen using a globbing pattern, Run considers it OK if the pattern results in no files being found.\n\nThis makes it possible to support features like an optional Runfile include directory, or the ability to start a project folder with no includes but have them automatically picked up as you add them.\n\n_Runfile_\n```\nINCLUDE maybe_some_runfiles/Runfile-*  # OK if no files found\n```\n\n##### Force Error If No Files Found\n\nTo force an error if no files are found when using a globbing pattern, use `!` :\n\n_Runfile_\n```\nINCLUDE ! maybe_some_runfiles/Runfile-*  # ERROR if no files found\n```\n\n##### Default: BAD For Single File\n\nWhen using a single filename (no globbing), Run considers it an error if the include file is not found.\n\n_Runfile_\n```\nINCLUDE Runfile-must-exist  # Errors if file not found\n```\n\n_output_\n```\n$ run list\n\nrun: include runfile not found: 'Runfile-must-exist'\n```\n\n##### Skip Error If File Not Found\n\nTo skip generating an error if no file is found when using a single filename, use `?` :\n\n_Runfile_\n```\nINCLUDE ? Runfile-might-exist  # OK if file not found\n```\n\n#### Avoiding Include Loops\n\nRun keeps track of already-included runfiles and will silently avoid including the same runfile multiple times.\n\n_Runfile_\n```\nINCLUDE Runfile-hello\nINCLUDE Runfile-hello  # Silently skipped\n```\n\n#### Overriding Commands\n\nRun allows you override commands, as long as they were originally registered in a _different_ Runfile.\n\n_Runfile_\n```\n## defined in Runfile\ncommand1:\n  echo command1 from Runfile\n\nINCLUDE Runfile-include\n\n## defined in Runfile\ncommand2:\n  echo command2 from Runfile\n```\n\n_Runfile-include_\n```\n## defined in Runfile-include\ncommand1:\n  echo command1 from Runfile-include\n\n## defined in Runfile-include\ncommand2:\n  echo command2 from Runfile-include\n```\n\n_list commands_\n```\n$ run list\n\nCommands:\n  ...\n  command1    defined in Runfile-include\n  command2    defined in Runfile\n```\n\nNotice that the _included_ runfile overrides `command1`, but the _primary_ runfile overrides `command2`.\n\n##### Cannot Re-Register Command In Same Runfile\n\nRun will error when attempting to register a command multiple times within the _same_ Runfile:\n\n_Runfile_\n```\nhello-world:\n  echo \"Hello, world\"\n\nhello-world:\n  echo \"Hello, world\"\n```\n\n_list commands_\n```\n$ run list\n\nrun: Runfile: command hello-world defined multiple times in the same file: lines 1 and 4\n```\n\n##### Overrides Are Case-Insensitive\n\nRun's override matching is case-insensitive:\n\n_Runfile_\n```\n## defined in Runfile\ncommand1:\n  echo command1 from Runfile\n\ninclude Runfile-include\n```\n\n_Runfile-include_\n```\n## defined in Runfile-include\nCOMMAND1:\n  echo command1 from Runfile-include\n```\n\n_list commands_\n```\n$ run list\n\nCommands:\n  ...\n  command1    defined in Runfile-include\n```\n\nNotice that `COMMAND1` from the _included_ runfile overrides `command1` from the _primary_ runfile.\n\n###### First Registered Command Defines Case For Help\n\nRun keeps track of the original case used when a command is first registered, and uses it when displaying help:\n\n_Runfile_\n```\n## defined in Runfile\nCOMMAND1:\n  echo command1 from Runfile\n\ninclude Runfile-include\n```\n\n_Runfile-include_\n```\n## defined in Runfile-include\ncommand1:\n  echo command1 from Runfile-include\n```\n\n_list commands_\n```\n$ run list\n\nCommands:\n  ...\n  COMMAND1    defined in Runfile-include\n```\n\nNotice that the displayed name comes from the original registration in the _primary_ runfile.\n\n##### First Registered Command Defines Default Documentation\n\nRun keeps track of the title \u0026 description when a command is first registered, and uses it if an overriding command does not define its own documentation:\n\n_Runfile_\n```\n## title defined in Runfile\ncommand1:\n  echo command1 from Runfile\n\ninclude Runfile-include\n```\n\n_Runfile-include_\n```\ncommand1:\n  echo command1 from Runfile-include\n```\n\n_list commands_\n```\n$ run list\n\nCommands:\n  ...\n  commmand1    title defined in Runfile\n```\n\n_command output_\n```\n$ run command1\n\ncommand1 from Runfile-include\n```\n\nNotice that, even though `command1` from the _included_ runfile was invoked, the displayed title comes from the original registration in the _primary_ runfile.\n\n##### Commands Are Listed In The Order They Are Registered\n\nRun keeps track of the _order_ in which commands are registered, and maintains that order even if a command is later overridden:\n\n_Runfile_\n```\n## defined in Runfile\ncommand1:\n  echo command1 from Runfile\n\n## defined in Runfile\ncommand2:\n  echo command2 from Runfile\n\n## defined in Runfile\ncommand3:\n  echo command3 from Runfile\n\ninclude Runfile-include\n```\n\n_Runfile-include_\n```\n## defined in Runfile-include\ncommand2:\n  echo command2 from Runfile-include\n```\n\n_list commands_\n```\n$ run list\n\nCommands:\n  ...\n  command1    defined in Runfile\n  command2    defined in Runfile-include\n  command3    defined in Runfile\n```\n\nNotice that `command2` is still shown _between_ `command1` and `command3`, matching the order in which it was originally registered.\n\n-------------------\n### Includes - .ENV\n\n`.env` files allow users to manage runfile configuration without modifying the Runfile directly.\n\nYour Runfile can include .env files using the following syntax:\n```\nINCLUDE.ENV \u003cfile pattern\u003e | \"\u003cfile pattern\u003e\" | '\u003cfile pattern\u003e'\n```\n\nSimple example:\n\n_Runfile.env_\n```\nHELLO=Newman\n```\n\n_Runfile_\n```\nINCLUDE.ENV Runfile.env\n\n##\n# export HELLO\nhello:\n    echo \"Hello, ${HELLO:-World}\"\n```\n\n_output_\n```\n$ run hello\n\nHello, Newman\n```\n\n*Notes:*\n* Variables are immediately available, as if they had been defined in the same place in the Runfile.\n* Variables are not automatically exported.\n* Run uses the [subosito/gotenv](https://github.com/subosito/gotenv) library to parse command output\n* `#` comments are supported and will be safely ignored\n* `export` keyword is optional and is (currently) ignored - This may be addressed in a future release\n* 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\n* Visit the [gotenv project page](https://github.com/subosito/gotenv) to learn more about which `.env` features are supported\n\n#### File(s) Not Found\n\nBy default, Run considers it OK no .env file is found (using either a single filename or a globbing pattern).\n\nTo force an error if no file(s) are found, use `!`:\n\n_Runfile_\n```\nINCLUDE.ENV ! Runfile-might-not-exist.env # ERROR if no file(s) found\n```\n\n--------------------------------------\n### Invoking Other Commands \u0026 Runfiles\n\n#### RUN / RUN.AFTER / RUN.ENV Actions\n\nYou can invoke other commands (with arguments) from your Runfile before or after your command executes:\n\n_Runfile_\n```\n##\n# RUN hello \"Newman\"\n# RUN.AFTER goodbye\ntest:\n    echo \"How are you?\"\n\nhello:\n    echo \"Hello, ${1:-World}\"\n\ngoodbye:\n    echo \"Goodbye, now\"\n```\n\n_output_\n```\n$ run test\n\nHello, Newman\nHow are you?\nGoodbye, now\n```\n\n*Note*: Any standard variable assignment value can be used (quoted strings, variable references, etc)\n\n##### Exported Variables\n\nYour command's exported environment variables are also exported to the invoked command:\n\n_exported variable example_\n```\n##\n# EXPORT NAME := \"Newman\"\n# RUN hello\ntest:\n    echo \"Goodbye, now\"\n\nhello:\n  echo \"Hello, ${NAME:-world}\"\n```\n\n_output_\n```\n$ run test\n\nHello, Newman\nGoodbye, now\n```\n\n*Notes*:\n* `RUN.BEFORE` is also supported, and behaves just like `RUN`\n* Commands are invoked in the order they are defined\n* Your command only runs if all previous RUN commands return exit code zero (0)\n* _After_ commands only run if your command returns exit code zero (0)\n* Execution halts if *any* RUN returns a non-zero exit code\n* You cannot invoke _builtin_ commands (help, version, etc)\n\n#### Setting Variables via RUN.ENV\n\nA 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:\n\n_eval example_\n```\n##\n# export .RUN, .RUNFILE\ntest:\n    eval $( \"$RUN\" newman )\n    echo \"Hello, ${HELLO:-World}\"\n\n## Generates script suitable for 'eval' by caller\nnewman:\n    echo \"HELLO=Newman\"\n```\n\nThis technique works well, but Run also supports a similar feature using `RUN.ENV`:\n\n_run.env example_\n```\n##\n# RUN.ENV newman\n# ASSERT [ -n \"${HELLO}\" ] \"HELLO not defined\"\ntest:\n    echo \"Hello, ${HELLO:-World}\"\n\n## Generates output compatible with simplified .env assignments\nnewman:\n    echo \"# Let's say hi to Newman\"\n    echo \"export HELLO=Newman\"\n```\n\n_output_\n```\n$ run newman\n\n# Let's say hi to Newman\nexport HELLO=Newman\n```\n\n```\n$ run test\n\nHello, Newman\n```\n\n*Notes*:\n* `RUN.ENV` commands are run **after** EXPORTS\n* `RUN.ENV` commands are run **before** ASSERTS\n* Commands invoked via `RUN.ENV` are expected to generate _relatively_ simple variable assignments\n* Run uses the [subosito/gotenv](https://github.com/subosito/gotenv) library to parse command output\n* `#` comments are supported and will be safely ignored\n* `export` keyword is optional and will be safely ignored\n* 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\n* Visit the [gotenv project page](https://github.com/subosito/gotenv) to learn more about which `.env` features are supported\n\n#### .RUN / .RUNFILE Attributes\n\nIf you need more control while invoking other commands, Run makes it possible to invoke commands, or even other Runfiles, from _within_ your command script.\n\nRun exposes the following attributes:\n\n* `.RUN` - Absolute path of the run binary currently in use\n* `.RUNFILE` - Absolute path of the current **primary** Runfile\n\nNOTE: Even from inside an [included](#includes) Runfile, `.RUNFILE` will always reference the _primary_ Runfile\n\nYour command script can use these to invoke other commands:\n\n_Runfile_\n```\n##\n# EXPORT .RUN, .RUNFILE\ntest:\n    \"${RUN}\" hello\n\nhello:\n    echo \"Hello, World\"\n```\n\n_output_\n```\n$ run test\n\nHello, World\n```\n\n-----------------------------\n### Hidden / Private Commands\n\n#### Hidden Commands\n\nYou can mark a command as _Hidden_ using a leading `.`:\n\n_hidden command example_\n```\n##\n# Prints 'Hello, Newman', then 'Goodbye, now'\n# RUN hello Newman\ntest:\n    echo \"Goodbye, now\"\n\n## Hello command is hidden\n.hello:\n    echo \"Hello, ${1:-world}\"\n```\n\nHidden commands don't show up when listing commands:\n\n_list commands_\n```\n$ run list\n\nCommands:\n  ...\n  test       Prints 'Hello, Newman', then 'Goodbye, now'\n```\n\nBut they can still be invoked by using their full name, with `.`:\n\n_run hidden command_\n```\n$ run .hello\n\nHello, world\n```\n\n#### Private Commands\n\nYou can mark a command as _Private_ using a leading `!`:\n\n_private command example_\n```\n##\n# Prints 'Hello, Newman', then 'Goodbye, now'\n# RUN hello Newman\ntest:\n    echo \"Goodbye, now\"\n\n## Hello command is private\n!hello:\n    echo \"Hello, ${1:-world}\"\n```\n\nPrivate commands don't show up when listing commands:\n\n_list commands_\n```\n$ run list\n\nCommands:\n  ...\n  test       Prints 'Hello, Newman', then 'Goodbye, now'\n```\n\nAnd they cannot be invoked from outside the Runfile:\n\n_try to run private command_\n```\n$ run hello\n\nrun: command not found: hello\n\n$ run '!hello'\n\nrun: command not found: !hello\n\n```\n\n-----------------\n### Script Shells\n\nRun's default shell is `'sh'`, but you can specify other shells.\n\nAll the standard shells should work.\n\n#### Per-Command Shell Config\n\nEach command can specify its own shell:\n```\n##\n# Hello world example.\n# NOTE: Requires ${.SHELL}\nhello (bash):\n  echo \"Hello, world\"\n```\n\n#### Global Default Shell Config\n\nYou can set the default shell for the entire runfile:\n\n_Runfile_\n```\n# Set default shell for all actions\n.SHELL = bash\n\n##\n# Hello world example.\n# NOTE: Requires ${.SHELL}\nhello:\n  echo \"Hello, world\"\n```\n\n#### Other Executors\n\nYou can even specify executors that are not technically shells.\n\n##### Python Example\n\n_Runfile_\n```\n## Hello world python example.\nhello (python):\n\tprint(\"Hello, world from python!\")\n```\n\n##### Script Execution : env\n\nRun executes scripts using the following command:\n\n```\n/usr/bin/env $SHELL $TMP_SCRIPT_FILE [ARG ...]\n```\n\nAny executor that is on the `PATH`, can be invoked via `env`, and takes a filename as its first argument should work.\n\n#### Custom `#!` Support\n\nRun allows you to define custom `#!` lines in your command script:\n\n##### C Example\n\nHere's an example of running a `c` program from a shell script using a custom `#!` header:\n\n_Runfile_\n```\n##\n# Hello world c example using #! executor.\n# NOTE: Requires gcc\nhello:\n  #!/usr/bin/env sh\n  sed -n -e '7,$p' \u003c \"$0\" | gcc -x c -o \"$0.$$.out\" -\n  $0.$$.out \"$0\" \"$@\"\n  STATUS=$?\n  rm $0.$$.out\n  exit $STATUS\n  #include \u003cstdio.h\u003e\n\n  int main(int argc, char **argv)\n  {\n    printf(\"Hello, world from c!\\n\");\n    return 0;\n  }\n```\n\n##### Script Execution: Direct\n\n*NOTE:* The `#!` executor does not use `/user/bin/env` to invoke your script.  Instead, it attempts to make the temporary script file executable then invoke it directly.\n\n\n-----------------\n### Misc Features\n\n#### Ignoring Script Lines\n\nYou can use a `#` on the first column of a command script to ignore a line:\n\n_Runfile_\n```\nhello:\n    # This comment WILL be present in the executed command script\n    echo \"Hello, Newman\"\n# This comment block WILL NOT be present in the executed command script\n#   echo \"Hello, World\"\n    echo \"Goodbye, now\"\n```\n\n*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).\n\n\n----------------\n## Special Modes\n\n### Shebang Mode\n\nIn `shebang mode`, you make your runfile executable and invoke commands directly through it:\n\n_runfile.sh_\n```\n#!/usr/bin/env run shebang\n\n## Hello example using shebang mode\nhello:\n  echo \"Hello, world\"\n\n```\n\n_output_\n```\n$ chmod +x runfile.sh\n$ ./runfile.sh hello\n\nHello, world\n\n```\n\n#### Filename used in help text\nIn shebang mode, the runfile filename replaces references to the `run` command:\n\n_shebang mode help example_\n```\n$ ./runfile.sh help\n\nUsage:\n       runfile.sh \u003ccommand\u003e [option ...]\n                 (run \u003ccommand\u003e)\n  or   runfile.sh list\n                 (list commands)\n  or   runfile.sh help \u003ccommand\u003e\n                 (show help for \u003ccommand\u003e)\n  ...\n```\n\n_shebang mode list example_\n\n```\n$ ./runfile.sh list\n\nCommands:\n  list           (builtin) List available commands\n  help           (builtin) Show help for a command\n  run-version    (builtin) Show run version\n  hello          Hello example using shebang mode\n```\n\n#### Version command name\n\nIn shebang mode, the `version` command is renamed to `run-version`.  This enables you to create your own `version` command, while still providing access to run's version info, if needed.\n\n_runfile.sh_\n\n```\n#!/usr/bin/env run shebang\n\n## Show runfile.sh version\nversion:\n    echo \"runfile.sh v1.2.3\"\n\n## Hello example using shebang mode\nhello:\n  echo \"Hello, world\"\n```\n\n_shebang mode version example_\n```\n$ ./runfile.sh list\n  ...\n  run-version    (builtin) Show Run version\n  version        Show runfile.sh version\n  ...\n\n$ ./runfile.sh version\n\nrunfile.sh v1.2.3\n\n$ ./runfile.sh run-version\n\nrunfile.sh is powered by run v0.0.0. learn more at https://github.com/TekWizely/run\n```\n\n-------------\n### Main Mode\n\nIn main mode you use an executable runfile that consists of a single command, aptly named `main`:\n\n_runfile.sh_\n```\n#!/usr/bin/env run shebang\n\n## Hello example using main mode\nmain:\n  echo \"Hello, world\"\n```\n\nIn this mode, run's built-in commands are disabled and the `main` command is invoked directly:\n\n_output_\n```\n$ ./runfile.sh\n\nHello, world\n```\n\n#### Filename used in help text\nIn main mode, the runfile filename replaces references to `command` name:\n\n_main mode help example_\n```\n$ ./runfile.sh --help\n\nrunfile.sh:\n  Hello example using main mode\n\n```\n\n#### Help options\n\nIn main mode, help options (`-h` \u0026 `--help`) are automatically configured, even if no other options are defined.\n\nThis means you will need to use `--` in order to pass options through to the main script.\n\n------------------------------------------\n## Using direnv to auto-configure $RUNFILE\n\nA nice hack to make executing run tasks within your project more convenient is to use [direnv](https://direnv.net/) to autoconfigure the `$RUNFILE` environment variable:\n\n_create + edit + activate rc file_\n```\n$ cd ~/my-project\n$ direnv edit .\n```\n\n_edit .envrc_\n```\nexport RUNFILE=\"${PWD}/Runfile\"\n```\n\nSave \u0026 exit.  This will activate _immediately_ but will also activate whenever you `cd` into your project's root folder.\n\n```\n$ cd ~/my-project\n\ndirenv: export +RUNFILE\n```\n\n_verify_\n```\n$ echo $RUNFILE\n\n/home/user/my-project/Runfile\n```\n\nWith this, you can execute `run \u003ccmd\u003e` from anywhere in your project.\n\n-------------\n## Installing\n\n### Via Bingo\n\n[Bingo](https://github.com/TekWizely/bingo) makes it easy to install (and update) golang apps directly from source:\n\n_install_\n```\n$ bingo install github.com/TekWizely/run\n```\n\n_update_\n```\n$ bingo update run\n```\n\n### Pre-Compiled Binaries\n\nSee the [Releases](https://github.com/TekWizely/run/releases) page as recent releases are accompanied by pre-compiled binaries for various platforms.\n\n##### Not Seeing Binaries For Your Platform?\n\nRun currently uses [goreleaser](https://goreleaser.com/) to generate release assets.\n\nFeel free to [open an issue](https://github.com/TekWizely/run/issues/new) to discuss additional target platforms, or even create a PR against the [.goreleaser.yml](https://github.com/TekWizely/run/blob/master/.goreleaser.yml) configuration.\n\n### Brew\n\n#### Brew Core\n\nRun is now available on homebrew core:\n\n* https://formulae.brew.sh/formula/run\n\n_install run via brew core_\n```\n$ brew install run\n```\n\n#### Brew Tap\n\nIn addition to being available in brew core, I have also created a tap to ensure the latest version is always available:\n\n* https://github.com/TekWizely/homebrew-tap\n\n_install run directly from tap_\n```\n$ brew install tekwizely/tap/run\n```\n\n_install tap to track updates_\n```\n$ brew tap tekwizely/tap\n\n$ brew install run\n```\n\n#### NIX\n\nFor Nix users, a package is available on nixpkgs:\n\n* [Nix package for Run](https://search.nixos.org/packages?show=run\u0026from=0\u0026size=1\u0026sort=relevance\u0026type=packages\u0026query=run)\n\nSupported Platforms:\n* x86_64-darwin\n* aarch64-darwin\n* aarch64-linux\n* i686-linux\n* x86_64-linux\n\n_install run on NixOS_\n```bash\n$ nix-env -iA nixos.run\n```\n\n_install run on non-NixOs_\n```bash\n$ nix-env -iA nixpkgs.run\n```\n\n#### AUR\n\nFor Archlinux users, a package is available on the AUR:\n\n* https://aur.archlinux.org/packages/run-git\n\n_install run from AUR using yay_\n\n```bash\n$ yay -S run-git\n```\n#### NPM / Yarn\n\nNPM \u0026 Yarn users can install run via the `@tekwizely/run` package:\n\n* [Run NPM Package Page](https://www.npmjs.com/package/@tekwizely/run)\n\n```\n$ npm i '@tekwizely/run'\n\n$ yarn add '@tekwizely/run'\n```\n\n### Other Package Managers\nI hope to have other packages available soon and will update the README as they become available.\n\n---------------\n## Contributing\n\nTo contribute to Run, follow these steps:\n\n1. Fork this repository.\n2. Create a branch: `git checkout -b \u003cbranch_name\u003e`.\n3. Make your changes and commit them: `git commit -m '\u003ccommit_message\u003e'`\n4. Push to the original branch: `git push origin \u003cproject_name\u003e/\u003clocation\u003e`\n5. Create the pull request.\n\nAlternatively see the GitHub documentation on [creating a pull request](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/creating-a-pull-request).\n\n----------\n## Contact\n\nIf you want to contact me you can reach me at TekWize.ly@gmail.com.\n\n----------\n## License\n\nThe `tekwizely/run` project is released under the [MIT](https://opensource.org/licenses/MIT) License.  See `LICENSE` file.\n\n-------------------------------------\n## Just Looking for Bash Arg Parsing?\n\nIf you happened to find this project on your quest for bash-specific arg parsing solutions, I found this fantastic S/O post with many great suggestions:\n\n* [Parsing Command-Line Arguments in Bash (S/O)](https://stackoverflow.com/questions/192249/how-do-i-parse-command-line-arguments-in-bash)\n\n---------------\n## Contributors ✨\n\nThanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)):\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section --\u003e\n\u003c!-- prettier-ignore-start --\u003e\n\u003c!-- markdownlint-disable --\u003e\n\u003ctable\u003e\n  \u003ctr\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"http://chabad360.me\"\u003e\u003cimg src=\"https://avatars2.githubusercontent.com/u/1668291?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003echabad360\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/TekWizely/run/commits?author=chabad360\" title=\"Documentation\"\u003e📖\u003c/a\u003e \u003ca href=\"#infra-chabad360\" title=\"Infrastructure (Hosting, Build-Tools, etc)\"\u003e🚇\u003c/a\u003e \u003ca href=\"https://github.com/TekWizely/run/issues?q=author%3Achabad360\" title=\"Bug reports\"\u003e🐛\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/dawidd6\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/9713907?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eDawid Dziurla\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"#infra-dawidd6\" title=\"Infrastructure (Hosting, Build-Tools, etc)\"\u003e🚇\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/rwhogg\"\u003e\u003cimg src=\"https://avatars3.githubusercontent.com/u/2373856?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eBob \"Wombat\" Hogg\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/TekWizely/run/commits?author=rwhogg\" title=\"Documentation\"\u003e📖\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://github.com/Gys\"\u003e\u003cimg src=\"https://avatars0.githubusercontent.com/u/943251?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eGys\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/TekWizely/run/issues?q=author%3AGys\" title=\"Bug reports\"\u003e🐛\u003c/a\u003e\u003c/td\u003e\n    \u003ctd align=\"center\"\u003e\u003ca href=\"https://crimson.no\"\u003e\u003cimg src=\"https://avatars.githubusercontent.com/u/125863?v=4?s=100\" width=\"100px;\" alt=\"\"/\u003e\u003cbr /\u003e\u003csub\u003e\u003cb\u003eRobin Burchell\u003c/b\u003e\u003c/sub\u003e\u003c/a\u003e\u003cbr /\u003e\u003ca href=\"https://github.com/TekWizely/run/commits?author=rburchell\" title=\"Code\"\u003e💻\u003c/a\u003e\u003c/td\u003e\n  \u003c/tr\u003e\n\u003c/table\u003e\n\n\u003c!-- markdownlint-restore --\u003e\n\u003c!-- prettier-ignore-end --\u003e\n\n\u003c!-- ALL-CONTRIBUTORS-LIST:END --\u003e\n\nThis project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTekWizely%2Frun","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FTekWizely%2Frun","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTekWizely%2Frun/lists"}