.idea | ||
src | ||
.gitignore | ||
example.bash | ||
LICENSE | ||
README.md |
g.bash
A Bash framework.
Documentation (WIP)
Global Helpers
g::eval [...command]
- Execute a command, but w/ in-framework loggingg::silence [...command]
- Execute a command, squashing all outputg::now
- Get a timestamp in ISO8061g::bc [...args]
- Execute abc
math statementg::awk [...inputs]
- Execute anawk
print command
Utilties (g::util
)
isNumeric [value]
- Checks if a given value is a number with optional decimal and positive/negativetrue
- A successful exit code/return value (0
)false
- A failure exit code/return value (1
)returnToEcho [...command]
- Execute a command that returnstrue
/false
and instead echo1
on success,0
otherwiseuuid
- Generate a UUIDuuid::underscore
- Generate a UUID (underscore-separated)escape [value]
- Bash-escape a value for safe use ineval
stringsrealpath [path]
- A non-GNU real path resolvertrace [?message] [?skip = frames to exclude]
- Generate a stack trace with an optional message
Strings (g::str
)
quote [str]
- Surround a string in quoteseval [...args]
- Execute a command and quote the outputlength [str]
- Get the number of chars in a stringpadLeft [str] [length] [pad character=' ']
- Left-pad a string to the given lengthpadRight [str] [length] [pad character=' ']
- Right-pad a string to the given lengthpadCenter [str] [length] [pad character=' ']
- Center-pad a string to the given lengthsubstring [str] [startAt] [length]
- Get a substringoffset [str] [startAt]
- Drop the firstn
characters of a stringreverse [str]
- Reverse a stringstartsWith [haystack] [needle]
- Check if the haystack starts with the needleendsWith [haystack] [needle]
- Check if the haystack ends with the needletrim [str]
- Trim the whitespace from either end of the stringindexOf [str] [substring]
- Print the character index where thesubstring
appears, if any (returnsg::util::false
if no match)replace [str] [find] [replace]
- Find-and-replace all occurrences in a stringreplace::once [str] [find] [replace]
- Find-and-replace the first occurrence in a string
Arrays (g::arr
)
Note: When passing an array as an argument to a function, it should be passed as
"${array[@]}"
includes [value] [array]
- Checks if a given value exists in the arrayassoc::hasKey [key] [array]
- Checks if an associative array has a given keyjoin [delimiter] [array]
- Implodes a list of values to a string using the given delimiter
Math (g::math
)
- Constants (
g::math::c
)e
- Euler's constantln2
- Natural log of 2ln10
- Natural log of 10pi
- Pisqrt05
- Square root of 1/2sqrt2
- Square root of 2
abs [num]
- Absolute value of a numbercubeRoot [num]
- Cube root of a numbersquareRoot [num]
- Square root of a numberlessThan [left] [right]
- Check ifleft < right
greaterThan [left] [right]
- Check ifleft > right
equalTo [left] [right]
- Check ifleft == right
, numericallyisPositive [num]
- Check ifnum > 0
isNegative [num]
- Check ifnum < 0
signOf [num]
- Prints the leading sign of a number (either+
or-
)mod [num] [modulus]
- Compute the modulus of a numberceiling [num]
- Round the number up to the nearest inttruncate [num]
- Truncate the number to an intfloor [num]
- Round the number down to the nearest intexponent [num] [power]
- Computenum^power
cos [num]
- Cosine of a numbersine [num]
- Sine of a numbertan [num]
- Tangent of a numberln [num]
- Natural log of a numberlog10 [num]
- Log base 10 of a numberlog2 [num]
- Log base 2 of a numberlog [num] [base]
- Arbitrary base logarithmrandom
- Get a random floatmax [...nums]
- Get the max value of some numbersmin [...nums]
- Get the min value of some numbersround [num] [precision]
- Round a number to the specified number of decimal points
Files (g::file
)
appendString [path] [string]
- Append the string contents to the end of a fileexists [path]
- Checks if a file existsdirectoryExists [path]
- Checks if a directory existstouch [path]
- Create a file if it does not existtruncate [path]
- If a file exists, empty its contents
Source Code (g::source
)
g::source
allows you to organize your scripts into multiple files, and perform filesystem-relative source imports. Similarly, it will prevent the same source file from being re-imported multiple times.
Example:
# index.bash
g::source src/setup
g::source src/logging
# src/setup.bash
g::source logging
# src/logging.bash
# This file is included once
g::source [path] [?up=1]
- Load a source file relative to the current script (must end in.bash
and will only be loaded once)resolve [path] [?up=1]
- Resolve the path of a source file relative to the current scriptexists [path] [?up=1]
- Check if a source file exists relative to the current scriptforce [path] [?up=1]
- Resolve and load a source file, bypassing the cachehas [path] [?up=1]
- Check if the given source file has been loaded
Configuration File (g::config
)
Provides a simple key-value way of storing persistent configuration.
Example:
echo "Last run: $(g::config::get last-run Never)"
g::config::set 'last-run' "$(g::now)"
setDefault [name]
- Set the default name of the config filegetDefault
- Get the default name of the config fileinit [?name]
- Make sure a config file existsget [name] [?default value]
- Get a value from the default config fileget::forFile [file] [name] [?default value]
- Get a value from a non-default config fileset [name] [value]
- Store a value in the default config fileset::forFile [file] [name] [value]
- Store a value in a non-default config file
Paths (g::path
)
concat [path] [...parts]
- Combine path segments into a path, accounting for leading and trailing slashesresolve [...parts]
- Concat path parts and determine the real pathresolveFrom [base dir] [...parts]
- Concat path parts and determine the real path relative to some base directorycd [...parts]
- Resolve path parts and change directoriestmp
- Get a temp file path (and mark it for cleanup)tmpdir
- Get a temp dir path (and mark it for cleanup)
Errors (g::error
)
throw [message]
- Throw an error- (global)
try
- (global)
catch
Logging (g::log
)
g::log
provides level- and target-aware logging output. The internal
level is used by g.bash
itself.
Available levels: error
| warn
| info
| debug
| verbose
| internal
enableTarget [name]
- Enable log outputs for the given targetenableAllTargets
- Enable log outputs for ALL targetsall
- Shorthand to enable the highest verbosity for ALL targetsgetLevel
- Get the current logging levelsetLevel [name]
- Set a new logging levelenable [target=stdout|stderr|file] [?param]
- Enable logging to the specified targetdisable [target=stdout|stderr|file]
- Disable logging to the specified targetg::error [output] [?target]
- Write a log message at theerror
level, optionally for a specific target- Same format for
g::warn
,g::info
,g::debug
,g::verbose
, andg::internal
- Same format for
g::log::rotate
- Archive the log file to a timestamped version and start a new one
Locks (g::lock
)
try [name]
- Try to acquire a lock, returningg::util::true
if successfulacquire [name]
- Acquire a lock, sleeping until it is availableholds [name]
- Check if we currently hold the given lockrelease [name]
- Release the given lock if heldsingleton
- Throw an error if this script is being executed concurrentlysingleton::acquire
- Wait for other instances of this script to finish
App Framework (g::app
)
g::app
is a way of defining multi-directive CLI applications with argument/option parsing.
Each application is broken up into "commands," and each command can have multiple arguments/flags.
Your source code can provide multiple applications (switching between them using g::app
) with app-scoped storage.
g::app [?name=app] [?description]
- Create a new top-level applicationget [name] [?default value]
- Get the value of an app-scoped variableset [name] [value]
- Set the value of an app-scoped variablehas [name]
- Check if the app-scope has a variable with the given nameusage
- Print usage information for the current applicationinvoke [command] [...args]
- Invoke a command in the current application
Defining Commands (g::app::command
)
A command is an invokable sub-command function for an application, which can have multiple flags and positional arguments associated with it.
When a command is executed, its arguments are parsed and a function app::<app name>::<command name>
is called. Basic example:
g::app myapp "An example application"
g::app::command greet "Greeting command"
g::app::command::arg name "Name of the person to greet" "World"
g::app::command::flag greeting= "Override the greeting"
function app::myapp::greet() {
local args="$1"
name="$(g::arg "$args" name)"
greeting="$(g::flag "$args" greeting)"
if [ -z "$greeting" ]; then
greeting="Hello,"
fi
echo "$greeting $name"
}
g::app::command [name] [?description]
- Start defining a new command in the current appexists [name]
- Check if a given command exists in the current appdescription [name]
- Get the description for a command in the current apparg [name] [?description] [?default value]
- Add a positional argument to the current commandflag [name] [?description]
- Add a position-less flag option. Ifname
trails with a=
, then a value is expectedrest [name] [?description]
- Register a rest-argument ([...args]
) for the current command
Accessing Arguments
When arguments for a command are parsed, they are stored in an "argument set." The argument set is a series of data structures containing the parsed/validated flags & positional arguments.
The argument set ID is passed to the command handler as the only parameter ($1
) and can be used to look up the values of flags and arguments.
g::args [uuid]
- Get the raw arguments from a parsed set (akin to$@
)g::arg [uuid] [name]
- Get the value of a positional argumentg::arg::has [uuid] [name]
- Checks if a positional argument was providedg::arg::rest [uuid]
- Get all the unmatched CLI arguments/flagsg::flag [uuid] [name]
- Get the value of a position-less flagg::flag::has [uuid] [name]
- Checks if a position-less flag was specified