Skip to content

Task Launcher is a bash based CLI script that can be used to run a series of commonly run commands with a shorter alias.

License

Notifications You must be signed in to change notification settings

SiJiL82/bash-task-launcher

Repository files navigation

Task Launcher

About

Task Launcher is a bash based CLI script that can be used to run a series of commonly run commands with a shorter alias.
For example, if you regularly run the following commands to build and run your project:

cd ~/projects/my_project/src
npm build-dev
npm start

You could create a Task Launcher task called build-and-run that contains these commands, and run them from anywhere in your shell by simply calling tl build-and-run.

Task Launcher also includes an interactive menu for all the tasks you’ve created, allowing you to execute the tasks available by entering their numeric input.
The menu includes support for sub-menus, allowing you to group related tasks together, and can prompt for user input to provide variable data to your tasks.

Getting Started

To start using Task Launcher, clone this repo:
git clone https://github.com/SiJiL82/bash-task-launcher.git

If you want to create a task launcher with tasks for your existing project (for example to speed up common developer tasks), clone this repo inside your project.
You can change the launcher command to one relative to your project, which allows you to have a Task Launcher config specifically for your project.
To do so, simply rename the tl file to whatever you want the command to be to call your launcher.
For example, if you’re working on "My Cool Website", you could rename tl to mcw which will allow you to call the launcher tasks with mcw build-and-run.

Using the Launcher

To view available tasks the launcher can call, run any of tl -h, tl h, tl help or tl --help:

tl help

To run a task directly, simply call tl followed by the task name:

tl cli example

To launch the interactive menu, call tl m or tl menu:

tl menu example

You can then launch any of the tasks, or enter any of the sub menus by entering the numeric indicator next to the task description:

tl menu task run

Installation

Task Launcher can be called from any location in your terminal - you don’t need to launch it from the location you’ve cloned it to every time.

To install the launcher, simply run it from the location you’ve cloned it to once, and it will self install via symlink into /usr/local/bin
Note: This may require sudo access and will attempt to elevate permissions if required.

cd ~/projects/bash-task-launcher
./tl

Uninstallation

To stop Task Launcher being available to run anywhere in your shell, simply remove the symlink from /usr/local/bin
Note: This may require sudo access

sudo rm /usr/local/bin/tl

Shell Autocomplete

Task Launcher includes autocomplete files for both bash and zsh shells that list all the available tasks.
Note: Despite being a bash based CLI script, it will work when being called from other shells, as long as bash exists on the system

To enable the autocomplete prompts follow the steps relevant to the shell you’re using:

zsh:

  • Get the full path to the autocomplete folder in the cloned repo on your machine
    e.g.: /home/USER_NAME/projects/bash-task-launcher/autocomplete

  • Edit your ~/.zshrc file

  • Add the line fpath=(path_found_above $fpath)

    • e.g.: fpath=(/home/USER_NAME/projects/bash-task-launcher/autocomplete $fpath)

  • Restart your terminal.

Now when you type tl followed by a space on the terminal, you should get a list of available commands to choose from.
The list will update as you type, filtering down to relevant commands.

bash:

  • Get the full path to the autocomplete/tl.bash file on your machine.

    • e.g.: /home/USER_NAME/projects/bash-task-launcher/autocomplete/sd.bash

  • Edit your ~/.bashrc file

  • Add the line source path_found_above

    • e.g.: source /home/USER_NAME/projects/bash-task-launcher/autocomplete/tl.bash

  • Restart your terminal

Now when you type tl followed by a space and press TAB twice, a list of available commands will be shown.
If you start typing a task name and then press TAB and only one available command is available, it will be autocompleted for you.
e.g.: If you have a task named example, type tl exa and press TAB and it will autocomplete to tl example

Building the Autocomplete Files

After adding any tasks to the Task Launcher, you’ll need to update the autocomplete files so they include your new tasks.

Simply run tl build-autocomplete to regenerate them.

Don’t forget to commit these files along with your task definitions if you’ve forked this repository / added it to an existing project that’s in source control

Creating Tasks

Creating the Task Definition

To create your own task for the Task Launcher, first decide on the task name.
This should be short, so it’s quick to type on the CLI, but still accurately describe what the task will do.
Task names must be unique across the entire launcher - tasks on different sub menus cannot share names.
Note: Your task name can only contain the charactes a-z (lowercase only) and the - character.
You cannot separate words in your task name with spaces or underscores.

Tasks are listed on the menu in the order they appear in the files in. To re-order the menu(s), simply re-order the task definitions in the task config files.

Edit the file in task_configs that contains the menu or sub-menu that your task relates to.
You can add all task and sub-menu definitions to a single file (such as task_configs/main) if you wish, however it is recommended to create a separate file for each sub-menu to keep the configs tidy and easy to maintain.

Copy the template below into the file you’re adding the task to:

example:menu() (echo MAIN_MENU)
example:describe() (echo 'This is the task description')
example() {
    # Enter your commands here
}

Replace the example task name with your new task name, for each of the example:menu, example:describe and example functions.
For example:

build-and-run:menu() (echo MAIN_MENU)
build-and-run:describe() (echo 'Build and start the web application')
build-and-run() {
    cd ~/projects/my_project/src
    npm build-dev
    npm start
}

If your task needs to be in a sub-menu, replace MAIN_MENU with the name of your sub-menu.

Enter a suitable description for the task, so it’s clear what the task does.
Keep the description short and concise, as very long descriptions will make the interactive menu unwieldy.

Enter the commands you want your task to run in the main task function.

Save the file and test it by running tl task-name

When your new task is complete, update the autocomplete files to include it

Creating Sub Menus

To prevent the initial menu screen from becoming overwhelming to the user, you can create sub-menus to group related tasks together intuitively.
Note: A task being in a sub-menu does not affect how it is called on the CLI in any way

It is recommended to create tasks in a sub-menu in a separate file to keep the config files from becoming difficult to maintain.
However, if you want your sub-menu option to appear on the main menu, you should create the sub-menu task in the task_configs/main file.
Task Launcher supports any level of nested sub-menus - to create a nested sub-menu, simply define the :menu function with the name of the menu you wish your sub-menu to appear on.

Edit the file in task_configs that contains the menu you want your sub-menu option to appear on.
For example, to include it on the main menu, edit task_configs/main.
Note: This is purely for maintainability - you can add the definition to any file you like!

Copy the template below into the file:

example-menu:menu() (echo MAIN_MENU)
example-menu:meta() (echo NO-RUNNER)
example-menu:describe() (echo 'This is the menu description')
example-menu() {
	menu "$(tasks:menuitems EXAMPLE_MENU)"
}

Replace the example-menu task name with your new menu task name (e.g.: npm-tools-menu) for each of example-menu:menu, example-menu:meta, example-menu:describe and example-menu

Do not edit the :meta definition. This is required to prevent the sub-menu task being listed as an available task to run.

Enter a suitable description for your sub-menu.

Inside the menu definition function, replace EXAMPLE_MENU with the name of your new menu (e.g.: NPM_TOOLS_MENU).

For example:

npm-tools-menu:menu() (echo MAIN_MENU)
npm-tools-menu:meta() (echo NO-RUNNER)
npm-tools-menu:describe() (echo 'NPM Tools')
npm-tools-menu() {
	menu "$(tasks:menuitems NPM_TOOLS_MENU)"
}

Update any tasks that you want to appear on the sub-menu, setting their :menu definition to match the name you have just assigned above.
For example:

build-and-run:menu() (echo NPM_TOOLS_MENU)
build-and-run:describe() (echo 'Build and start the web application')
build-and-run() {
    cd ~/projects/my_project/src
    npm build-dev
    npm start
}

Creating Task Config Files

To create a file to add task definitions to:

  • Create the file: touch ./task_configs/submenu

  • Make the file executable: chmod +x ./task_configs/submenu

  • Add the bash shebang to the top of the file: #!/usr/bin/env bash

Other Features

Useful Task Functions

There are a few useful functions available in the shared-functions file that can be used in your task definitions to improve the user experience.

print_info

Prints an information message to the user in blue text.
Usage:

example:menu() (echo EXAMPLE_MENU)
example:describe() (echo 'An example task')
example() {
    print_info "To print information to the user, use 'print_info'"
}

print_warning

Prints a warning message to the user in red text.
Usage:

example:menu() (echo EXAMPLE_MENU)
example:describe() (echo 'An example task')
example() {
    print_warning "To print a warning to the user, use 'print_warning'"
}

prompt

Prints a message to the user in yellow text, and waits for them to enter input.
An optional default can be provided that the user can accept by pressing enter immediately.
Usage:

example:menu() (echo EXAMPLE_MENU)
example:describe() (echo 'Prompt the user')
example() {
    input=$(prompt "Do you like this question?")
    echo "You said '$input'"
}
example-default:menu() (echo EXAMPLE_MENU)
example-default:describe() (echo 'Prompt the user with a default response')
example-default() {
    input=$(prompt "Do you like this question?" "No")
    echo "You said '$input'"
}
tl prompt example

arg_or_prompt

Task functions can accept arguments to be used within the script, so when called on the CLI the user can provide the argument.
On the interactive menu however, the user must be prompted to enter the argument value.
If you would like users to have the option to either provide the argument on the CLI, or be prompted to enter it, you can use arg_or_prompt instead of prompt.
Usage:

example:menu() (echo EXAMPLE_MENU)
example:describe() (echo 'An example task')
example() {
    name=$(arg_or_prompt "$1" "Enter your name")
    echo "Hello $name"
}
tl arg or prompt example

prompt_options

Prints a list of options for the user to chose from.
Returns the option item selected - not the numerical position of the item.
Usage:

example-options:menu() (echo MAIN_MENU)
example-options:describe() (echo 'An example task with options')
example-options() {
    local -r options=("One" "Two" "Three" "Four" "Five" "Six" "Seven" "Eight" "Nine" "Ten")
    local -r choice=$(prompt_options options)
    print_info "You chose: $choice"
}

arg_or_prompt_options

Allows the user to provide the option they wish to chose as a CLI argument.
The value they provide will be checked to see if it is in the option values you provide, and prompt them to chose a new value if not.
Usage:

example-options:menu() (echo MAIN_MENU)
example-options:describe() (echo 'An example task with options')
example-options() {
    local -r options=("One" "Two" "Three" "Four" "Five" "Six" "Seven" "Eight" "Nine" "Ten")
    local -r choice=$(arg_or_prompt_options options "$1")
    print_info "You chose: $choice"
}

:die

If you want a command in your task to print a warning message when it fails, call :die as an "or" option on your command.
Usage:

example:menu() (echo EXAMPLE_MENU)
example:describe() (echo 'An example task')
example() {
    cd ./directory_that_doesnt_exist || :die "Cannot change directory"
}

Task Functions

If you have common commands that are shared across a number of tasks, it is recommended to create a function containing those commands in the task-functions file.

This is entirely optional, however doing so helps to keep the task config files tidy and maintainable.

Contributing

Issues / bugs

If you find anything not working correctly, please raise an issue

Have a Question?

If you need any help getting Task Launcher up and running, creating a task for it, or have an idea for an improvement (that you can’t make your self) please create a new discussion and I’ll do my best to help, or point you towards something that might solve your issue.

Development

If you’d like to help out with improving Task Launcher, please feel free to create a fork and raise a pull request - contributions are most definitely welcome!

Miscellaneous

Because I know eventually it’ll get asked - the prompt I’m using in the screenshots is Oh My Posh.
My config is available here - feel free to copy it!

About

Task Launcher is a bash based CLI script that can be used to run a series of commonly run commands with a shorter alias.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages