-
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
4 changed files
with
387 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,334 @@ | ||
#! /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.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 | ||
|
||
. "$_GO_CORE_DIR/lib/internal/command_descriptions" | ||
|
||
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_PLUGINS_DIR/<plugin>/lib/<module> | ||
__go_module_path="$_GO_PLUGINS_DIR/${module_name/\///lib/}" | ||
if [[ -n "$_GO_PLUGINS_DIR" && -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 | ||
|
||
for module_path in "$module_dir"/lib/$glob; do | ||
if [[ -f "$module_path" ]]; then | ||
__go_modules+=("$module_path") | ||
fi | ||
done | ||
} | ||
|
||
_@go.modules_summaries() { | ||
local module_path | ||
local __go_cmd_desc | ||
|
||
. "$_GO_CORE_DIR/lib/internal/command_descriptions" | ||
|
||
for module_path in "${__go_modules[@]}"; do | ||
if ! _@go.command_summary "$module_path"; then | ||
@go.printf "ERROR: failed to parse summary from %s\n" "$module_path" >&2 | ||
return 1 | ||
fi | ||
__go_modules_summaries+=("$__go_cmd_desc") | ||
done | ||
} | ||
|
||
_@go.modules_produce_listing() { | ||
local action="$1" | ||
local modules=("${__go_modules[@]#$_GO_CORE_DIR/lib/}") | ||
modules=("${modules[@]#$_GO_SCRIPTS_DIR/lib/}") | ||
|
||
if [[ -n "$_GO_PLUGINS_DIR" ]]; then | ||
modules=("${modules[@]#$_GO_PLUGINS_DIR/}") | ||
modules=("${modules[@]/lib\//}") | ||
fi | ||
|
||
if [[ -z "$action" ]]; then | ||
__go_modules=("${modules[@]}") | ||
return | ||
fi | ||
|
||
. "$_GO_CORE_DIR/lib/internal/formatting" | ||
|
||
local __go_padded_items=() | ||
local __go_zipped_items=() | ||
|
||
_@go.pad_items 'modules' | ||
modules=("${__go_padded_items[@]}") | ||
|
||
case "$action" in | ||
paths) | ||
__go_modules=("${__go_modules[@]#$_GO_ROOTDIR/}") | ||
_@go.zip_items 'modules' '__go_modules' | ||
;; | ||
summaries) | ||
local __go_modules_summaries=() | ||
_@go.modules_summaries | ||
_@go.zip_items 'modules' '__go_modules_summaries' | ||
;; | ||
*) | ||
@go.printf 'ERROR: Unknown action: %s\n' "$action" >&2 | ||
return 1 | ||
esac | ||
__go_modules=("${__go_zipped_items[@]}") | ||
} | ||
|
||
_@go.modules_search() { | ||
local glob="${1:-*}" | ||
local plugin_glob=("*" "$glob") | ||
local plugin | ||
|
||
if [[ "$glob" =~ / ]]; then | ||
plugin_glob[0]="${glob%/*}" | ||
plugin_glob[1]="${glob#*/}" | ||
# Since it's plugin glob, prevent deep core/lib and project/lib matches. | ||
glob='/' | ||
fi | ||
|
||
_@go.modules_find_all_in_dir "$_GO_CORE_DIR" "$glob" | ||
__go_core_modules_end="${#__go_modules[@]}" | ||
|
||
if [[ -n "$_GO_PLUGINS_DIR" ]]; then | ||
for plugin in "$_GO_PLUGINS_DIR/"${plugin_glob[0]:-*}; do | ||
_@go.modules_find_all_in_dir "$plugin" "${plugin_glob[1]:-*}" | ||
done | ||
fi | ||
__go_plugin_modules_end="${#__go_modules[@]}" | ||
|
||
_@go.modules_find_all_in_dir "$_GO_SCRIPTS_DIR" "$glob" | ||
__go_project_modules_end="${#__go_modules[@]}" | ||
} | ||
|
||
_@go.modules_emit_class() { | ||
local class="$1" | ||
local action="$2" | ||
local begin="$3" | ||
local end="$4" | ||
local delimiter=$'\n'' ' | ||
local __go_modules=("${__go_all_modules[@]:$begin:$((end - begin))}") | ||
|
||
if [[ "${#__go_modules[@]}" -ne '0' ]]; then | ||
_@go.modules_produce_listing "$action" | ||
printf "From the %s:%s\n\n" "$class" "${__go_modules[*]/#/$delimiter}" | ||
fi | ||
} | ||
|
||
_@go.modules_list_by_class() { | ||
local action="$1" | ||
local __go_modules=() | ||
local __go_core_modules_end=0 | ||
local __go_plugin_modules_end=0 | ||
local __go_project_modules_end=0 | ||
local __go_all_modules | ||
|
||
_@go.modules_search | ||
__go_all_modules=("${__go_modules[@]}") | ||
_@go.modules_emit_class 'core framework library' "$action" \ | ||
0 "$__go_core_modules_end" | ||
_@go.modules_emit_class 'installed plugin libraries' "$action" \ | ||
"$__go_core_modules_end" "$__go_plugin_modules_end" | ||
_@go.modules_emit_class 'project library' "$action" \ | ||
"$__go_plugin_modules_end" "$__go_project_modules_end" | ||
} | ||
|
||
_@go.modules_list() { | ||
local action="$1" | ||
shift | ||
local module_specs=("$@") | ||
local __go_modules=() | ||
local __go_module_path | ||
local module_spec | ||
|
||
for module_spec in "${module_specs[@]}"; do | ||
if [[ "$module_spec" == '*' ]]; then | ||
if [[ "${#module_specs[@]}" -ne 1 ]]; then | ||
@go.printf "Do not specify other arguments when '*' is present.\n" >&2 | ||
return 1 | ||
fi | ||
_@go.modules_search | ||
elif [[ "$module_spec" =~ \*|/$ ]]; then | ||
_@go.modules_search "$module_spec" | ||
elif ! _@go.modules_path "$module_spec"; then | ||
@go.printf "Unknown module: $module_spec\n" >&2 | ||
return 1 | ||
else | ||
__go_modules+=("$__go_module_path") | ||
fi | ||
done | ||
|
||
_@go.modules_produce_listing "$action" | ||
local IFS=$'\n' | ||
echo "${__go_modules[*]}" | ||
} | ||
|
||
_@go.modules_tab_completion() { | ||
local word_index="$1" | ||
shift | ||
local args=("$@") | ||
local first="${args[0]}" | ||
local word=("${args[$word_index]}") | ||
local glob="${word}*" | ||
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_modules | ||
local plugin | ||
local module | ||
|
||
if [[ -n "$_GO_PLUGINS_DIR" ]]; then | ||
if [[ "$glob" =~ / ]]; then | ||
plugin="${glob%/*}" | ||
_@go.modules_find_all_in_dir "$_GO_PLUGINS_DIR/$plugin" "${glob#*/}*" | ||
_@go.modules_produce_listing | ||
echo "${__go_modules[*]}" | ||
return | ||
fi | ||
|
||
for plugin in "$_GO_PLUGINS_DIR/"$glob; do | ||
for module in "$plugin/lib/"*; do | ||
if [[ -f "$module" ]]; then | ||
__go_modules+=("$plugin/") | ||
break | ||
fi | ||
done | ||
done | ||
fi | ||
|
||
_@go.modules_find_all_in_dir "$_GO_CORE_DIR" "$glob" | ||
_@go.modules_find_all_in_dir "$_GO_SCRIPTS_DIR" "$glob" | ||
_@go.modules_produce_listing | ||
echo "${__go_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 "$@" |
Oops, something went wrong.