Valet logo

Valet

Valet is a zero dependency tool that helps you build fast, robust, testable and interactive CLI applications in bash.

Read the docs

🥵
Duplicated code in all scripts
I'm copy/pasting the same log functions across all my scripts!
💔
Frail arguments parser
All my scripts contain a variation of the same while [[ $# > 0 ]]; loop to parse arguments.
🔥
Dependency hell
My scripts depend on external tools that are not always installed.
🐌
Slow scripts
My bash scripts are so slow! They are unusable on bash for windows, I can't do anything without WSL.
🤬
Script reusability & sharing
I can never remember the required options and arguments of my script, and the help is often outdated.

Sound familiar? Let's see what Valet can do for you!

Build professional CLI tools

Valet gives you the framework and functions required to build awesome tools, effortlessly, in bash. Get everything you expect from a good CLI software (e.g. git, docker…) in a few lines of bash code and YAML configuration.

Turn your scripts into commands

Valet enables you to easily create commands that can take arguments and/or options automatically parsed by the Valet. Exceptions are gracefully handled with the error stack printed to the user.

Interactively execute your commands

Find all your commands in a convenient menu with fuzzy finding capabilities. Get prompted for missing arguments or options to make your commands easy to use.

Fetch and share extensions

You commands are wrapped into extensions that can easily be shared with coworkers or the internet.

Libraries of pure bash functions

Make your scripts more performant and write code faster by using Valet libraries for string manipulation, interactive prompt, pure bash I/O and more… You can also extend Valet to create and share your own libraries!

Test your commands

Ever wondered how you can effectively setup unit tests for your scripts? Valet standardizes the way you test functions and commands with approval tests approach. Run them all in a single command and automate tests in CI pipelines.

Clear and standardized help

Declare properties for your commands with YAML which are used to automatically display a user friendly documentation.

Made for CI/CD automation

Valet only requires bash, has advanced logging capabilities and can be entirely configured through environment variables, which makes it a great candidate as a core framework to build your CI/CD jobs.

Pure bash, zero dependencies

Simply run the install script which copies Valet and you are good to go, you will only ever need bash! And thanks to bash scripting nature, you can highly customize Valet itself by re-declaring functions to your liking.

Lighting fast on any platform

Valet does not use forking which makes it super fast, even on windows Git bash.


Valet in a gist:

  • In Valet, you can create new commands that you can invoke with valet my-command.
  • Each command has properties that describe it (a description, a list of arguments and options, and so on…).
  • Each command has an associated bash function that is called when the command is invoked and which contains your logic.
  • You define commands and their functions in .sh files under your Valet user directory and Valet takes care of indexing your commands; which allows you to quickly find them, parse options, arguments, print their help…
  • Commands are packaged in extensions that can easily be shared and downloaded by other Valet users.

🖥️ An interactive menu

Calling valet without arguments lets you interactively search commands, read their documentation and execute them:

Demo interactive-menu

✨ Create a command

Command properties are defined using a simple YAML syntax:

showcase-command1.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/usr/bin/env bash
: "---
command: showcase command1
function: showcaseCommand1
shortDescription: A showcase command that uses arguments and options.
description: |-
  An example of description.

  You can put any text here, it will be wrapped to fit the terminal width.

  You can ⌜highlight⌝ some text as well.
arguments:
- name: first-arg
  description: |-
    First argument.
- name: more...
  description: |-
    Will be an an array of strings.
options:
- name: -o, --option1
  description: |-
    First option.
  noEnvironmentVariable: true
- name: -2, --this-is-option2 <level>
  description: |-
    An option with a value.
  default: two
examples:
- name: showcase command1 -o -2 value1 arg1 more1 more2
  description: |-
    Call command1 with option1, option2 and some arguments.
---"
function showcaseCommand1() {
  :
}

📖 Clear and standardized help

With valet command --help or valet help command, you get a beautifully formatted help for your command:

Demo show-help

🪄 Automatic parsing of arguments and options

Positional arguments and options are automatically parsed by Valet based on your command definition.

They are made available as local variables in your command function.

See the command implementation
showcase-command1.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/usr/bin/env bash
# command properties hidden for the sake of brevity
function showcaseCommand1() {
  command::parseArguments "$@"; eval "${REPLY}"
  command::checkParsedResults

  log::info "First argument: ${firstArg:-}."
  log::info "Option 1: ${option1:-}."
  log::info "Option 2: ${thisIsOption2:-}."
  log::info "More: ${more[*]}."

  # example use of a library function
  # Importing the string library (note that we could do that at the begining of the script)
  # shellcheck disable=SC1091
  source string
  local _myString="<b>My bold text</b>"
  string::extractBetween _myString "<b>" "</b>"
  local extractedText="${REPLY}"
  log::info "Extracted text is: ⌜${extractedText:-}⌝"

  echo "That's it!"
}
Demo parse-args

🐾 Advanced logging

Easily log messages and customize their output on the fly.

See the command implementation
test-log.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#!/usr/bin/env bash
: "---
command: test-log
function: testLog
shortDescription: A command that only for testing valet logging functions.
description: |-
  A command that only for testing valet logging functions.
---"
function testLog() {
  log::errorTrace "This is an error trace message which is always displayed."
  log::trace "This is a trace message."
  log::debug "This is a debug message."
  log::info "This is an info message with a super long sentence. Notice how the line gets wrapped and indented correctly to increase readability."
  log::success "This is a success message."
  log::warning "This is a warning message."$'\n'"With a second line."
  log::error "This is an error message, also shows the callstack with debug level."
  if log::isDebugEnabled; then
    log::printString "The debug mode is activated!"
  fi
  if log::isTraceEnabled; then
    log::printString "The trace mode is activated!"
  fi
}
Demo logging

🧪 Test framework

Automate tests for your script using the approval tests approach for assertions:

Demo tests

🧩 Libraries of functions

Make your scripts more performant and write code faster by using Valet standard libraries for string manipulation, interactive prompt, pure bash I/O and more…

Use one of the 187 functions coming in standard with Valet! Some examples:

script.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
myFunction() {
  source string
  MY_STRING="field1 field2 field3"
  string::getField MY_STRING 1 separator=" "
  echo "The field at index 1 is ${REPLY}"

  source interactive
  if interactive::promptYesNo "Do you want to continue?"; then 
    echo "Yes."
  else
    echo "No."
  fi
}

Note

These demo were recorded with the asciinema. The color scheme for the terminal is dracula and the font is JetBrainsMono Nerd Font.