mirror of
https://github.com/armbian/build
synced 2025-09-24 19:47:06 +07:00
extensions: many fixes; allow for dumping the source of hooks, via dump_extension_method_sources_functions() and dump_extension_method_sources_body()
- fix: indent of generated sources - fix: no reason to source the generated file in a loop. do it once. 20x faster? - `dump_extension_method_sources_functions "name_of_hook"`: get function definitions (inside braces) - `dump_extension_method_sources_body "name_of_hook"`: get the function bodies (sans-braces)
This commit is contained in:
committed by
Igor Pečovnik
parent
61d85648ea
commit
d2bb1f893a
@@ -59,6 +59,60 @@ function call_extension_method() {
|
||||
done
|
||||
}
|
||||
|
||||
function dump_extension_method_sources_functions() {
|
||||
declare hook_name="${1}"
|
||||
declare dump_source_hook_function="dump_custom_sources_extension_hooks_${hook_name}"
|
||||
|
||||
function dump_function_declaration_and_braces() {
|
||||
declare function_name="${1}"
|
||||
echo -e "\t# Begin of function declaration '${function_name}'"
|
||||
declare -f "${function_name}" | sed -e '2d' -e '1d' -e '$d'
|
||||
echo -e "\t# End of function declaration '${function_name}'"
|
||||
echo ""
|
||||
}
|
||||
|
||||
display_alert "Extension Method source custom dump: ${hook_name}" "hook: ${hook_name} via dump_function_declaration_and_braces" "extensions"
|
||||
if [[ $(type -t ${dump_source_hook_function} || true) == function ]]; then
|
||||
display_alert "Dumping extensions hooks with function declaration and braces" "${dump_source_hook_function}" "debug"
|
||||
echo "# Begin of all custom functions for hook '${hook_name}'"
|
||||
"${dump_source_hook_function}" dump_function_declaration_and_braces
|
||||
echo "# End of all custom functions for hook '${hook_name}'"
|
||||
echo ""
|
||||
else
|
||||
display_alert "Extension Method source custom dump: ${hook_name}" "not found hook: ${dump_source_hook_function}: '$(type -t ${dump_source_hook_function} || true)'" "debug"
|
||||
fi
|
||||
|
||||
unset dump_body_sans_function_header_or_trailer
|
||||
return 0 # always success
|
||||
}
|
||||
|
||||
function dump_extension_method_sources_body() {
|
||||
declare hook_name="${1}"
|
||||
declare dump_source_hook_function="dump_custom_sources_extension_hooks_${hook_name}"
|
||||
|
||||
function dump_body_sans_function_header_or_trailer() {
|
||||
declare function_name="${1}"
|
||||
echo -e "\t# Begin of function body '${function_name}'"
|
||||
declare -f "${function_name}" | sed -e '2d' -e '1d' -e '$d'
|
||||
echo -e "\t# End of function body '${function_name}'"
|
||||
echo ""
|
||||
}
|
||||
|
||||
display_alert "Extension Method source custom dump: ${hook_name}" "hook: ${hook_name} via dump_body_sans_function_header_or_trailer" "extensions"
|
||||
if [[ $(type -t ${dump_source_hook_function} || true) == function ]]; then
|
||||
display_alert "Dumping extension source via custom method" "${dump_source_hook_function}" "debug"
|
||||
echo "# Begin of all custom sources for '${hook_name}'"
|
||||
"${dump_source_hook_function}" dump_body_sans_function_header_or_trailer
|
||||
echo "# End of all custom sources for '${hook_name}'"
|
||||
echo ""
|
||||
else
|
||||
display_alert "Extension Method source custom dump: ${hook_name}" "not found hook: ${dump_source_hook_function}: '$(type -t ${dump_source_hook_function} || true)'" "debug"
|
||||
fi
|
||||
|
||||
unset dump_body_sans_function_header_or_trailer
|
||||
return 0 # always success
|
||||
}
|
||||
|
||||
# what this does is a lot of bash mumbo-jumbo to find all board-,family-,config- or user-defined hook points.
|
||||
# the meat of this is 'compgen -A function', which is bash builtin that lists all defined functions.
|
||||
# it will then compose a full hook point (function) that calls all the implementing hooks.
|
||||
@@ -102,10 +156,16 @@ function initialize_extension_manager() {
|
||||
|
||||
declare -i hook_points_counter=0 hook_functions_counter=0 hook_point_functions_counter=0
|
||||
|
||||
# initialize the function declarations(init) file.
|
||||
local temp_source_file_for_hook_point="${EXTENSION_MANAGER_TMP_DIR}/extension_function_definition.sh"
|
||||
echo "# extension function definitions: " > "${temp_source_file_for_hook_point}"
|
||||
|
||||
# initialize the cleanups file.
|
||||
extension_manager_cleanup_file="${EXTENSION_MANAGER_TMP_DIR}/extension_function_cleanup.sh"
|
||||
echo "# cleanups: " > "${extension_manager_cleanup_file}"
|
||||
|
||||
local tab=" " newline="" # for indentation/readability...
|
||||
newline=$'\n' # ... of generated code
|
||||
local FUNCTION_SORT_OPTIONS="--general-numeric-sort --ignore-case" # --random-sort could be used to introduce chaos
|
||||
local hook_point=""
|
||||
# now loop over the hook_points.
|
||||
@@ -188,7 +248,6 @@ function initialize_extension_manager() {
|
||||
common_function_vars="${common_function_vars} HOOK_POINT_TOTAL_FUNCS=\"${hook_point_functions_counter}\""
|
||||
|
||||
display_alert "Extensions hook_point: ${hook_point} will run ${hook_point_functions_counter} functions" "${hook_point_functions_counter}" "extensions"
|
||||
local temp_source_file_for_hook_point="${EXTENSION_MANAGER_TMP_DIR}/extension_function_definition.sh"
|
||||
|
||||
declare hook_point_functions_loop_counter=0
|
||||
|
||||
@@ -201,11 +260,14 @@ function initialize_extension_manager() {
|
||||
# theres a lot of opportunities here, but for now I keep it simple:
|
||||
# - execute functions in the order defined by ${hook_point_functions} above
|
||||
# - define call-specific environment variables, to help extension authors to write portable extensions (eg: EXTENSION_DIR)
|
||||
cat <<- FUNCTION_DEFINITION_HEADER > "${temp_source_file_for_hook_point}"
|
||||
${hook_point}() {
|
||||
display_alert "Extension-managed hook starting '${hook_point}': will run ${hook_point_functions_counter} functions" "${hook_point_functions}" "extensionstrace"
|
||||
cat <<- FUNCTION_DEFINITION_HEADER >> "${temp_source_file_for_hook_point}"
|
||||
function ${hook_point}() {
|
||||
${tab}display_alert "Extension-managed hook starting '${hook_point}': will run ${hook_point_functions_counter} functions" "${hook_point_functions}" "extensionstrace"
|
||||
FUNCTION_DEFINITION_HEADER
|
||||
|
||||
# keep a list of the called functions. we'll use it to generate the source-dumping function, below.
|
||||
declare -a list_of_called_functions=()
|
||||
|
||||
for hook_point_function in ${hook_point_functions}; do
|
||||
hook_point_functions_loop_counter=$((hook_point_functions_loop_counter + 1))
|
||||
|
||||
@@ -225,17 +287,20 @@ function initialize_extension_manager() {
|
||||
# output the call, passing arguments, and also logging the output to the extensions log.
|
||||
# attention: don't pipe here (eg, capture output), otherwise hook function cant modify the environment (which is mostly the point)
|
||||
cat <<- FUNCTION_DEFINITION_CALLSITE >> "${temp_source_file_for_hook_point}"
|
||||
hook_point_function_trace_sources["${hook_point}${hook_extension_delimiter}${hook_point_function}"]="\${BASH_SOURCE[*]}"
|
||||
hook_point_function_trace_lines["${hook_point}${hook_extension_delimiter}${hook_point_function}"]="\${BASH_LINENO[*]}"
|
||||
display_alert "Extension Method ${hook_point}" "${hook_point_functions_loop_counter}/${hook_point_functions_counter} (ext:${EXTENSION:-built-in}) ${hook_point_function}" "extensionstrace"
|
||||
display_alert "Extension-managed hook starting ${hook_point_functions_loop_counter}/${hook_point_functions_counter}" "${hook_point}${hook_extension_delimiter}${hook_point_function}" "extensionstrace"
|
||||
${hook_point_function_variables} ${hook_point}${hook_extension_delimiter}${hook_point_function} "\$@"
|
||||
display_alert "Extension-managed hook finished ${hook_point_functions_loop_counter}/${hook_point_functions_counter}" "${hook_point}${hook_extension_delimiter}${hook_point_function}" "extensionstrace"
|
||||
${tab}hook_point_function_trace_sources["${hook_point}${hook_extension_delimiter}${hook_point_function}"]="\${BASH_SOURCE[*]}"
|
||||
${tab}hook_point_function_trace_lines["${hook_point}${hook_extension_delimiter}${hook_point_function}"]="\${BASH_LINENO[*]}"
|
||||
${tab}display_alert "Extension Method ${hook_point}" "${hook_point_functions_loop_counter}/${hook_point_functions_counter} (ext:${EXTENSION:-built-in}) ${hook_point_function}" "extensionstrace"
|
||||
${tab}display_alert "Extension-managed hook starting ${hook_point_functions_loop_counter}/${hook_point_functions_counter}" "${hook_point}${hook_extension_delimiter}${hook_point_function}" "extensionstrace"
|
||||
${tab}${hook_point_function_variables} ${hook_point}${hook_extension_delimiter}${hook_point_function} "\$@"
|
||||
${tab}display_alert "Extension-managed hook finished ${hook_point_functions_loop_counter}/${hook_point_functions_counter}" "${hook_point}${hook_extension_delimiter}${hook_point_function}" "extensionstrace"
|
||||
FUNCTION_DEFINITION_CALLSITE
|
||||
|
||||
# feed the list of called functions for the source-dumping function.
|
||||
list_of_called_functions+=("${hook_point}${hook_extension_delimiter}${hook_point_function}")
|
||||
|
||||
# output the cleanup for the implementation as well.
|
||||
cat <<- FUNCTION_CLEANUP_FOR_HOOK_POINT_IMPLEMENTATION >> "${extension_manager_cleanup_file}"
|
||||
unset ${hook_point}${hook_extension_delimiter}${hook_point_function}
|
||||
${tab}unset ${hook_point}${hook_extension_delimiter}${hook_point_function}
|
||||
FUNCTION_CLEANUP_FOR_HOOK_POINT_IMPLEMENTATION
|
||||
|
||||
# unset extension vars for the next loop.
|
||||
@@ -243,20 +308,45 @@ function initialize_extension_manager() {
|
||||
done
|
||||
|
||||
cat <<- FUNCTION_DEFINITION_FOOTER >> "${temp_source_file_for_hook_point}"
|
||||
display_alert "Extension-managed hook ending '${hook_point}': completed" "${hook_point}" "extensionstrace"
|
||||
} # end ${hook_point}() function
|
||||
${tab}display_alert "Extension-managed hook ending '${hook_point}': completed" "${hook_point}" "extensionstrace"
|
||||
} # end ${hook_point}() function${newline}
|
||||
FUNCTION_DEFINITION_FOOTER
|
||||
|
||||
# Extra function, running over the implementations and calling the arguments passed with each as parameter.
|
||||
# Useful for getting the source code of the implementations, for example, or the list of called functions
|
||||
# in a given hook. See dump_extension_method_sources_body() and dump_extension_method_sources_functions().
|
||||
cat <<- FUNCTION_DUMP_SOURCE_CUSTOM_START >> "${temp_source_file_for_hook_point}"
|
||||
function dump_custom_sources_extension_hooks_${hook_point}() {
|
||||
FUNCTION_DUMP_SOURCE_CUSTOM_START
|
||||
|
||||
declare function_name
|
||||
for function_name in "${list_of_called_functions[@]}"; do
|
||||
# call the arguments as function, passing the function name as argument
|
||||
echo "${tab}\"\${@}\" \"${function_name}\" " >> "${temp_source_file_for_hook_point}"
|
||||
done
|
||||
|
||||
cat <<- FUNCTION_DUMP_SOURCE_CUSTOM_END >> "${temp_source_file_for_hook_point}"
|
||||
} # end dump_source_extension_hooks_${hook_point}() function${newline}
|
||||
FUNCTION_DUMP_SOURCE_CUSTOM_END
|
||||
|
||||
# unsets, lest the next loop inherits them
|
||||
unset hook_point_functions hook_point_functions_sortname_to_realname hook_point_functions_realname_to_sortname
|
||||
|
||||
# source the generated function.
|
||||
# shellcheck disable=SC1090
|
||||
source "${temp_source_file_for_hook_point}"
|
||||
|
||||
rm -f "${temp_source_file_for_hook_point}"
|
||||
unset hook_point_functions hook_point_functions_sortname_to_realname hook_point_functions_realname_to_sortname list_of_called_functions
|
||||
done
|
||||
|
||||
# Extra debug, show the generated source and cleanup.
|
||||
if [[ "${SHOW_EXTENSIONS}" == "yes" ]]; then
|
||||
display_alert "Showing" "extensions initialization generated code" "info"
|
||||
run_tool_batcat --file-name "extensions_initialize.sh" "${temp_source_file_for_hook_point}"
|
||||
display_alert "Showing" "extensions cleanup generated code" "info"
|
||||
run_tool_batcat --file-name "extensions_cleanup.sh" "${extension_manager_cleanup_file}"
|
||||
fi
|
||||
|
||||
# source the generated function.
|
||||
# shellcheck disable=SC1090
|
||||
source "${temp_source_file_for_hook_point}"
|
||||
|
||||
rm -f "${temp_source_file_for_hook_point}"
|
||||
|
||||
# Dont show any output until we have more than 1 hook function (we implement one already, below)
|
||||
[[ ${hook_functions_counter} -gt 0 ]] &&
|
||||
display_alert "Extension manager" "processed ${hook_points_counter} Extension Methods calls and ${hook_functions_counter} Extension Method implementations" "info"
|
||||
|
||||
Reference in New Issue
Block a user