diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..73f69e0 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,8 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml +# Editor-based HTTP Client requests +/httpRequests/ diff --git a/.idea/g.bash.iml b/.idea/g.bash.iml new file mode 100644 index 0000000..c956989 --- /dev/null +++ b/.idea/g.bash.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..7c5d2b8 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/example.bash b/example.bash index cc53214..8072578 100755 --- a/example.bash +++ b/example.bash @@ -1,6 +1,7 @@ #!/bin/bash source src/g.bash +shopt -s expand_aliases g::log::setLevel internal g::log::enableTarget g::arg @@ -14,7 +15,7 @@ g::app::command::arg name "The name of the shell" g::app::command::flag no-tty "Disable TTY output" function app::ex::shell() { - echo "Starting shell: '$@'" + echo "Starting shell: '$*'" } g::app::command ls "List contents of the directory" @@ -25,21 +26,25 @@ g::app::command::arg name "Name of the ls" function app::ex::ls() { local args="$1" - echo "Argcall: $args::arg" - echo "Arg1: $($args::arg name)" - echo "Arg1: $(g::arg $g__APP_LAST_ARGPARSE 0)" - echo "Arg2: $(g::arg $g__APP_LAST_ARGPARSE name)" - - echo "Dir: $(g::flag $g__APP_LAST_ARGPARSE dir)" - echo "Fubar: $(g::flag $g__APP_LAST_ARGPARSE fubar)" - echo "dry-run: $(g::flag $g__APP_LAST_ARGPARSE dry-run)" - - if g::arg::has $g__APP_LAST_ARGPARSE 0; then - echo "Has arg0" - fi - - echo "All args: $(g::args $g__APP_LAST_ARGPARSE)" + g::lock::try + +# alias +# echo "Argcall: $args::arg" +# echo "Arg1: $($args::arg name)" +# +# echo "Arg1: $(g::arg $g__APP_LAST_ARGPARSE 0)" +# echo "Arg2: $(g::arg $g__APP_LAST_ARGPARSE name)" +# +# echo "Dir: $(g::flag $g__APP_LAST_ARGPARSE dir)" +# echo "Fubar: $(g::flag $g__APP_LAST_ARGPARSE fubar)" +# echo "dry-run: $(g::flag $g__APP_LAST_ARGPARSE dry-run)" +# +# if g::arg::has $g__APP_LAST_ARGPARSE 0; then +# echo "Has arg0" +# fi +# +# echo "All args: $(g::args $g__APP_LAST_ARGPARSE)" } g::app::invoke "$@" diff --git a/src/g.bash b/src/g.bash index 5b5e57a..daa8975 100644 --- a/src/g.bash +++ b/src/g.bash @@ -1685,6 +1685,13 @@ function g::app::command::parse::has::flag() { return $(g::util::false) } +## +# Register the value of a positional argument in an argument set. +# +# @param position +# @param value +# @param uuid - the identifier of the argument set +# function g::app::command::parse::register::arg() { local position="$1" local value="$2" @@ -1695,6 +1702,13 @@ function g::app::command::parse::register::arg() { g::app::set "$varName" "$value" } +## +# Get the value of a positional argument in an argument set. +# +# @param position - the argument position +# @param uuid - the argument set identifier +# @echo the argument value +# function g::app::command::parse::get::arg() { local position="$1" local uuid="$2" @@ -1704,6 +1718,13 @@ function g::app::command::parse::get::arg() { g::app::get "$varName" } +## +# Check if an argument set has an argument for the given position. +# +# @param position - the argument position +# @param uuid - the argument set identifier +# @return true if the argument exists +# function g::app::command::parse::has::arg() { local position="$1" local uuid="$2" @@ -1717,6 +1738,14 @@ function g::app::command::parse::has::arg() { return $(g::util::false) } +## +# Parse a raw argument string for the given command and create a new argument set. +# +# Sets the argument set identifier in $g__APP_LAST_ARGPARSE. +# +# @param cmdName - the identifier of the command the arguments are for +# @param ...args - the raw arguments +# function g::app::command::parse() { local cmdName="$1" shift 1 @@ -1841,6 +1870,12 @@ function g::app::command::parse() { g__APP_LAST_ARGPARSE="$groupUuid" } +## +# Validate the parsed arguments for the given argument set. +# +# @param cmdName - the identifier of the command the arguments are for +# @param groupUuid - the identifier of the argument set +# function g::app::command::validate() { local cmdName="$1" local groupUuid="$2" @@ -1872,6 +1907,11 @@ function g::app::command::validate() { done } +## +# Print a usage message for the current application. +# +# @echo the message +# function g::app::usage() { local header="$g__APP_CURRENT_NAME" local description="$(g::app::get DESCRIPTION)" @@ -1904,6 +1944,12 @@ function g::app::usage() { echo "$commandsString" } +## +# Invoke a command in the current application with some arguments. +# +# @param commandName - the identifier of the command +# @param ...args - the arguments +# function g::app::invoke() { local commandName="${1:-}" shift 1 @@ -1943,6 +1989,7 @@ function g::app::invoke() { g::error "Run '$(basename $g__CALLER_PATH) help' to view usage." } +## WIP function g::args::buildAlias() { local uuid="$1" @@ -1955,6 +2002,13 @@ function g::args::buildAlias() { g__APP_LAST_ALIAS="g::args::alias::${uuid}" } +## +# Get the raw arguments for a given argument set. +# This is akin to $@ in a normal invocation. +# +# @param uuid - the identifier of the argument set +# @echo the raw argument string +# function g::args() { local uuid="$1" @@ -1966,6 +2020,13 @@ function g::args() { g::app::get "$allVar" } +## +# Get the value of a given argument in an argument set. +# +# @param uuid - the identifier of the argument set +# @param nameOrPosition - the argument name or index +# @echo the argument value +# function g::arg() { local uuid="$1" local nameOrPosition="$2" @@ -1983,6 +2044,13 @@ function g::arg() { g::app::command::parse::get::arg "$nameOrPosition" "$uuid" } +## +# Check if the given argument set has the given argument. +# +# @param uuid - the identifier of the argument set +# @param nameOrPosition - the argument name or index +# @return true if the argument is set +# function g::arg::has() { local uuid="$1" local nameOrPosition="$2" @@ -2000,6 +2068,13 @@ function g::arg::has() { return $(g::app::command::parse::has::arg "$nameOrPosition" "$uuid") } +## +# Get the value of a given flag in an argument set. +# +# @param uuid - the identifier of the argument set +# @param nameOrPosition - the flag name +# @echo the flag value +# function g::flag() { local uuid="$1" local nameOrPosition="$2" @@ -2017,6 +2092,13 @@ function g::flag() { g::app::command::parse::get::flag "$nameOrPosition" "$uuid" } +## +# Check if the given argument set has a given flag. +# +# @param uuid - the identifier of the argument set +# @param nameOrPosition - the flag name +# @return true if the flag is set +# function g::flag::has() { local uuid="$1" local nameOrPosition="$2" @@ -2037,6 +2119,12 @@ function g::flag::has() { +## +# Try to acquire the given lock. +# +# @param lockName +# @return true if acquired +# function g::lock::try() { local lockName="$1" @@ -2054,6 +2142,11 @@ function g::lock::try() { return $(g::util::false) } +## +# Acquire the given lock, sleeping between retries. +# +# @param lockName +# function g::lock::acquire() { local lockName="$1" while ! g::lock::try "$lockName"; do @@ -2061,11 +2154,22 @@ function g::lock::acquire() { done } +## +# Returns true if the current process holds the lock. +# +# @param lockName +# @return true if held +# function g::lock::holds() { local lockName="$1" return $(g::arr::includes "$lockName" "${g__LOCKING_HOLDS[@]}") } +## +# Release a lock if held. Throw otherwise. +# +# @param lockName +# function g::lock::release() { local lockName="$1" @@ -2079,6 +2183,9 @@ function g::lock::release() { g__LOCKING_HOLDS=("${g__LOCKING_HOLDS[@]/$lockName}") } +## +# Release all held locks before exit. +# function g::lock::cleanupForExit() { for lockFile in "${g__LOCKING_HOLDS[@]}"; do g::internal "Releasing lockfile: $lockFile" @@ -2086,16 +2193,28 @@ function g::lock::cleanupForExit() { done } +## +# Try to acquire the lock for this script's unique caller name. +# Throw an error if we are unable to acquire it. +# function g::lock::singleton() { if ! g::lock::try "$(g::lock::uniqueCallerName)"; then g::error::throw "Another instance of this script is already running." fi } +## +# Acquire the lock for this script's unique caller name. +# function g::lock::singleton::acquire() { g::lock::acquire "$(g::lock::uniqueCallerName)" } +## +# Generate a file-safe name unique to the caller script. +# +# @echo the unique name +# function g::lock::uniqueCallerName() { g::str::replace "$g__CALLER_PATH" '/' '__' }