-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
330 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,321 @@ | ||
#! /bin/bash | ||
# | ||
# List optional Bash modules available for import via `. $_GO_USE_MODULES` | ||
# | ||
# Usage: | ||
# A list of all available plugins by class (core, plugin, project): | ||
# {{go}} {{cmd}} [--paths|--summaries] | ||
# | ||
# The paths or one-line summaries for all or individual modules: | ||
# {{go}} {{cmd}} [--paths|--summaries] <module-glob...> | ||
# | ||
# The modules currently imported by the script and their source paths: | ||
# {{go}} {{cmd}} --imported | ||
# | ||
# Detailed help for an individual module: | ||
# {{go}} {{cmd}} [-h|-help|--help|help] <module-name> | ||
# | ||
# Detailed help for the module system itself: | ||
# {{go}} {{cmd}} [-h|-help|--help|help] | ||
# | ||
# Options: | ||
# -h,--help Show the help message for a specific module | ||
# --paths List the path of each module | ||
# --summaries List the summary of each module | ||
# | ||
# Where: | ||
# <module-name> Name of one of the installed modules | ||
# <module-glob> Module name, plugin package (trailing /), or glob pattern | ||
# | ||
# Modules are reusable libraries of Bash code that may be sourced by the | ||
# top-level `./go` script, by individual Bash command scripts, and individual | ||
# Bash functions by executing `. $_GO_USE_MODULES` followed by one or more | ||
# module names. | ||
# | ||
# For detailed information about the module system, run `{{go}} {{cmd}} help` | ||
# without a `<module-name>` argument. | ||
|
||
. "$_GO_CORE_DIR/lib/internal/command_descriptions" | ||
|
||
_@go.modules_help() { | ||
local module_name="$1" | ||
local __go_module_path | ||
|
||
if [[ "$#" -eq '0' ]]; then | ||
module_name='$_GO_USE_MODULES' | ||
__go_module_path="$_GO_USE_MODULES" | ||
elif [[ "$#" -ne '1' ]]; then | ||
@go.printf "Please specify only one module name.\n" >&2 | ||
return 1 | ||
elif ! _@go.modules_path "$module_name"; then | ||
@go.printf "Unknown module: $1\n" >&2 | ||
return 1 | ||
fi | ||
|
||
local __go_cmd_desc | ||
|
||
if ! _@go.command_description "$__go_module_path"; then | ||
@go.printf "ERROR: failed to parse description from %s\n" \ | ||
"$__go_cmd_path" >&2 | ||
return 1 | ||
fi | ||
@go.printf "$module_name - $__go_cmd_desc\n" | ||
} | ||
|
||
_@go.modules_path() { | ||
local module_name="$1" | ||
|
||
__go_module_path="$_GO_CORE_DIR/lib/$module_name" | ||
if [[ -f "$__go_module_path" ]]; then | ||
return | ||
fi | ||
|
||
# Convert <plugin>/<module> to _GO_SCRIPTS_DIR/plugins/<plugin>/lib/<module> | ||
__go_module_path="$_GO_SCRIPTS_DIR/plugins/${module_name/\///lib/}" | ||
if [[ -f "$__go_module_path" ]]; then | ||
return | ||
fi | ||
|
||
__go_module_path="$_GO_SCRIPTS_DIR/lib/$module_name" | ||
if [[ -f "$__go_module_path" ]]; then | ||
return | ||
fi | ||
return 1 | ||
} | ||
|
||
_@go.modules_find_all_in_dir() { | ||
local module_dir="$1" | ||
local glob="${2:-*}" | ||
local module_path | ||
local __go_cmd_desc | ||
|
||
for module_path in "$module_dir"/lib/$glob; do | ||
if [[ -f "$module_path" ]]; then | ||
__go_modules_paths+=("$module_path") | ||
module="${module_path##*/lib/}" | ||
__go_modules+=("$module") | ||
fi | ||
done | ||
} | ||
|
||
_@go.modules_add_info_to_module_names() { | ||
local action="$1" | ||
local padding='' | ||
local padding_len=0 | ||
local module | ||
local i | ||
|
||
if [[ -z "$action" ]]; then | ||
return | ||
fi | ||
|
||
for module in "${__go_modules[@]}"; do | ||
while [[ "${#padding}" -lt "${#module}" ]]; do | ||
padding+=' ' | ||
done | ||
done | ||
|
||
for ((i=0; i != "${#__go_modules[@]}"; ++i)); do | ||
module="${__go_modules[$i]}" | ||
padding_len="$((${#padding} - ${#module}))" | ||
__go_modules["$i"]="${module}${padding:0:padding_len} " | ||
done | ||
|
||
case "$action" in | ||
paths) | ||
for ((i=0; i != "${#__go_modules[@]}"; ++i)); do | ||
__go_modules["$i"]+="${__go_modules_paths[$i]#$_GO_ROOTDIR/}" | ||
done | ||
;; | ||
summaries) | ||
for ((i=0; i != "${#__go_modules[@]}"; ++i)); do | ||
if ! _@go.command_summary "${__go_modules_paths[$i]}"; then | ||
@go.printf "ERROR: failed to parse summary from %s\n" \ | ||
"$__go_cmd_path" >&2 | ||
return 1 | ||
fi | ||
__go_modules["$i"]+="$__go_cmd_desc" | ||
done | ||
;; | ||
*) | ||
@go.printf "ERROR: Unknown action: $action\n" >&2 | ||
return 1 | ||
esac | ||
} | ||
|
||
_@go.modules_search() { | ||
local action="$1" | ||
local glob="${2:-*}" | ||
local plugin | ||
local plugin_glob=('*' "$glob") | ||
local module_paths=() | ||
local plugin_modules=() | ||
local __go_cmd_desc | ||
local i | ||
|
||
if [[ "$glob" =~ / ]]; then | ||
plugin_glob[0]="${glob%/*}" | ||
plugin_glob[1]="${glob#*/}" | ||
fi | ||
|
||
__go_modules=() | ||
__go_modules_paths=() | ||
_@go.modules_find_all_in_dir "$_GO_CORE_DIR" "$glob" | ||
_@go.modules_add_info_to_module_names "$action" | ||
__go_core_modules=("${__go_modules[@]}") | ||
modules_paths+=("${__go_modules_paths[@]}") | ||
__go_modules_paths=() | ||
|
||
for plugin in "$_GO_SCRIPTS_DIR"/plugins/${plugin_glob[0]:-*}; do | ||
__go_modules=() | ||
_@go.modules_find_all_in_dir "$plugin" "${plugin_glob[1]:-*}" | ||
plugin="${plugin#$_GO_SCRIPTS_DIR/plugins/}" | ||
plugin_modules+=("${__go_modules[@]/#/$plugin/}") | ||
done | ||
|
||
__go_modules=("${plugin_modules[@]}") | ||
_@go.modules_add_info_to_module_names "$action" | ||
__go_plugin_modules=("${__go_modules[@]}") | ||
modules_paths+=("${__go_modules_paths[@]}") | ||
__go_modules_paths=() | ||
|
||
__go_modules=() | ||
_@go.modules_find_all_in_dir "$_GO_SCRIPTS_DIR" "$glob" | ||
_@go.modules_add_info_to_module_names "$action" | ||
__go_project_modules=("${__go_modules[@]}") | ||
__go_modules=("${__go_core_modules[@]}" "${__go_plugin_modules[@]}" | ||
"${__go_project_modules[@]}") | ||
__go_modules_paths=("${modules_paths[@]}") | ||
} | ||
|
||
_@go.modules_list_by_class() { | ||
local action="$1" | ||
local __go_core_modules | ||
local __go_plugin_modules | ||
local __go_project_modules | ||
local delimiter=$'\n'' ' | ||
|
||
_@go.modules_search "$action" | ||
|
||
if [[ "${#__go_core_modules}" -ne '0' ]]; then | ||
printf "From the core framework library:%s\n\n" \ | ||
"${__go_core_modules[*]/#/$delimiter}" | ||
fi | ||
|
||
if [[ "${#__go_plugin_modules}" -ne '0' ]]; then | ||
printf "From installed plugin libraries:%s\n\n" \ | ||
"${__go_plugin_modules[*]/#/$delimiter}" | ||
fi | ||
|
||
if [[ "${#__go_project_modules}" -ne '0' ]]; then | ||
printf "From the project library:%s\n\n" \ | ||
"${__go_project_modules[*]/#/$delimiter}" | ||
fi | ||
} | ||
|
||
_@go.modules_list() { | ||
local action="$1" | ||
shift | ||
local __go_modules=("$@") | ||
local __go_modules_paths=() | ||
local __go_module_path | ||
local module | ||
|
||
for module in "${__go_modules[@]}"; do | ||
if [[ "$module" == '*' ]]; then | ||
if [[ "${#__go_modules[@]}" -ne 1 ]]; then | ||
@go.printf "Do not specify other arguments when '*' is present.\n" >&2 | ||
return 1 | ||
fi | ||
_@go.modules_search | ||
elif [[ "$module" =~ \*|/ ]]; then | ||
_@go.modules_search '' "$module" | ||
elif ! _@go.modules_path "$module"; then | ||
@go.printf "Unknown module: $module\n" >&2 | ||
return 1 | ||
else | ||
__go_modules_paths+=("$__go_module_path") | ||
fi | ||
done | ||
|
||
_@go.modules_add_info_to_module_names "$action" | ||
@go.printf "%s\n" "${__go_modules[@]}" | ||
} | ||
|
||
_@go.modules_tab_completion() { | ||
local word_index="$1" | ||
shift | ||
local args=("$@") | ||
local first="${args[0]}" | ||
local word=("${args[$word_index]}") | ||
local flags=('-h' '-help' '--help' 'help' '--paths' '--summaries') | ||
local origIFS="$IFS" | ||
local plugins='' | ||
local flags_pattern | ||
|
||
if [[ "$#" -le '1' ]]; then | ||
flags+=('--imported') | ||
fi | ||
|
||
local IFS='|' | ||
flags_pattern="^(${flags[*]})$" | ||
IFS="$origIFS" | ||
|
||
if [[ "$#" -eq '0' || "$word_index" -eq '0' ]]; then | ||
echo "${flags[*]}" | ||
return | ||
elif [[ ! "$first" =~ $flags_pattern || "$first" == '--imported' ]]; then | ||
return | ||
fi | ||
|
||
local __go_core_modules | ||
local __go_plugin_modules | ||
local __go_project_modules | ||
_@go.modules_search "$action" | ||
|
||
if [[ "$word" =~ / ]]; then | ||
plugins="${__go_plugin_modules[*]}" | ||
else | ||
plugins="${__go_plugin_modules[*]/\/*//}" | ||
fi | ||
echo "${__go_core_modules[*]} ${plugins[*]} ${__go_project_modules[*]}" | ||
} | ||
|
||
_@go.modules() { | ||
local action="$1" | ||
shift | ||
|
||
case "$action" in | ||
--complete) | ||
# Tab completions | ||
_@go.modules_tab_completion "$@" | ||
;; | ||
-h|-help|--help|help) | ||
_@go.modules_help "$@" | ||
;; | ||
''|--paths|--summaries) | ||
action="${action#--}" | ||
if [[ "$#" -eq '0' ]]; then | ||
_@go.modules_list_by_class "$action" | ||
else | ||
_@go.modules_list "$action" "$@" | ||
fi | ||
;; | ||
--imported) | ||
if [[ "$#" -ne 0 ]]; then | ||
@go.printf 'The --imported option takes no other arguments.\n' >&2 | ||
return 1 | ||
elif [[ "${#_GO_IMPORTED_MODULES[@]}" -ne '0' ]]; then | ||
_@go.modules_list 'paths' "${_GO_IMPORTED_MODULES[@]}" | ||
fi | ||
;; | ||
-*) | ||
@go.printf "Unknown option: $action\n" >&2 | ||
return 1 | ||
;; | ||
*) | ||
_@go.modules_list '' "$action" "$@" | ||
esac | ||
} | ||
|
||
_@go.modules "$@" |