You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem? Please describe.
When writing Bash scripts taking command line options, I use getopt to preprocess the command line, and a while loop and case statement to handle individual options:
#!/usr/bin/env bash
# Parse command line or print help text.
script=""
files=()
title=""
items=()
depth=0
ultra=0
verbose=0
getopt=$(getopt --options=t:i:d:uv --longoptions=title:,items:,depth:,ultra,verbose,help -- "$@") || exit
eval set -- $getopt
while true; do
case "$1" in
-t|--title)
title="$2"
shift
shift
;;
-i|--items)
items+=("$2")
shift
shift
;;
-d|--depth)
depth="$2"
shift
shift
;;
-u|--ultra)
ultra=1
shift
;;
-v|--verbose)
verbose=1
shift
;;
--help)
cat <<EOF
Test Amber command line parser
Syntax: $(basename $0) [options]
SCRIPT: Text ......... Script path
FILES: [Text] ........ File paths
-t|--title: Text ..... Title text
-i|--items: [Text] ... Item text
-d|--depth: Num ...... File depth
-u|--ultra: Bool ..... Ultra flag
-v|--verbose: Bool ... Verbose flag
--help ............... Show help text
EOF
exit 1
;;
--)
shift
break
;;
*)
exit 1
;;
esac
done
# Copy positional parameters.
script="$1"
shift
files=("$@")
# Print positional parameters and options.
echo "Script: \"${script}\""
for file in "${files[@]}"; do
echo "File: \"${file}\""
done
echo "Title: \"${title}\""
for item in "${items[@]}"; do
echo "Item: \"${item}\""
done
echo "Depth: ${depth}"
echo "Ultra: ${ultra}"
echo "Verbose: ${verbose}"
This can handle:
Long options with params --label=zzz or --label "zzz"
Short options with params -lzzz
Long options for flags --flag
Short options for flags -f
Short options for multiple flags -xyz expanded to -x -y -z
Positional arguments left over at the end of the while loop
Describe the solution you'd like
However, this is such a painful process, I have to copy and adapt a previous script every time. I would like to avoid this pain in Amber, by writing a set of builtin functions. This is my proposal:
#!/usr/bin/env amber
main(args) {
// Parse command line or print help text.
let parser = parser("Test Amber command line parser")
let script = param(parser, "script", "", "Script path")
let files = param(parser, "files", [Text], "File paths")
let title = param(parser, "-t|--title", "", "Title text")
let items = param(parser, "-i|--items", [Text], "Item text")
let depth = param(parser, "-d|--depth", 0, "File depth")
let ultra = param(parser, "-u|--ultra", false, "Ultra flag")
let verbose = param(parser, "-v|--verbose", false, "Verbose flag")
getopt(parser, args)
// Print positional parameters and options.
echo "Script: \"{script}\""
for index, file in files {
echo "File #{index}: \"{file}\""
}
echo "Title: \"{title}\""
for index, item in items {
echo "Item #{index}: \"{item}\""
}
echo "Depth: {depth}"
echo "Ultra: {ultra}"
echo "Verbose: {verbose}"
}
The parser builtin creates a parser struct to hold the array of (reference counted) argument structs for Bash generation. The param builtin parses the option match string, a default value (which also defines whether it takes a parameter at all, and the type of that parameter) and a help string, and creates the argument structs for the parser. The getopt builtin causes the command line to be parsed. Subsequently, the argument structs are responsible for returning the parsed values for use in the main script.
Describe alternatives you've considered
The only alternative would be to attempt to write this as a standard library function, but (i) it requires interaction between the various components, which is just not possible in pure Amber, and (ii) it would be unable to support typed arguments, which are necessary to (for example) iterate over array arguments.
Additional context
N/A
The text was updated successfully, but these errors were encountered:
Is your feature request related to a problem? Please describe.
When writing Bash scripts taking command line options, I use
getopt
to preprocess the command line, and awhile
loop andcase
statement to handle individual options:This can handle:
--label=zzz
or--label "zzz"
-lzzz
--flag
-f
-xyz
expanded to-x -y -z
while
loopDescribe the solution you'd like
However, this is such a painful process, I have to copy and adapt a previous script every time. I would like to avoid this pain in Amber, by writing a set of builtin functions. This is my proposal:
The
parser
builtin creates a parser struct to hold the array of (reference counted) argument structs for Bash generation. Theparam
builtin parses the option match string, a default value (which also defines whether it takes a parameter at all, and the type of that parameter) and a help string, and creates the argument structs for theparser
. Thegetopt
builtin causes the command line to be parsed. Subsequently, the argument structs are responsible for returning the parsed values for use in the main script.Describe alternatives you've considered
The only alternative would be to attempt to write this as a standard library function, but (i) it requires interaction between the various components, which is just not possible in pure Amber, and (ii) it would be unable to support typed arguments, which are necessary to (for example) iterate over array arguments.
Additional context
N/A
The text was updated successfully, but these errors were encountered: