summaryrefslogtreecommitdiffhomepage
path: root/subr.ex
diff options
context:
space:
mode:
Diffstat (limited to 'subr.ex')
-rw-r--r--subr.ex/ex_init.subr2
-rw-r--r--subr.ex/ex_pkg.subr289
-rw-r--r--subr.ex/ex_pkg_depends.subr225
-rw-r--r--subr.ex/ex_pkg_dispatch.subr26
-rw-r--r--subr.ex/ex_pkg_restart.subr8
5 files changed, 324 insertions, 226 deletions
diff --git a/subr.ex/ex_init.subr b/subr.ex/ex_init.subr
index e9b4d3f4..5dc4f857 100644
--- a/subr.ex/ex_init.subr
+++ b/subr.ex/ex_init.subr
@@ -321,7 +321,7 @@ ex_init_files() {
#
# ex_init_logging() - initialise build logging
# @_rstatus: out reference to variable of status string on failure
-# @_rverbose_tags: in reference toout variable of -V argument value
+# @_rverbose_tags: in reference to out variable of -V argument value
# @_verbose: -[vV] argument value
#
# Returns: zero (0) on success, non-zero (>0) on failure
diff --git a/subr.ex/ex_pkg.subr b/subr.ex/ex_pkg.subr
index c914360e..2475f447 100644
--- a/subr.ex/ex_pkg.subr
+++ b/subr.ex/ex_pkg.subr
@@ -4,48 +4,29 @@
#
#
-# ex_pkg_check_depends() - check single named package for unsatisfied dependencies
-# @_checkfl: enable (1) or inhibit (0) dependency expansion
-# @_rpkg_disabled: in reference to variable of list of disabled packages
-# @_rpkg_finished: in reference to variable of list of finished packages
-# @_pkg_name: single package name
-# @_rpkg_names: in reference to variable of list of package names
-# @_workdir: pathname to build-specific temporary directory
+# ex_pkg_copy_group_vars() - copy build group variables into build group
+# @_group_name_src: single source build group name
+# @_group_name_dst: single destination build group name
+# @[_build_vars_default]: optional list of default build variables, defaults to ${DEFAULT_BUILD_VARS}
#
-# Returns: zero (0) given no outstanding dependencies, non-zero (>0) otherwise
-# Side effects: ${PKG_${_PKG_NAME}_DEPENDS_FULL} may be mutated
+# Returns: zero (0) on success, non-zero (>0) on failure.
#
-ex_pkg_check_depends() {
- local _epcd_checkfl="${1}" _epcd_rpkg_disabled="${2}" _epcd_rpkg_finished="${3#\$}" \
- _epcd_pkg_name="${4}" _epcd_rpkg_names="${5#\$}" _epcd_workdir="${6}" \
- _epcd_dependfl=0 _epcd_depends="" _epcd_pkg_name_depend="";
-
- if [ "${_epcd_checkfl}" -eq 1 ]; then
- if ! rtl_get_var_unsafe \$_epcd_depends -u "PKG_"${_epcd_pkg_name}"_DEPENDS_FULL"\
- || [ "${_epcd_depends:+1}" != 1 ];
- then
- if rtl_get_var_unsafe \$_epcd_depends -u "PKG_"${_epcd_pkg_name}"_DEPENDS";
- then
- eval PKG_"${_epcd_pkg_name}"_DEPENDS_FULL='$(rtl_uniq ${_epcd_depends})';
- else
- return 0;
- fi;
+ex_pkg_copy_group_vars() {
+ local _epcgv_group_name_src="${1#\$}" _epcgv_group_name_dst="${2#\$}" \
+ _epcgv_build_vars_default="${3:-${DEFAULT_BUILD_VARS}}" \
+ _epcgv_group_name_dst_uc="" _epcgv_group_name_src_uc="" \
+ _epcgv_vname="" _epcgv_vval="";
+ rtl_toupper2 \$_epcgv_group_name_dst \$_epcgv_group_name_dst_uc;
+ rtl_toupper2 \$_epcgv_group_name_src \$_epcgv_group_name_src_uc;
+
+ for _epcgv_vname in ${_epcgv_build_vars_default}; do
+ if rtl_get_var_unsafe \$_epcgv_vval "${_epcgv_group_name_src_uc}_${_epcgv_vname}"\
+ && [ "${_epcgv_vval:+1}" = 1 ]; then
+ rtl_set_var_unsafe "${_epcgv_group_name_dst_uc}_${_epcgv_vname}" "${_epcgv_vval}";
fi;
+ done;
- for _epcd_pkg_name_depend in ${_epcd_depends}; do
- if ! rtl_lmatch "${_epcd_rpkg_disabled}" "${_epcd_pkg_name_depend}"\
- && ! ex_pkg_state_test2 "${_epcd_workdir}" "${_epcd_pkg_name_depend}" finish;
- then
- if ! rtl_lmatch "${_epcd_rpkg_names}" "${_epcd_pkg_name_depend}"; then
- rtl_log_msgV "fatalexit" "${MSG_build_unknown_dep}" "${_epcd_pkg_name_depend}" "${_epcd_pkg_name}";
- else
- _epcd_dependfl=1; break;
- fi;
- fi;
- done;
- fi;
-
- return "${_epcd_dependfl}";
+ return 0;
};
#
@@ -180,7 +161,7 @@ ex_pkg_get_package_vars() {
eval ${_epgpv_rpkg_vnames}='${_epgpv_vnames}';
return 0;
-}
+};
#
# ex_pkg_load_vars() - load build variables
@@ -249,197 +230,89 @@ ex_pkg_load_vars() {
# Returns: zero (0) on success, non-zero (>0) on failure.
#
ex_pkg_load_groups() {
- local _eplg_rgroups="${1#\$}" _eplg_rgroups_noauto="${2#\$}" \
- _eplg_build_groups="" _eplg_build_groups_noauto="" \
- _eplg_fname="" _eplg_group="" _eplg_group_noautofl=0 \
- _eplg_group_target="" _eplg_group_target_uc="" \
- _eplg_group_target_appendfl=0 _eplg_groups="" _eplg_pkg_name="" \
- _eplg_pkg_names="";
+ local _eplg_rgroups="${1#\$}" _eplg_rgroups_noauto="${2#\$}" \
+ _eplg_build_groups="" _eplg_build_groups_noauto="" _eplg_fname="";
+ EXP_PKG_REGISTER_GROUP_RGROUPS="${_eplg_rgroups}";
+ EXP_PKG_REGISTER_GROUP_RGROUPS_NOAUTO="${_eplg_rgroups_noauto}";
for _eplg_fname in $(find ./groups.d -name *.group | sort); do
- rtl_fileop source_opt "${_eplg_fname}";
-
- _eplg_group="${_eplg_fname##*/}";
- _eplg_group="${_eplg_group%.group}";
- _eplg_group="${_eplg_group#*.}";
-
- if [ "${GROUP_TARGET_APPEND:+1}" = 1 ]; then
- _eplg_group_target="${GROUP_TARGET_APPEND}";
- _eplg_group_target_appendfl=1;
- unset GROUP_TARGET_APPEND;
- else
- _eplg_group_target="${_eplg_group}";
- _eplg_group_target_appendfl=0;
- fi;
-
- _eplg_group_noautofl=0;
- if ! rtl_lmatch \$_eplg_groups "${_eplg_group_target}"; then
- rtl_lconcat \$_eplg_groups "${_eplg_group_target}";
- if eval [ \"\${GROUP_AUTO:+1}\" = 1 ]; then
- if eval [ \"\${GROUP_AUTO:-0}\" -ne 0 ]; then
- _eplg_group_noautofl=0;
- rtl_lconcat \$_eplg_build_groups "${_eplg_group_target}";
- else
- _eplg_group_noautofl=1;
- rtl_lconcat \$_eplg_build_groups_noauto "${_eplg_group_target}";
- fi;
- unset GROUP_AUTO;
- else
- rtl_lconcat \$_eplg_build_groups "${_eplg_group_target}";
- fi;
- fi;
-
- if rtl_get_var_unsafe \$_eplg_pkg_names -u "${_eplg_group}_PACKAGES"\
- && [ "${_eplg_pkg_names:+1}" = 1 ]; then
- if [ "${_eplg_group_target_appendfl}" -eq 1 ]; then
- rtl_toupper2 \$_eplg_group_target \$_eplg_group_target_uc;
- rtl_lconcat "\$${_eplg_group_target_uc}_PACKAGES" "${_eplg_pkg_names}";
- fi;
-
- if [ "${_eplg_group_noautofl}" -eq 0 ]; then
- for _eplg_pkg_name in ${_eplg_pkg_names}; do
- rtl_set_var_unsafe -u "PKG_${_eplg_pkg_name}_GROUP" "${_eplg_group}";
- rtl_set_var_unsafe -u "PKG_${_eplg_pkg_name}_GROUP_FNAME" "${_eplg_fname}";
- done;
- fi;
- fi;
+ rtl_fileop source_with_fnamevar "${_eplg_fname}";
done;
+ unset EXP_PKG_REGISTER_GROUP_RGROUPS;
+ unset EXP_PKG_REGISTER_GROUP_RGROUPS_NOAUTO;
- _eplg_build_groups="$(rtl_uniq "${_eplg_build_groups}")";
- eval ${_eplg_rgroups}=\"${_eplg_build_groups}\";
-
- if [ "${_eplg_rgroups_noauto:+1}" = 1 ]; then
- _eplg_build_groups_noauto="$(rtl_uniq "${_eplg_build_groups_noauto}")";
- eval ${_eplg_rgroups_noauto}=\"${_eplg_build_groups_noauto}\";
- fi;
+ for _eplg_fname in $(find ./groups.d -mindepth 2 -name *.package | sort); do
+ rtl_fileop source_with_fnamevar "${_eplg_fname}";
+ done;
return 0;
};
#
-# ex_pkg_unfold_depends() - unfold list of package names into dependency-expanded set of complete, disabled, finished, and outstanding package names
-# @_rdisabled: in reference toout variable of disabled packages
-# @_rfinished: in reference toout variable of finished packages
-# @_rnames: out reference to variable of package names
-# @_checkfl: enable (1) or inhibit (0) dependency expansion
-# @_forcefl: enable (1) or inhibit (0) forcibly rebuilding finished packages
-# @_group_name: build group name
-# @_pkg_names: list of package names
-# @_restart: optional whitespace-separated list of package names to rebuild
-# @_test_finished: only exclude disabled packages (0,) split finished packages
-# @_workdir: pathname to build-specific temporary directory
+# ex_pkg_register() - register single package
+# @_pkg_name: single package name
+# @_fname: pathname to file package is defined in, relative to midipix_build root
+# @[_group_name]: optional build group name; inferred from @_fname if not specified
#
# Returns: zero (0) on success, non-zero (>0) on failure.
#
-ex_pkg_unfold_depends() {
- local _epud_rdisabled="${1#\$}" _epud_rfinished="${2#\$}" _epud_rnames="${3#\$}" \
- _epud_checkfl="${4}" _epud_forcefl="${5}" _epud_group_name="${6}" \
- _epud_pkg_names="${7}" _epud_restart="${8}" _epud_test_finished="${9}" \
- _epud_workdir="${10}" \
- _epud_pkg_disabled="" _epud_pkg_force="" _epud_pkg_name="" \
- _epud_pkg_names_new="" _epud_restartfl=0;
-
- if [ "${_epud_restart:+1}" = 1 ]\
- && ! rtl_lmatch \$_epud_restart "ALL LAST"; then
- rtl_lsearch \$_epud_pkg_names "${_epud_restart}";
- fi;
- if [ "${_epud_restart:+1}" = 1 ]\
- && [ "${_epud_checkfl:-0}" -eq 1 ]; then
- rtl_lunfold_dependsV 'PKG_${_rld_name}_DEPENDS' \$_epud_pkg_names ${_epud_pkg_names};
- _epud_pkg_names="$(rtl_uniq ${_epud_pkg_names})";
+ex_pkg_register() {
+ local _epr_pkg_name="${1}" _epr_fname="${2}" _epr_group_name="${3:-}" \
+ _epr_group_name_uc="" _epr_group_noautofl=0;
+
+ if [ "${_epr_group_name:+1}" != 1 ]; then
+ _epr_group_name="${_epr_fname#./*/}";
+ _epr_group_name="${_epr_group_name%%/*}";
+ _epr_group_name="${_epr_group_name%.d}";
+ _epr_group_name="${_epr_group_name#*.}";
fi;
- for _epud_pkg_name in ${_epud_pkg_names}; do
- if [ "${_epud_restart}" = "ALL" ]\
- || rtl_lmatch \$_epud_restart "${_epud_pkg_name}"; then
- _epud_restartfl=1;
- else
- _epud_restartfl=0;
- fi;
-
- if rtl_get_var_unsafe \$_epud_pkg_disabled -u "PKG_${_epud_pkg_name}_DISABLED"\
- && [ "${_epud_pkg_disabled}" = 1 ];
- then
- rtl_lconcat "${_epud_rdisabled}" "${_epud_pkg_name}";
-
- elif [ "${_epud_test_finished:-1}" -eq 1 ]\
- && ex_pkg_state_test2 "${_epud_workdir}" "${_epud_pkg_name}" finish\
- && [ "${_epud_restartfl:-0}" -eq 0 ]\
- && [ "${_epud_forcefl:-0}" -ne 1 ]\
- && rtl_get_var_unsafe \$_epud_pkg_force -u "${_epud_group_name}_FORCE"\
- && [ "${_epud_pkg_force}" != 1 ];
- then
- rtl_lconcat "${_epud_rfinished}" "${_epud_pkg_name}";
-
- else
- rtl_lconcat \$_epud_pkg_names_new "${_epud_pkg_name}";
- fi;
- done;
-
- eval ${_epud_rdisabled}='$(rtl_uniq2 "${_epud_rdisabled}")';
- eval ${_epud_rfinished}='$(rtl_uniq2 "${_epud_rfinished}")';
- eval ${_epud_rnames}='$(rtl_uniq "${_epud_pkg_names_new}")';
+ rtl_toupper2 \$_epr_group_name \$_epr_group_name_uc;
+ rtl_lconcat "\$${_epr_group_name_uc}_PACKAGES" "${_epr_pkg_name}";
+ rtl_set_var_unsafe -u "PKG_${_epr_pkg_name}_GROUP" "${_epr_group_name}";
+ rtl_set_var_unsafe -u "PKG_${_epr_pkg_name}_GROUP_FNAME" "${_epr_fname}";
return 0;
};
#
-# ex_pkg_unfold_rdepends() - unfold list of package names into reverse dependency-expanded set of complete, disabled, finished, and outstanding package names
-# @_rdisabled: in reference toout variable of disabled packages
-# @_rfinished: in reference toout variable of finished packages
-# @_rnames: out reference to variable of package names
-# @_group_name: build group name
-# @_pkg_names: list of package names
-# @_restart: optional whitespace-separated list of package names to rebuild
-# @_test_finished: only exclude disabled packages (0,) split finished packages
-# @_workdir: pathname to build-specific temporary directory
+# ex_pkg_register_group() - register single group
+# @_group_name: single group name
+# @_fname: pathname to file group is defined in, relative to midipix_build root
+# @[_ownerfl]: "owner" for groups that own their packages, "copy" for shorthand groups referring to packages from other groups
+# @[_autofl]: "auto" for groups to build by default, "noauto" for optional groups only built when requested
+# ${EXP_PKG_REGISTER_GROUP_RGROUPS}: inout reference to variable of build groups
+# ${EXP_PKG_REGISTER_GROUP_RGROUPS_NOAUTO}: inout reference to variable of build groups only built when requested
#
-# Returns: zero (0) on success, non-zero (>0) on failure.
+# Returns: zero (0) on success, non-zero (>0) on failure.
#
-ex_pkg_unfold_rdepends() {
- local _epur_rdisabled="${1#\$}" _epur_rfinished="${2#\$}" _epur_rnames="${3#\$}" \
- _epur_group_name="${4}" _epur_pkg_names="${5}" _epur_restart="${6}" \
- _epur_test_finished="${7}" _epur_workdir="${8}" \
- _epur_depends="" _epur_disabled=0 _epur_force=0 _epur_pkg_depends="" \
- _epur_pkg_name="" _epur_pkg_names_new="" _epur_pkg_name_depend="" \
- _epur_pkg_rdepends="";
-
- for _epur_pkg_name_depend in ${_epur_restart}; do
- for _epur_pkg_name in ${_epur_pkg_names}; do
- if [ "${_epur_pkg_name}" = "${_epur_pkg_name_depend}" ]; then
- continue;
-
- elif rtl_get_var_unsafe \$_epur_depends -u "PKG_"${_epur_pkg_name}"_DEPENDS"\
- && rtl_lunfold_dependsV 'PKG_${_rld_name}_DEPENDS' \$_epur_pkg_depends ${_epur_depends}\
- && [ "${_epur_pkg_depends:+1}" = 1 ]\
- && rtl_lmatch \$_epur_pkg_depends "${_epur_pkg_name_depend}";
- then
- if rtl_get_var_unsafe \$_epur_disabled -u "PKG_${_epur_pkg_name}_DISABLED"\
- && [ "${_epur_disabled}" = 1 ];
- then
- rtl_lconcat "${_epur_rdisabled}" "${_epur_pkg_name}";
-
- elif [ "${_epur_test_finished}" -eq 1 ]\
- && ex_pkg_state_test2 "${_epur_workdir}" "${_epur_pkg_name}" finish\
- && rtl_get_var_unsafe \$_epur_force -u "${_epur_group_name}_FORCE"\
- && [ "${_epur_force}" != 1 ];
- then
- rtl_lconcat "${_epur_rfinished}" "${_epur_pkg_name}";
-
- elif [ "${_epur_test_finished:-1}" -eq 0 ]\
- || ! ex_pkg_state_test2 "${_epur_workdir}" "${_epur_pkg_name}" finish\
- || ( rtl_get_var_unsafe \$_epur_force -u "${_epur_group_name}_FORCE"\
- && [ "${_epur_force}" = 1 ] );
- then
- rtl_lconcat \$_epur_pkg_names_new "${_epur_pkg_name}";
- fi;
- fi;
- done;
- done;
+ex_pkg_register_group() {
+ local _eprg_group_name="${1}" _eprg_fname="${2}" \
+ _eprg_ownerfl="${3:-owner}" _eprg_autofl="${4:-auto}" \
+ _eprg_pkg_name="" _eprg_pkg_names="" _eprg_rgroups="";
+
+ case "${_eprg_autofl}" in
+ auto) _eprg_rgroups="${EXP_PKG_REGISTER_GROUP_RGROUPS}"; ;;
+ noauto) _eprg_rgroups="${EXP_PKG_REGISTER_GROUP_RGROUPS_NOAUTO}"; ;;
+ *) ;;
+ esac;
+ if ! rtl_lmatch "${_eprg_rgroups}" "${_eprg_group_name}"; then
+ rtl_lconcat "${_eprg_rgroups}" "${_eprg_group_name}";
+ fi;
- eval ${_epur_rdisabled}='$(rtl_uniq2 "${_epur_rdisabled}")';
- eval ${_epur_rfinished}='$(rtl_uniq2 "${_epur_rfinished}")';
- eval ${_epur_rnames}='$(rtl_uniq "${_epur_pkg_names_new}")';
+ case "${_eprg_ownerfl}" in
+ owner)
+ if rtl_get_var_unsafe \$_eprg_pkg_names -u "${_eprg_group_name}_PACKAGES"\
+ && [ "${_eprg_pkg_names:+1}" = 1 ]; then
+ for _eprg_pkg_name in ${_eprg_pkg_names}; do
+ rtl_set_var_unsafe -u "PKG_${_eprg_pkg_name}_GROUP" "${_eprg_group_name}";
+ rtl_set_var_unsafe -u "PKG_${_eprg_pkg_name}_GROUP_FNAME" "${_eprg_fname}";
+ done;
+ fi;
+ ;;
+ copy) ;;
+ *) ;;
+ esac;
return 0;
};
diff --git a/subr.ex/ex_pkg_depends.subr b/subr.ex/ex_pkg_depends.subr
new file mode 100644
index 00000000..6a4f5aae
--- /dev/null
+++ b/subr.ex/ex_pkg_depends.subr
@@ -0,0 +1,225 @@
+#
+# Copyright (c) 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023 LucĂ­a Andrea Illanes Albornoz <lucia@luciaillanes.de>
+# set +o errexit -o noglob -o nounset is assumed.
+#
+
+#
+# ex_pkg_check_depends() - check single named package for unsatisfied dependencies
+# @_checkfl: enable (1) or inhibit (0) dependency expansion
+# @_rpkg_disabled: in reference to variable of list of disabled packages
+# @_rpkg_finished: in reference to variable of list of finished packages
+# @_pkg_name: single package name
+# @_rpkg_names: in reference to variable of list of package names
+# @_workdir: pathname to build-specific temporary directory
+#
+# Returns: zero (0) given no outstanding dependencies, non-zero (>0) otherwise
+#
+ex_pkg_check_depends() {
+ local _epcd_checkfl="${1}" _epcd_rpkg_disabled="${2}" _epcd_rpkg_finished="${3#\$}" \
+ _epcd_pkg_name="${4}" _epcd_rpkg_names="${5#\$}" _epcd_workdir="${6}" \
+ _epcd_dependfl=0 _epcd_depends="" _epcd_pkg_name_depend="";
+
+ if [ "${_epcd_checkfl}" -eq 1 ]\
+ && rtl_get_var_unsafe \$_epcd_depends -u "PKG_"${_epcd_pkg_name}"_DEPENDS"\
+ && [ "${_epcd_depends:+1}" = 1 ]; then
+ for _epcd_pkg_name_depend in ${_epcd_depends}; do
+ if ! rtl_lmatch "${_epcd_rpkg_disabled}" "${_epcd_pkg_name_depend}"\
+ && ! ex_pkg_state_test2 "${_epcd_workdir}" "${_epcd_pkg_name_depend}" finish;
+ then
+ if ! rtl_lmatch "${_epcd_rpkg_names}" "${_epcd_pkg_name_depend}"; then
+ rtl_log_msgV "fatalexit" "${MSG_build_unknown_dep}" "${_epcd_pkg_name_depend}" "${_epcd_pkg_name}";
+ else
+ _epcd_dependfl=1; break;
+ fi;
+ fi;
+ done;
+ fi;
+
+ return "${_epcd_dependfl}";
+};
+
+#
+# ex_pkg_check_depends_unknown() - check single named package for unknown dependencies
+# @_pkg_name: single package name
+# @_rpkg_names_set: in reference to variable of set of package names
+# @_rpkg_unknown: out reference to variable of list of finished packages
+#
+# Returns: zero (0) given no unknown dependencies, non-zero (>0) otherwise
+#
+ex_pkg_check_depends_unknown() {
+ local _epcdu_pkg_name="${1}" _epcdu_rpkg_names_set="${2#\$}" \
+ _epcdu_rpkg_unknown="${3#\$}" \
+ _epcdu_defined=0 _epcdu_depends="" _epcdu_pkg_name_depend="" \
+ _epcdu_rc=0;
+
+ if rtl_get_var_unsafe \$_epcdu_depends -u "PKG_"${_epcdu_pkg_name}"_DEPENDS"\
+ && [ "${_epcdu_depends:+1}" = 1 ]; then
+ for _epcdu_pkg_name_depend in ${_epcdu_depends}; do
+ if [ "${_epcdu_pkg_name_depend#*:*}" != "${_epcdu_pkg_name_depend}" ]; then
+ continue;
+ elif ! rtl_get_var_unsafe \$_epcdu_defined "${_epcdu_rpkg_names_set}_${_epcdu_pkg_name_depend}"\
+ || [ "${_epcdu_defined:-0}" -eq 0 ]; then
+ rtl_lconcat "${_epcdu_rpkg_unknown}" "${_epcdu_pkg_name_depend}";
+ _epcdu_rc=1;
+ fi;
+ done;
+ fi;
+
+ return "${_epcdu_rc}";
+};
+
+#
+# ex_pkg_unfold_depends() - unfold list of package names into dependency-expanded set of complete, disabled, finished, and outstanding package names
+# @_rdisabled: in reference to out variable of disabled packages
+# @_rfinished: in reference to out variable of finished packages
+# @_rnames: out reference to variable of package names
+# @_checkfl: enable (1) or inhibit (0) dependency expansion
+# @_forcefl: enable (1) or inhibit (0) forcibly rebuilding finished packages
+# @_group_name: build group name
+# @_pkg_names: list of package names
+# @_restart: optional whitespace-separated list of package names to rebuild
+# @_test_finished: only exclude disabled packages (0,) split finished packages
+# @_workdir: pathname to build-specific temporary directory
+#
+# Returns: zero (0) on success, non-zero (>0) on failure.
+#
+ex_pkg_unfold_depends() {
+ local _epud_rdisabled="${1#\$}" _epud_rfinished="${2#\$}" _epud_rnames="${3#\$}" \
+ _epud_checkfl="${4}" _epud_forcefl="${5}" _epud_group_name="${6}" \
+ _epud_pkg_names="${7}" _epud_restart="${8}" _epud_test_finished="${9}" \
+ _epud_workdir="${10}" \
+ _epud_depends="" _epud_pkg_disabled="" _epud_pkg_force="" _epud_pkg_name="" \
+ _epud_pkg_name_depend="" _epud_pkg_names_new="" _epud_pkg_names_set="" \
+ _epud_pkg_unknown="" _epud_restartfl=0 _epud_unknown_depends=0;
+
+ if [ "${_epud_restart:+1}" = 1 ]\
+ && ! rtl_lmatch \$_epud_restart "ALL LAST"; then
+ rtl_lsearch \$_epud_pkg_names "${_epud_restart}";
+ fi;
+ if [ "${_epud_restart:+1}" = 1 ]\
+ && [ "${_epud_checkfl:-0}" -eq 1 ]; then
+ rtl_lunfold_dependsV 'PKG_${_rld_name}_DEPENDS' \$_epud_pkg_names ${_epud_pkg_names};
+ _epud_pkg_names="$(rtl_uniq ${_epud_pkg_names})";
+ fi;
+
+ rtl_llift_set \$_epud_pkg_names \$_epud_pkg_names_set;
+ for _epud_pkg_name in ${_epud_pkg_names}; do
+ if rtl_get_var_unsafe \$_epud_depends -u "PKG_"${_epud_pkg_name}"_DEPENDS"\
+ && [ "${_epud_depends:+1}" = 1 ]; then
+ _epud_pkg_unknown="";
+ if ! ex_pkg_check_depends_unknown "${_epud_pkg_name}" \$_epud_pkg_names_set \$_epud_pkg_unknown; then
+ for _epud_pkg_name_depend in ${_epud_pkg_unknown}; do
+ rtl_log_msgV "warning" "${MSG_build_unknown_dep}" "${_epud_pkg_name_depend}" "${_epud_pkg_name}";
+ done;
+ _epud_unknown_depends=1;
+ fi;
+ fi;
+
+ if [ "${_epud_restart}" = "ALL" ]\
+ || rtl_lmatch \$_epud_restart "${_epud_pkg_name}"; then
+ _epud_restartfl=1;
+ else
+ _epud_restartfl=0;
+ fi;
+
+ if rtl_get_var_unsafe \$_epud_pkg_disabled -u "PKG_${_epud_pkg_name}_DISABLED"\
+ && [ "${_epud_pkg_disabled}" = 1 ];
+ then
+ rtl_lconcat "${_epud_rdisabled}" "${_epud_pkg_name}";
+
+ elif [ "${_epud_test_finished:-1}" -eq 1 ]\
+ && ex_pkg_state_test2 "${_epud_workdir}" "${_epud_pkg_name}" finish\
+ && [ "${_epud_restartfl:-0}" -eq 0 ]\
+ && [ "${_epud_forcefl:-0}" -ne 1 ]\
+ && rtl_get_var_unsafe \$_epud_pkg_force -u "${_epud_group_name}_FORCE"\
+ && [ "${_epud_pkg_force}" != 1 ];
+ then
+ rtl_lconcat "${_epud_rfinished}" "${_epud_pkg_name}";
+
+ else
+ rtl_lconcat \$_epud_pkg_names_new "${_epud_pkg_name}";
+ fi;
+ done;
+ rtl_llift_unset \$_epud_pkg_names_set;
+
+ if [ "${_epud_unknown_depends}" -eq 1 ]; then
+ rtl_log_msgV "warning" "${MSG_build_unknown_deps}";
+ fi;
+
+ eval ${_epud_rdisabled}='$(rtl_uniq2 "${_epud_rdisabled}")';
+ eval ${_epud_rfinished}='$(rtl_uniq2 "${_epud_rfinished}")';
+ eval ${_epud_rnames}='$(rtl_uniq "${_epud_pkg_names_new}")';
+
+ return 0;
+};
+
+#
+# ex_pkg_unfold_rdepends() - unfold list of package names into reverse dependency-expanded set of complete, disabled, finished, and outstanding package names
+# @_rdisabled: in reference to out variable of disabled packages
+# @_rfinished: in reference to out variable of finished packages
+# @_rnames: out reference to variable of package names
+# @_group_name: build group name
+# @_pkg_names: list of package names
+# @_restart: optional whitespace-separated list of package names to rebuild
+# @_test_finished: only exclude disabled packages (0,) split finished packages
+# @_workdir: pathname to build-specific temporary directory
+# @_recursefl: resolve recursively ("recurse") or non-recursively ("norecurse")
+#
+# Returns: zero (0) on success, non-zero (>0) on failure.
+#
+ex_pkg_unfold_rdepends() {
+ local _epur_rdisabled="${1#\$}" _epur_rfinished="${2#\$}" _epur_rnames="${3#\$}" \
+ _epur_group_name="${4}" _epur_pkg_names="${5}" _epur_restart="${6}" \
+ _epur_test_finished="${7}" _epur_workdir="${8}" _epur_recursefl="${9}" \
+ _epur_depends="" _epur_disabled=0 _epur_force=0 _epur_pkg_depends="" \
+ _epur_pkg_name="" _epur_pkg_names_new="" _epur_pkg_name_depend="" \
+ _epur_pkg_name_rdepend="" _epur_pkg_rdepends="";
+
+ for _epur_pkg_name_depend in ${_epur_restart}; do
+ for _epur_pkg_name in ${_epur_pkg_names}; do
+ if [ "${_epur_pkg_name}" = "${_epur_pkg_name_depend}" ]; then
+ continue;
+
+ elif rtl_get_var_unsafe \$_epur_depends -u "PKG_"${_epur_pkg_name}"_DEPENDS"\
+ && rtl_lunfold_dependsV 'PKG_${_rld_name}_DEPENDS' \$_epur_pkg_depends ${_epur_depends}\
+ && [ "${_epur_pkg_depends:+1}" = 1 ]\
+ && rtl_lmatch \$_epur_pkg_depends "${_epur_pkg_name_depend}";
+ then
+ case "${_epur_recursefl}" in
+ recurse) _epur_pkg_rdepends="${_epur_pkg_name} ${_epur_pkg_depends}"; ;;
+ norecurse) _epur_pkg_rdepends="${_epur_pkg_name}"; ;;
+ esac;
+
+ for _epur_pkg_name_rdepend in ${_epur_pkg_rdepends}; do
+ if rtl_get_var_unsafe \$_epur_disabled -u "PKG_${_epur_pkg_name_rdepend}_DISABLED"\
+ && [ "${_epur_disabled}" = 1 ];
+ then
+ rtl_lconcat "${_epur_rdisabled}" "${_epur_pkg_name_rdepend}";
+
+ elif [ "${_epur_test_finished}" -eq 1 ]\
+ && ex_pkg_state_test2 "${_epur_workdir}" "${_epur_pkg_name_rdepend}" finish\
+ && rtl_get_var_unsafe \$_epur_force -u "${_epur_group_name}_FORCE"\
+ && [ "${_epur_force}" != 1 ];
+ then
+ rtl_lconcat "${_epur_rfinished}" "${_epur_pkg_name_rdepend}";
+
+ elif [ "${_epur_test_finished:-1}" -eq 0 ]\
+ || ! ex_pkg_state_test2 "${_epur_workdir}" "${_epur_pkg_name_rdepend}" finish\
+ || ( rtl_get_var_unsafe \$_epur_force -u "${_epur_group_name}_FORCE"\
+ && [ "${_epur_force}" = 1 ] );
+ then
+ rtl_lconcat \$_epur_pkg_names_new "${_epur_pkg_name_rdepend}";
+ fi;
+ done;
+ fi;
+ done;
+ done;
+
+ eval ${_epur_rdisabled}='$(rtl_uniq2 "${_epur_rdisabled}")';
+ eval ${_epur_rfinished}='$(rtl_uniq2 "${_epur_rfinished}")';
+ eval ${_epur_rnames}='$(rtl_uniq "${_epur_pkg_names_new}")';
+
+ return 0;
+};
+
+# vim:filetype=sh textwidth=0
diff --git a/subr.ex/ex_pkg_dispatch.subr b/subr.ex/ex_pkg_dispatch.subr
index 5a5ef006..19818e97 100644
--- a/subr.ex/ex_pkg_dispatch.subr
+++ b/subr.ex/ex_pkg_dispatch.subr
@@ -64,7 +64,7 @@ exp_pkg_dispatch_expand_packages() {
"${_epdep_rdisabled}" "${_epdep_rfinished}" \
"${_epdep_rnames}" "${_epdep_group_name}" \
"${_epdep_pkg_names}" "${_epdep_restart}" 1 \
- "${_epdep_workdir}";
+ "${_epdep_workdir}" "recurse";
fi;
fi;
@@ -77,16 +77,16 @@ exp_pkg_dispatch_expand_packages() {
#
# exp_pkg_dispatch_group() - dispatch a single build group
-# @_rdispatch_count: in reference toout variable of dispatcher count
-# @_rdispatch_count_cur: in reference toout variable of current dispatcher count
+# @_rdispatch_count: in reference to out variable of dispatcher count
+# @_rdispatch_count_cur: in reference to out variable of current dispatcher count
# @_dispatch_count_max: maximum dispatcher count
# @_dispatch_group_cur: current group
# @_dispatch_group_max: maximum group
-# @_rdispatch_njobs: in reference toout variable of dispatcher count
-# @_rdispatch_wait: in reference toout variable of package names in a wait state
+# @_rdispatch_njobs: in reference to out variable of dispatcher count
+# @_rdispatch_wait: in reference to out variable of package names in a wait state
# @_rpkg_disabled: in reference to variable of list of disabled packages
-# @_rpkg_finished: in reference toout variable of list of finished packages
-# @_rpkg_names: in reference toout variable of list of package names
+# @_rpkg_finished: in reference to out variable of list of finished packages
+# @_rpkg_names: in reference to out variable of list of package names
# @_build_steps_default: list of default build steps
# @_build_vars_default: list of default build variables
# @_checkfl: enable (1) or inhibit (0) dependency expansion
@@ -213,16 +213,16 @@ exp_pkg_dispatch_group() {
#
# exp_pkg_dispatch_packages() - dispatch set of packages
-# @_rdispatch_count: in reference toout variable of dispatcher count
+# @_rdispatch_count: in reference to out variable of dispatcher count
# @_dispatch_count_cur: current dispatcher count
# @_dispatch_count_max: maximum dispatcher count
# @_dispatch_group_cur: current group
# @_dispatch_group_max: maximum group
-# @_rdispatch_njobs: in reference toout variable of dispatcher count
-# @_rdispatch_wait: in reference toout variable of package names in a wait state
+# @_rdispatch_njobs: in reference to out variable of dispatcher count
+# @_rdispatch_wait: in reference to out variable of package names in a wait state
# @_rpkg_disabled: in reference to variable of list of disabled packages
-# @_rpkg_finished: in reference toout variable of list of finished packages
-# @_rpkg_names: in reference toout variable of list of package names
+# @_rpkg_finished: in reference to out variable of list of finished packages
+# @_rpkg_names: in reference to out variable of list of package names
# @_build_steps_default: list of default build steps
# @_build_vars_default: list of default build variables
# @_checkfl: enable (1) or inhibit (0) dependency expansion
@@ -302,7 +302,7 @@ ex_pkg_dispatch() {
_epd_checkfl=1 _epd_forcefl=0 _epd_perc_group=0 \
_epd_pkg_disabled="" _epd_pkg_finished="" _epd_pkg_names="" _epd_pkg_name="" \
_epd_pkg_dispatch_count=0 _epd_pkg_dispatch_count_cur=0 _epd_pkg_dispatch_count_max=0 \
- _epd_pkg_dispatch_group_cur=0 _epd_pkg_dispatch_group_max=0 \
+ _epd_pkg_dispatch_group_cur=1 _epd_pkg_dispatch_group_max=0 \
_epd_pkg_dispatch_njobs=0 \
_epd_rc=0 _epd_reversefl=0;
diff --git a/subr.ex/ex_pkg_restart.subr b/subr.ex/ex_pkg_restart.subr
index 4548f1bb..a0cf220e 100644
--- a/subr.ex/ex_pkg_restart.subr
+++ b/subr.ex/ex_pkg_restart.subr
@@ -113,11 +113,11 @@ exp_pkg_expand_restart_at_spec_cmp() {
"${_eperasc_spec_at0%%,*}" \$_eperasc_spec_at0 \
"${_eperasc_rset}" \
&& exp_pkg_check_restart_at "${_eperasc_rstatus}" \$_eperasc_spec_at0; then
- if [ \( "${_eperasc_eqfl}" -eq 1 \) -a \( "${_eperasc_ltfl}" -eq 1 \) ]\
- || [ \( "${_eperasc_eqfl}" -eq 0 \) -a \( "${_eperasc_ltfl}" -eq 0 \) ]; then
+ if [ "${_eperasc_eqfl}" -eq 1 -a "${_eperasc_ltfl}" -eq 1 ]\
+ || [ "${_eperasc_eqfl}" -eq 0 -a "${_eperasc_ltfl}" -eq 0 ]; then
_eperasc_spec_at0="${_eperasc_spec_at0##*,}";
- elif [ \( "${_eperasc_eqfl}" -eq 1 \) -a \( "${_eperasc_ltfl}" -eq 0 \) ]\
- || [ \( "${_eperasc_eqfl}" -eq 0 \) -a \( "${_eperasc_ltfl}" -eq 1 \) ]; then
+ elif [ "${_eperasc_eqfl}" -eq 1 -a "${_eperasc_ltfl}" -eq 0 ]\
+ || [ "${_eperasc_eqfl}" -eq 0 -a "${_eperasc_ltfl}" -eq 1 ]; then
_eperasc_spec_at0="${_eperasc_spec_at0%%,*}";
fi;