[lang-ref] ( parse_args_overview ) ( bash )

@test "parse args overview" {
	# implement with while, case, shift
	command01() {
		# parser
		local -a positional=()
		local verbose=0
		local force=0
		local prefix=""

		while [[ $# -gt 0 ]]; do
			case "$1" in
				-v|--verbose)
					verbose=1
					shift
					;;
				-f|--force)
					force=1
					shift
					;;
				--prefix)
					if [[ $# -lt 2 ]]; then
						echo "missing value for $1" >&2
						return 2
					fi
					prefix="$2"
					shift 2
					;;
				--prefix=*)
					prefix="${1#--prefix=}"
					shift
					;;
				--)
					shift
					positional+=("$@")
					break
				;;
				-*)
					echo "unknown option: $1" >&2
					return 2
					;;
				*)
					positional+=("$1")
					shift
					;;
			esac
		done

		if [[ ${#positional[@]} -lt 2 ]]; then
			echo "usage: cmd FILENAME_IN FILENAME_OUT [options]" >&2
			echo "error: need 2 positional args (IN OUT), got ${#positional[@]}" >&2
			return 2
		fi

		FILENAME_IN="${positional[0]}"
		FILENAME_OUT="${positional[1]}"
		VERBOSE="$verbose"
		FORCE="$force"
		PREFIX="$prefix"
	}

	# command line
	command01 a.txt b.txt --verbose --prefix=test.

	# check parse result
	[ "$FILENAME_IN"  =   "a.txt" ]
	[ "$FILENAME_OUT" =   "b.txt" ]
	[ "$FORCE"        -eq 0 ]
	[ "$VERBOSE"      -eq 1 ]
	[ "$PREFIX"       =   "test." ]
}

#!/usr/bin/env bats
@test "parse args overview alternative" {
	# use getopts
	command01() {
		# optional args
		local verbose=0
		local force=0
		local prefix=""
		local OPTIND=1

		while getopts ":vfp:" opt; do
		case "$opt" in
			v)
				verbose=1
				;;
			f)
				force=1
				;;
			p)
				prefix="$OPTARG"
				;;
			:)
				echo "missing value for -$OPTARG" >&2
				return 2
				;;
			\?)
				echo "unknown option: -$OPTARG" >&2
				return 2
				;;
			esac
		done

		shift $((OPTIND - 1))

		# positional args
		if [[ $# -lt 2 ]]; then
			echo "usage: cmd [-v] [-f] [-p PREFIX] FILENAME_IN FILENAME_OUT" >&2
			return 2
		fi

		FILENAME_IN="$1"
		FILENAME_OUT="$2"
		VERBOSE="$verbose"
		FORCE="$force"
		PREFIX="$prefix"
	}

	# command line
	command01 -v -p test. a.txt b.txt

	# check parse result
	[ "$FILENAME_IN"  =   "a.txt" ]
	[ "$FILENAME_OUT" =   "b.txt" ]
	[ "$FORCE"        -eq 0 ]
	[ "$VERBOSE"      -eq 1 ]
	[ "$PREFIX"       =   "test." ]
}