Skip to content

Commit

Permalink
✨ add default for opts/args
Browse files Browse the repository at this point in the history
  • Loading branch information
jcaillon committed Jun 22, 2024
1 parent 3145482 commit d37244d
Show file tree
Hide file tree
Showing 16 changed files with 533 additions and 206 deletions.
54 changes: 54 additions & 0 deletions docs/content/docs/025.command-properties/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,38 @@ url: /docs/command-properties

This page describes the properties available to define a command.

Here is a definition example that uses all the properties:

```yaml {linenos=table,linenostart=1}
command: command
function: functionName
shortDescription: A short sentence.
description: |-
A long description that can use ⌜quotes⌝.
sudo: false
hideInMenu: false
arguments:
- name: firstArg
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.
noEnvironmentVariable: false
examples:
- name: command -o -2 value1 arg1 more1 more2
description: |-
Call command with option1, option2 and some arguments.
```
You can check the [showcase commands][showcase-examples] to get definition examples.
## 🫚 Top level properties
Expand Down Expand Up @@ -164,6 +196,28 @@ The description for this option. It will be used to display the help/usage of th
|----------|---------------|
| yes ✔️ | N/A |

### noEnvironmentVariable

By default, an option that can have a value (e.g. `--option <something>`) will be parsed to a local variable which default to a global variable if not value was passed by the user.

For instance, the option `--option1` will be parsed to the local variable `option1` with the following definition: `local option1="${VALET_OPTION1:-}"`. This allows to define options through environment variable.

This behavior can be changed by setting `noEnvironmentVariable: true` which will always make the local variable for the option empty.

| Mandatory? | Default value? |
|----------|---------------|
| no | false |

### default

The default value to give to the local variable parsed from the option. The global variable will take precedence (see noEnvironmentVariable).

The local variable will be defined like this: `local option1="${VALET_OPTION1:-"default value"}"`. Where `default value` is the value of this option.

| Mandatory? | Default value? |
|----------|---------------|
| no | N/A |

## 🎈 Examples

Examples are used in the command help/usage and let the user quickly understand how to use the command.
Expand Down
6 changes: 3 additions & 3 deletions docs/content/docs/800.roadmap/_index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,21 @@ url: /docs/roadmap

This page lists the features that I would like to implement in Valet. They come in addition to new features described in the [issues][valet-issues].

- Add a default value for options.
- We can have fuzzy matching on options too; just make sure it is not ambiguous.
- Show the arguments required when a command parsing fails.
- Allow to regroup single letter options (e.g. -fsSL).
- Add full support for interactive mode.
- For dropdown with a set list of options, we can verify that the input value is one of the expected value.
- Generate an autocompletion script for bash and zsh.
- Self-command to create a new command interactively.
- Create a valet-community-commands where everyone can contribute to new default commands for Valet.
- head / tail from file.
- Allow to regroup single letter options (e.g. -fsSL).
- Add a command self package that build the user commands into a single script file.
- fix running tests with verbose mode on.
- Have a consistent look and feel for interactive functions.
- Reimplement usage of main::sortCommands / main::addLastChoice.
- Add a default value for options.
- Implement regex replace in pure bash.
- Show the arguments required when a command parsing fails.
- Betters checks in self build!
- Support alternative single comments `### VALET COMMAND` instead of multiline comments for command declaration (see we can have help in autocompletion).
- A command can declare dependencies to auto check if some tools are installed before running the command.
Expand Down
1 change: 1 addition & 0 deletions examples.d/showcase/showcase.sh
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ options:
- 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: |-
Expand Down
14 changes: 14 additions & 0 deletions tests.d/1001-main-functions/results.approved.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,17 @@ Exit code: `0`
→ main::parseFunctionArguments selfMock2
local parsingErrors option1 thisIsOption2 help firstArg
local -a more
option1=""
thisIsOption2="${VALET_THIS_IS_OPTION2:-}"
help=""
parsingErrors="Expecting ⌜2⌝ argument(s) but got ⌜0⌝."
more=(
)
→ main::parseFunctionArguments selfMock2 -o -2 optionValue2 arg1 more1 more2
local parsingErrors option1 thisIsOption2 help firstArg
local -a more
help=""
parsingErrors=""
option1="true"
thisIsOption2="optionValue2"
Expand All @@ -128,6 +131,7 @@ more=(
→ main::parseFunctionArguments selfMock2 -o -2 optionValue2 arg1
local parsingErrors option1 thisIsOption2 help firstArg
local -a more
help=""
parsingErrors="Expecting ⌜2⌝ argument(s) but got ⌜1⌝."
option1="true"
thisIsOption2="optionValue2"
Expand All @@ -138,7 +142,9 @@ more=(
→ main::parseFunctionArguments selfMock2 -unknown -what optionValue2 arg
local parsingErrors option1 thisIsOption2 help firstArg
local -a more
option1=""
thisIsOption2="${VALET_THIS_IS_OPTION2:-}"
help=""
parsingErrors="Unknown option ⌜-unknown⌝.
Unknown option ⌜-what⌝."
firstArg="optionValue2"
Expand All @@ -150,6 +156,7 @@ more=(
local parsingErrors option1 thisIsOption2 help firstArg
local -a more
thisIsOption2="${VALET_THIS_IS_OPTION2:-}"
help=""
parsingErrors=""
firstArg="arg"
option1="true"
Expand All @@ -161,7 +168,9 @@ more=(
→ main::parseFunctionArguments selfMock2 -this arg more1
local parsingErrors option1 thisIsOption2 help firstArg
local -a more
option1=""
thisIsOption2="${VALET_THIS_IS_OPTION2:-}"
help=""
parsingErrors="Unknown option ⌜-this⌝ (did you mean ⌜--this-is-option2⌝?)."
firstArg="arg"
more=(
Expand All @@ -171,6 +180,8 @@ more=(
→ main::parseFunctionArguments selfMock2 --this-is-option2 --option1 arg more1
local parsingErrors option1 thisIsOption2 help firstArg
local -a more
option1=""
help=""
parsingErrors=""
thisIsOption2="--option1"
firstArg="arg"
Expand All @@ -180,6 +191,7 @@ more=(
→ main::parseFunctionArguments selfMock4 arg1 arg2
local parsingErrors help firstArg secondArg
help=""
parsingErrors=""
firstArg="arg1"
secondArg="arg2"
Expand All @@ -188,7 +200,9 @@ secondArg="arg2"
→ main::parseFunctionArguments selfMock2 -- --arg1-- --arg2--
local parsingErrors option1 thisIsOption2 help firstArg
local -a more
option1=""
thisIsOption2="${VALET_THIS_IS_OPTION2:-}"
help=""
parsingErrors=""
firstArg="--arg1--"
more=(
Expand Down
2 changes: 1 addition & 1 deletion tests.d/1100-self-config/01.self-config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function testSelfConfig() {

echo "→ (selfConfig --override --export-current-values)"
(
unset ${!VALET_CONFIG_*} VALET_USER_DIRECTORY
unset -v ${!VALET_CONFIG_*} VALET_USER_DIRECTORY
export VALET_CONFIG_FILE="${configFile}"
export VALET_CONFIG_COLOR_DEBUG=$'\e[44m'
export VALET_CONFIG_LOG_COLUMNS=20
Expand Down
101 changes: 79 additions & 22 deletions tests.d/1101-self-build-utils/00.self-build-utils.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,7 @@
# shellcheck source=../../valet.d/commands.d/self-build-utils
source "${GLOBAL_VALET_HOME}/valet.d/commands.d/self-build-utils"

function testExtractCommandYamls() {

extractCommandYamls "resources/extract-command-yamls-test-file"

local content
for content in "${RETURNED_ARRAY[@]}"; do
echo "content:"$'\n'"${content}"
done

test::endTest "Testing extractCommandYamls" 0
}

function testExtractCommandDefinitionToVariables() {
local content="
_VALID_YAML="
command: test
author: github.com/jcaillon
fileToSource: source
Expand All @@ -27,6 +14,8 @@ description: |-
In a multi-line string.
With 3 paragraphs.
sudo: false
hideInMenu: false
arguments:
- name: arg1
description: Description of arg 1.
Expand All @@ -37,31 +26,50 @@ arguments:
description: Description of arg 3.
fourthProp: ok3
options:
- name: option1
- name: --option1
description: |-
Description of option 1.
Another line.
- name: option2
noEnvironmentVariable: true
default: true
- name: --option2
description: |-
Description of option 2.
Another line.
noEnvironmentVariable: false
- description: |-
Description of option 3.
Another line.
default: default value
examples:
- name: command -o -2 value1 arg1 more1 more2
description: |-
Call command with option1, option2 and some arguments.
"
echo "${content}"

extractCommandDefinitionToVariables "${content}"
function testExtractCommandYamls() {

local varName var
for varName in ${!TEMP_CMD_BUILD_*}; do
local -n var="${varName}"
echo "${varName}=${var@Q}"
extractCommandYamls "resources/extract-command-yamls-test-file"

local content
for content in "${RETURNED_ARRAY[@]}"; do
log::info "content:"
log::printFileString "${content}"
done

test::endTest "Testing extractCommandYamls" 0
}

function testExtractCommandDefinitionToVariables() {
log::printFileString "${_VALID_YAML}"

extractCommandDefinitionToVariables "${_VALID_YAML}"

printVars ${!TEMP_CMD_BUILD_*}

test::endTest "Testing extractCommandDefinitionToVariables" 0
}

Expand All @@ -75,9 +83,58 @@ function testExtractFirstLongNameFromOptionString() {
test::endTest "Testing extractFirstLongNameFromOptionString" 0
}

function testDeclareFinalVariables() {
log::printFileString "${_VALID_YAML}"

# declare common variables
declareFinalCommandDefinitionCommonVariables "func" "cmd"

# declare help variables
declareFinalCommandDefinitionHelpVariables "func"

# declare options and arguments for the parser
declareFinalCommandDefinitionParserVariables "func"

printVars ${!CMD_*}

test::endTest "Testing declareFinalCommandDefinition*" 0
}

function testVerifyCommandDefinition() {
log::printFileString "${_VALID_YAML}"

# verify that the command definition is valid
verifyCommandDefinition "func" "cmd"
echo
echo "${SELF_BUILD_ERRORS:-}"

test::endTest "Testing verifyCommandDefinition" 0
}

function printVars() {
local varName var
for varName in "$@"; do
local -n var="${varName}"
echo "${varName}=${var[*]@K}"
done
}

function main() {
testExtractCommandYamls
testExtractCommandDefinitionToVariables
testExtractFirstLongNameFromOptionString

testDeclareFinalVariables
testVerifyCommandDefinition
}
# save all CMD_* variables into a temporary string
io::invoke declare -p ${!CMD_*}
_ALL_CMD_VARIABLES="${RETURNED_VALUE//declare -? /}"
unset -v ${!CMD_*} _LINE

main

# reset all CMD_* as they were
unset -v _VALID_YAML
unset -v ${!CMD_*}
eval "${_ALL_CMD_VARIABLES}"
Loading

0 comments on commit d37244d

Please sign in to comment.