#!/bin/sh -e # ================================================================================== # portsreinstall main script # Copyright (C) 2010-2014 Mamoru Sakaue, MwGhennndo, All Rights Reserved. # This software is distributed under the 2-Clause BSD License. # ================================================================================== # ================================================== # ================== ENVIRONMENT =================== # ================================================== # ============ Set up of environment ============= APPNAME=`basename "$0"` # MYVERSION=3.0.6 # COMPATIBLE_VERSIONS='^(3\.0\.[0-9]+)$' # Template for development versions MYVERSION=3.0.5+toward_3.0.6_20140601155959 COMPATIBLE_VERSIONS='^(3\.0\.[0-9]+\+toward_3\.0\.[0-9]+_[0-9]+|3\.0\.[0-9]+)$' MYPREFIX=`dirname "\`dirname \"$0\"\`" | sed 's|/bin$||'` MYPREFIX=${MYPREFIX:-/usr/local} LIBDIR=${MYPREFIX}/lib/${APPNAME} . ${LIBDIR}/libtemp.sh . ${LIBDIR}/libstr.sh . ${LIBDIR}/liboptions.sh . ${LIBDIR}/libusage.sh . ${LIBDIR}/libmessage.sh . ${LIBDIR}/libpkgsys.sh . ${LIBDIR}/libmisc.sh . ${LIBDIR}/libfileedit.sh . ${LIBDIR}/libconf.sh . ${LIBDIR}/libdatabase_build.sh . ${LIBDIR}/libdatabase_query.sh . ${LIBDIR}/libdatabase_record.sh . ${LIBDIR}/libcommand.sh . ${LIBDIR}/libprogram.sh . ${LIBDIR}/libreinstall.sh . ${LIBDIR}/libdeinstall.sh misc_init_vardefs temp_trap_init DBDIR=/var/tmp/${APPNAME}.db CONFFILE=${MYPREFIX}/etc/${APPNAME}.conf PKGTOOLSCONF=${MYPREFIX}/etc/pkgtools.conf # ================================================== # ========= PARSING OPTIONS AND ARGUMENTS ========== # ================================================== # ============= Save arguments for upgraded restart ============= options_dump_args "$@" > ${TMPDIR}/restart_command.sh # ============= Option check ============= options_set_default options_getopts "$@" || : if [ $OPTIONS_ERRNO -eq 2 ] then message_echo "INTERNAL ERROR: In parsing options" >&2 exit 1 fi shift "${OPTIONS_SHIFT}" # ============= Argument check for no-command options ============= if [ $opt_help_mode -ne 0 -o $opt_show_version = yes ] then if [ $# -gt 0 ] then OPTIONS_ERRNO=1 fi fi # ============= Output usage if the case of a help mode or option/argument errors ============= if [ $OPTIONS_ERRNO -ne 0 ] then exit $OPTIONS_ERRNO elif [ $opt_help_mode -eq 1 ] then usage_short exit elif [ $opt_help_mode -eq 2 ] then usage_long | less -r exit fi # ============= Output version number ============= if [ $opt_show_version = yes ] then message_version exit fi # ============= Set up variables for environment of ports and packages ============= conf_setup_ports_envs conf_setup_packages_envs # ============= Execute command operations before getting the temporary database ready ============= command_exec_before_db_creation "$@" # ============= Creation of temporary database directory ============= database_build_create # ============= Argument check for conventional runs ============= command_parse_args "$@" shift "${COMMAND_SHIFT}" # ================================================== # ================== TOOLS SET UP ================== # ================================================== # ============= Termination messages during construction of the temporary database ============= # Set termination messages temp_terminate_process_common () { local msg_where [ $opt_batch_mode = yes ] && return msg_where=`temp_get_msg_current_stage` [ -n "$msg_where" ] && msg_where=" during $msg_where" echo if [ $errno -eq 130 ] then echo "INFO: Terminated at `message_timestamp`$msg_where." echo echo " You can restart this process from the terminated point by" else echo "INFO: Aborted at `message_timestamp`$msg_where." echo echo " You may restart this process from the aborted point by" fi echo "executing without options or arguments as:" if [ -n "$COMMAND_RESTART" ] then echo " ${APPNAME} $COMMAND_RESTART" else echo " ${APPNAME}" fi } temp_terminate_process () { local tmp_msg tmp_msg=${TMPDIR}/temp_terminate_process:msg [ $errno -eq 0 -o $opt_batch_mode = yes ] && return temp_terminate_process_common [ -n "$COMMAND_RESTART" ] && return cat > $tmp_msg << eof Instead, if you only want to construct the temporary database so as to stop before the actual reinstallation, execute as: ${APPNAME} prepare eof message_cat "$tmp_msg" } # ============= Opening title ============= message_credit [ $COMMAND_MODE = do -o $COMMAND_MODE = redo -o $COMMAND_MODE = forget ] && \ message_opening_notice message_echo # ============= Execute command operations which do not need package tools ============= command_exec_without_pkgtools "$@" misc_is_superuser_privilege && touch "${DBDIR}/in_use" # ============= Definition of environment dependent functions ============= pkgsys_def_pkgtools # ============= Option settings ============= # Execute command operations which are not affected by saved option settings command_exec_irrespective_of_saved_options "$@" # Load, renew and save option values optcomb_err=0 options_chk_invalid_optvals_renewal non_renewable || optcomb_err=$? if [ \( $opt_reload_conf = yes -o $opt_reset_targets = yes \) -a "x$COMMAND_MODE" != xredo ] then message_echo "ERROR: Options -L and -N are available only in the initial run of redo command." >&2 message_echo >&2 optcomb_err=1 fi if [ $opt_batch_ports_only = yes -a $opt_interactive_ports_only = yes ] then message_echo "ERROR: Options -A and -I conflict with each other." >&2 message_echo >&2 optcomb_err=1 fi if [ -e "${DBDIR}/saved_options.sh" ] then { options_renewed_optvals M renewable_anytime || optcomb_err=$? options_renewed_optvals N renewable_in_redo_on_target || optcomb_err=$? options_renewed_optvals L renewable_in_redo_on_conf || optcomb_err=$? } > ${TMPDIR}/renewed_optvals.sh [ $optcomb_err -eq 0 ] || exit $optcomb_err . "${DBDIR}/saved_options.sh" . "${TMPDIR}/renewed_optvals.sh" fi misc_is_superuser_privilege && misc_get_all_vardefs | options_filter saved > ${DBDIR}/saved_options.sh # Show option values if [ -e "${DBDIR}/saved_options.sh" -a $opt_batch_mode = no \ -a \( $COMMAND_MODE = do -o $COMMAND_MODE = redo \) ] then message_echo "INFO: List of option values:" message_echo "-----------------------------------------" message_cat "${DBDIR}/saved_options.sh" message_echo "-----------------------------------------" message_echo fi # ============= Configurations ============= # Save the previous configuration if exists PROGRAM_DEPENDS='' _program_exec_and_record_completion__operation () { rm -rf "${DBDIR}/conf.prev" [ -d "${DBDIR}/conf" ] && \ cp -Rp "${DBDIR}/conf" "${DBDIR}/conf.prev" : } program_exec_and_record_completion SAVE_PREV_CONF # Get complete configuration variable definitions by importing pkgtools.conf(5) if available PROGRAM_DEPENDS='SAVE_PREV_CONF' _program_exec_and_record_completion__operation () { local need_msg need_msg=no rm -rf "${DBDIR}/conf" mkdir -p "${DBDIR}/conf" [ "x`options_get_effective_opt_load_pkgtoolsconf 2> /dev/null`" != xno -a $opt_batch_mode = no ] \ && need_msg=yes [ $need_msg = yes ] && \ message_section_title "Parsing pkgtools.conf (by using installed portupgrade)" conf_get_complete_var_defs > ${DBDIR}/conf/complete_setup.sh [ $need_msg = yes ] && { message_echo "===> ok"; message_echo; } : } program_exec_and_record_completion GET_COMPLETE_CONF_VAR_DEF # Parse the configuration PROGRAM_DEPENDS='GET_COMPLETE_CONF_VAR_DEF' _program_exec_and_record_completion__operation () { message_section_title "Parsing the configuration" conf_manipulate_available_var_defs . "${DBDIR}/conf/manipulated_defs.sh" # ALT_MOVED_* conf_build_effective_MOVED # Environmental variables conf_setup_effective_env > ${DBDIR}/conf/setenv.sh . "${DBDIR}/conf/setenv.sh" # HOLD_* conf_parse_vars_for_each_port_glob HOLD str_escape_regexp_filter < ${DBDIR}/conf/HOLD:PORTS.parsed \ | sed 's/^/^/;s/$/$/' > ${DBDIR}/conf/HOLD_PORTS.grep_pattern # TABOO_* conf_parse_vars_for_each_port_glob TABOO fileedit_combine_lists "${DBDIR}/conf/TABOO:PORTS.parsed" "${DBDIR}/taboo.list" \ > ${DBDIR}/taboo.all.list # NOPKG_* conf_parse_vars_for_each_port_glob NOPKG # REPLACE_* conf_build_replacement_patterns_from_REPLACE # MARG_* conf_parse_vars_for_each_port_glob_with_bound_val MARG TARGET DEF # MENV_* conf_parse_vars_for_each_port_glob_with_bound_val MENV TARGET DEF # BEFOREBUILD_* conf_parse_vars_for_each_port_glob_with_bound_val BEFOREBUILD TARGET COMMAND # BEFOREDEINSTALL_* conf_parse_vars_for_each_port_glob_with_bound_val BEFOREDEINSTALL TARGET COMMAND # AFTERINSTALL_* conf_parse_vars_for_each_port_glob_with_bound_val AFTERINSTALL TARGET COMMAND message_echo } program_exec_and_record_completion PARSE_CONF . "${DBDIR}/conf/setenv.sh" # ============= Upgrade of tools ============= # Execute command operations which should be done without upgrade of tools command_exec_before_tools_upgrade "$@" # Check whether the temporary database is newer than the ports tree and refresh if so database_build_refresh_if_obsolete # Get the port origin for this utility if installed by port MYPORTORIGIN=`pkgsys_get_my_origin 2> /dev/null` || : # Collect all installed packages PROGRAM_DEPENDS='' _program_exec_and_record_completion__operation () { message_section_title "Collecting all installed packages" pkg_info_qoa > ${DBDIR}/installed_ports pkg_info_gen_pkg_origin_table str_escape_regexp_filter < "${DBDIR}/installed_ports" \ | sed 's/^/^/; s/$/$/' > ${DBDIR}/installed_ports.grep_pattern message_echo } program_exec_and_record_completion COLLECT_ALL_INSTALLED_PACKAGES # Preliminary inspection of tools which have to be up-to-date # (No need depend on PARSE_CONF because INSPECT_ALL_DEPENDENCIES will take the task.) PROGRAM_DEPENDS= _program_exec_restartable_loop_operation__routine () { local origin origin=$1 database_build_inspect_dependencies "$origin" } _program_exec_and_record_completion__operation () { local DEPTH_INDEX message_section_title "Preliminary inspection of tools which have to be up-to-date" { [ "$PKGSYS_USE_PKGNG" = yes ] && echo 'ports-mgmt/pkg' pkgsys_is_dialog4ports_used && echo 'ports-mgmt/dialog4ports' [ -n "$MYPORTORIGIN" ] && echo "$MYPORTORIGIN" } 2> /dev/null > ${DBDIR}/stage.loop_list/tools_to_inspect DEPTH_INDEX='--' program_exec_restartable_loop_operation tools_to_inspect database_build_post_inspect_dependencies message_echo } program_exec_and_record_completion PRELIMINARY_INSPECTION_OF_TOOLS # Upgrade of ports-mgmt/pkg if new # (No need depend on PARSE_CONF because REINSTALLATION will take the task.) if [ \( "$COMMAND_MODE" = do -o "$COMMAND_MODE" = redo \) \ -a $opt_dry_run = no -a $opt_suppress_pkgtools_upadte = no \ -a "$PKGSYS_USE_PKGNG" = yes ] then PROGRAM_DEPENDS='PRELIMINARY_INSPECTION_OF_TOOLS' _program_exec_and_record_completion__operation () { local _MSG_CURRENT_STAGE_general _MSG_CURRENT_STAGE_general="pkgng upgrade" temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}" message_section_title "Upgrade of ports-mgmt/pkg if new" touch "${DBDIR}/target_all" reinstall_exec ports-mgmt/pkg reinstall_restore_conflicts rm -f "${DBDIR}/target_all" temp_set_msg_current_stage message_echo } program_exec_and_record_completion UPGRADE_PKGNG fi # Upgrade of ports-mgmt/dialog4ports if new # (No need depend on PARSE_CONF because REINSTALLATION will take the task.) if [ \( "$COMMAND_MODE" = do -o "$COMMAND_MODE" = redo \) \ -a $opt_dry_run = no -a $opt_suppress_pkgtools_upadte = no ] \ && pkgsys_is_dialog4ports_used then PROGRAM_DEPENDS='PRELIMINARY_INSPECTION_OF_TOOLS' _program_exec_and_record_completion__operation () { local _MSG_CURRENT_STAGE_general _MSG_CURRENT_STAGE_general="pkgng dialog4ports" temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}" message_section_title "Upgrade of dialog4ports if new" touch "${DBDIR}/target_all" reinstall_exec ports-mgmt/dialog4ports reinstall_restore_conflicts rm -f "${DBDIR}/target_all" temp_set_msg_current_stage message_echo } program_exec_and_record_completion UPGRADE_DIALOG4PORTS fi # Upgrade of this utility if new # (No need depend on PARSE_CONF because REINSTALLATION will take the task.) if [ \( "$COMMAND_MODE" = do -o "$COMMAND_MODE" = redo \) \ -a $opt_dry_run = no -a $opt_suppress_self_upadte = no \ -a -n "$MYPORTORIGIN" ] then PROGRAM_DEPENDS='PRELIMINARY_INSPECTION_OF_TOOLS' _program_exec_and_record_completion__operation () { local _MSG_CURRENT_STAGE_general _MSG_CURRENT_STAGE_general="pkgng upgrade" temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}" message_section_title "Upgrade of this utility if new" touch "${DBDIR}/target_all" reinstall_exec "$MYPORTORIGIN" reinstall_restore_conflicts rm -f "${DBDIR}/target_all" temp_set_msg_current_stage message_echo } program_exec_and_record_completion UPGRADE_SELF fi if [ "x`${APPNAME} -aV 2> /dev/null`" != "x$MYVERSION" ] then message_echo "INFO: ${APPNAME} is upgraded and the temporary database needs refresh." database_build_clean_for_self_upgrade || : message_echo "INFO: Restarting with the new version." message_echo temp_trap_for_invoking_new_version . "${TMPDIR}"/restart_command.sh exit fi # ================================================== # ================== PREPARATION =================== # ================================================== # ============= Correspondence to configuration changes ============= # Patch to the temporary database by reflecting changes in configuration PROGRAM_DEPENDS='PARSE_CONF' _program_exec_and_record_completion__operation () { local tmpfile_diff tmpfile_old tmpfile_new key [ -d "${DBDIR}/conf.prev" ] || return 0 message_section_title "Patch to the temporary database by reflecting changes in configuration" tmpfile_old=${TMPDIR}/PATCH_TO_TMPDB_REFLECT_CONF_CHANGES::old tmpfile_new=${TMPDIR}/PATCH_TO_TMPDB_REFLECT_CONF_CHANGES::new tmpfile_updated_ports=${TMPDIR}/PATCH_TO_TMPDB_REFLECT_CONF_CHANGES::updated_ports if fileedit_manipulate_old_new_lines \ "${DBDIR}/conf.prev/setenv.sh" "${DBDIR}/conf/setenv.sh" "$tmpfile_old" "$tmpfile_new" then if grep -q -e ^LOCALBASE= -e ^LINUXBASE= -e ^PORTSDIR= "$tmpfile_old" "$tmpfile_new" then message_echo "ERROR: Migration of the temporary database is unavailable because LOCALBASE, LINUXBASE or PORTSDIR was changed." >&2 message_echo " ${APPNAME} clean" >&2 message_echo "must be executed in advance." >&2 exit 1 fi fi cut -s -d '|' -f 1,2 "${DBDIR}/conf.prev/MOVED_ALT.parsed" | tr '|' '\t' > ${TMPDIR}/MOVED_ALT.old cut -s -d '|' -f 1,2 "${DBDIR}/conf/MOVED_ALT.parsed" | tr '|' '\t' > ${TMPDIR}/MOVED_ALT.new if fileedit_manipulate_old_new_lines \ "${TMPDIR}/MOVED_ALT.old" "${TMPDIR}/MOVED_ALT.new" "$tmpfile_old" "$tmpfile_new" then cat "$tmpfile_old" "$tmpfile_new" | while read from to do echo "$from" [ -n "$to" ] && echo "$to" done fi > $tmpfile_updated_ports if fileedit_manipulate_old_new_lines \ "${DBDIR}/conf.prev/REPLACE.csv" "${DBDIR}/conf/REPLACE.csv" "$tmpfile_old" "$tmpfile_new" then cat "$tmpfile_old" "$tmpfile_new" | while read from to do echo "$from" [ -n "$to" ] && echo "$to" done fi >> $tmpfile_updated_ports [ `wc -l < $tmpfile_updated_ports` -gt 0 ] && rm -f "${DBDIR}/REPLACE.complete_sed_pattern" [ -d "${DBDIR}/conf/each_port" ] && find "${DBDIR}/conf/each_port" -depth 2 \ | while read dbpath do origin=`str_dirpath_to_origin "$dbpath"` dbpath_prev=${DBDIR}/conf.prev/each_port/$origin diff -r "$dbpath_prev" "$dbpath" > /dev/null 2>&1 && continue echo "$origin" done >> $tmpfile_updated_ports [ -d "${DBDIR}/conf.prev/each_port" ] && find "${DBDIR}/conf.prev/each_port" -depth 2 \ | while read dbpath_prev do origin=`str_dirpath_to_origin "$dbpath_prev"` dbpath=${DBDIR}/conf/each_port/$origin [ -d "$dbpath" ] && continue echo "$origin" done >> $tmpfile_updated_ports if [ `wc -l < $tmpfile_updated_ports` -gt 0 ] then sort -u "$tmpfile_updated_ports" | while read origin do database_build_patch_reconf "$origin" done program_deregister_stage_complete INSPECT_ALL_DEPENDENCIES fi message_echo } program_exec_and_record_completion PATCH_TO_TMPDB_REFLECT_CONF_CHANGES # ============= Database construction ============= # Execute command operations which must be done before building the temporary database command_exec_before_building_tempdb "$@" # Meta process for redo PROGRAM_DEPENDS='' _program_exec_and_record_completion__operation () { rm -f "${DBDIR}/new_success_in_current_run" [ "x$COMMAND_MODE" = xredo ] || return 0 message_echo "[REDO mode]" message_echo } program_exec_and_record_completion REDO_INIT # Determine specified targets PROGRAM_DEPENDS='' _program_exec_and_record_completion__operation () { local tag level dbsuffix message_section_title "Determining specified targets" cat "${DBDIR}/stage.loop_list/target_itself.specified" \ "${DBDIR}/stage.loop_list/target_dependents.specified" \ "${DBDIR}/stage.loop_list/target_requirements.specified" \ "${DBDIR}/need.list" \ "${DBDIR}/targets_specified_so_far" 2> /dev/null \ | sort -u > ${DBDIR}/targets_specified_so_far.tmp mv "${DBDIR}/targets_specified_so_far.tmp" "${DBDIR}/targets_specified_so_far" rm -f "${DBDIR}/stage.loop_list/target_itself.specified" \ "${DBDIR}/stage.loop_list/target_dependents.specified" \ "${DBDIR}/stage.loop_list/target_requirements.specified" if [ -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ] then options_select_new_ports_if_duplicated O \ "${DBDIR}/stage.loop_list/target_itself.specified" "$opt_target_itself" options_select_new_ports_if_duplicated t \ "${DBDIR}/stage.loop_list/target_dependents.specified" "$opt_target_dependents" options_select_new_ports_if_duplicated T \ "${DBDIR}/stage.loop_list/target_requirements.specified" "$opt_target_requirements" if [ `cat "${DBDIR}/stage.loop_list/target_itself.specified" \ "${DBDIR}/stage.loop_list/target_dependents.specified" \ "${DBDIR}/stage.loop_list/target_requirements.specified" | wc -l` -eq 0 ] then message_echo "ERROR: No matching port for target globs." >&2 message_echo >&2 exit 1 fi cat "${DBDIR}/stage.loop_list/target_itself.specified" \ "${DBDIR}/stage.loop_list/target_dependents.specified" \ "${DBDIR}/stage.loop_list/target_requirements.specified" \ | sort -u > ${TMPDIR}/DETERMINE_SPECIFIED_TARGETS.reset cat "${TMPDIR}/DETERMINE_SPECIFIED_TARGETS.reset" "${DBDIR}/need.list" 2> /dev/null \ | sort -u > ${DBDIR}/need.list.tmp mv "${DBDIR}/need.list.tmp" "${DBDIR}/need.list" sort -u "${DBDIR}/need.list" "${DBDIR}/targets_specified_so_far" \ > ${DBDIR}/targets_specified_so_far.tmp mv "${DBDIR}/targets_specified_so_far.tmp" "${DBDIR}/targets_specified_so_far" for tag in all run build none do for level in direct full do dbsuffix=$tag.$level { cat "${TMPDIR}/DETERMINE_SPECIFIED_TARGETS.reset" cat "${DBDIR}/stage.loop_list/target_dependents.specified" | while read origin do nodedir=${DBDIR}/requires/$origin cat "$nodedir/dependents.$dbsuffix" 2> /dev/null done cat "${DBDIR}/stage.loop_list/target_requirements.specified" | while read origin do nodedir=${DBDIR}/requires/$origin cat "$nodedir/requirements.$dbsuffix" 2> /dev/null done } | sort -u | while read origin do fileedit_rm_a_line "$origin" "${DBDIR}/success.$dbsuffix.list" fileedit_rm_a_line "$origin" "${DBDIR}/todo_after_requirements_succeed.$dbsuffix.list" rm -f "${DBDIR}/requires/$origin/succeeded_once" done done done fi message_echo } program_exec_and_record_completion DETERMINE_SPECIFIED_TARGETS # Show specified targets if [ -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" -a $opt_batch_mode = no ] then message_echo "INFO: (Re/de-)installation will be carried out only for the targets:" echo if [ `wc -l < ${DBDIR}/stage.loop_list/target_itself.specified` -gt 0 ] then message_echo "[Targets only]" echo "----------------------------------------" cat "${DBDIR}/stage.loop_list/target_itself.specified" echo "----------------------------------------" echo fi if [ `wc -l < ${DBDIR}/stage.loop_list/target_dependents.specified` -gt 0 ] then message_echo "[Targets with their `options_get_dependency_msgterm` dependents]" echo "----------------------------------------" cat "${DBDIR}/stage.loop_list/target_dependents.specified" echo "----------------------------------------" echo fi if [ `wc -l < ${DBDIR}/stage.loop_list/target_requirements.specified` -gt 0 ] then message_echo "[Targets with their `options_get_dependency_msgterm` requirements]" echo "----------------------------------------" cat "${DBDIR}/stage.loop_list/target_requirements.specified" echo "----------------------------------------" echo fi fi # Determine all target ports PROGRAM_DEPENDS='DETERMINE_SPECIFIED_TARGETS COLLECT_ALL_INSTALLED_PACKAGES' _program_exec_and_record_completion__operation () { message_section_title "Determining all target ports" { if [ $opt_only_target_scope = no ] then cat "${DBDIR}/installed_ports" 2> /dev/null || : fi cat "${DBDIR}/stage.loop_list/target_itself.specified" || : cat "${DBDIR}/stage.loop_list/target_dependents.specified" || : cat "${DBDIR}/stage.loop_list/target_requirements.specified" || : cat "${DBDIR}/targets_specified_so_far" || : } 2> /dev/null | sort -u > "${DBDIR}/stage.loop_list/ports_to_inspect" message_echo } program_exec_and_record_completion DETERMINE_ALL_TARGET_PORTS # Inspection of all dependencies PROGRAM_DEPENDS='PARSE_CONF DETERMINE_ALL_TARGET_PORTS' _program_exec_restartable_loop_operation__routine () { local origin origin=$1 database_build_inspect_dependencies "$origin" } _program_exec_and_record_completion__operation () { local DEPTH_INDEX message_section_title "Inspecting dependencies of the all installed packages" [ $opt_only_target_scope = no -a -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ] && \ message_echo "INFO: Ports which seem irrelevant to the targets are also inspected in order to get complete information." DEPTH_INDEX='--' program_exec_restartable_loop_operation ports_to_inspect database_build_post_inspect_dependencies message_echo } program_exec_and_record_completion INSPECT_ALL_DEPENDENCIES # Convert dependency-lists to actual ones PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES' _program_exec_restartable_loop_operation__routine () { local origin table dbtag level tag target origin=$1 for table in dependents requirements do for dbtag in requires obsolete do for level in direct full do for tag in all run build do target=${DBDIR}/$dbtag/$origin/${table}.${tag}.${level} if [ -e "$target.src" ] then sed -E -f "${DBDIR}/REPLACE.complete_sed_pattern" "$target.src" \ | grep -v '^$' | sort -u > $target.tmp [ -e "$target" ] && ! diff "$target.tmp" "$target" > /dev/null \ && echo "$origin" >> ${DBDIR}/update_dependencies mv "$target.tmp" "$target" else [ -e "$target" ] && echo "$origin" >> ${DBDIR}/update_dependencies rm -f "$target" fi done done done done } _program_exec_and_record_completion__operation () { message_section_title "Conversion of dependency-lists to actual ones" program_exec_restartable_loop_operation convert_dependency_lists sort -u "${DBDIR}/update_dependencies" > ${DBDIR}/update_dependencies.tmp mv "${DBDIR}/update_dependencies.tmp" "${DBDIR}/update_dependencies" str_escape_regexp_filter < ${DBDIR}/update_dependencies \ | sed 's/^/^/; s/$/$/' > ${DBDIR}/update_dependencies.grep_pattern for tag in all run build do ( cd "${DBDIR}/requires" && \ find . -depth 3 -type f -name requirements.${tag}.full | sed 's|^./||;s|/[^/]*$||' ) \ | grep -v -E -f "${DBDIR}/update_dependencies.grep_pattern" \ | str_escape_regexp_filter | sed 's/^/^/; s/$/$/' \ > ${TMPDIR}/convert_requirements_list:full_complete.grep_pattern || : ( cd "${DBDIR}/requires" && \ find . -depth 3 -type f -name requirements.${tag}.direct | sed 's|^./||;s|/[^/]*$||' ) \ | grep -v -E -f "${TMPDIR}/convert_requirements_list:full_complete.grep_pattern" \ > ${DBDIR}/stage.loop_list/complete_${tag}time_reqlists || : done for inspected_level_tmp in direct node do cat "${DBDIR}/ports.inspected.${inspected_level_tmp}.list" || : done 2> /dev/null | sort -u > ${DBDIR}/stage.loop_list/trim_dependency_lists_rm_uninspected_ports find "${DBDIR}/requires" -depth 2 -type d > ${DBDIR}/stage.loop_list/inspect_dependent [ -e "${DBDIR}/dependents_files" ] && \ mv "${DBDIR}/dependents_files" "${DBDIR}/dependents_files.prev" rm -f "${DBDIR}/stage.loop_list/make_dependents_lists_unique.tmp" "${DBDIR}/dependents_files.tmp" message_echo } program_exec_and_record_completion CONVERT_REQUIREMENTS_LIST # Completion of recursive requirement lists for _REQUIREMENT_LISTS_tag in all run build do PROGRAM_DEPENDS='CONVERT_REQUIREMENTS_LIST' _program_exec_restartable_loop_operation__routine () { local tag dbpath origin tag=${_REQUIREMENT_LISTS_tag} dbpath=$1 origin=`str_dirpath_to_origin "$dbpath"` database_build_get_complete_recursive_dependency requirements.${tag} "$origin" > /dev/null } _program_exec_and_record_completion__operation () { local tag tag=${_REQUIREMENT_LISTS_tag} message_section_title "Completion of ${tag}-time requirement lists" program_exec_restartable_loop_operation complete_${tag}time_reqlists message_echo } program_exec_and_record_completion REQUIREMENT_LISTS:${_REQUIREMENT_LISTS_tag} done # Trim dependency lists by removing uninspected ports if [ $opt_only_target_scope = yes ] then PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES CONVERT_REQUIREMENTS_LIST' _program_exec_restartable_loop_operation__routine () { local dbpath tag level srcdb dbpath=$1 for tag in all run build do for level in direct full do srcdb=requirements.${tag}.${level} [ -e "$dbpath/$srcdb" ] || continue grep -E -f "${DBDIR}/inspected_ports.grep_pattern" "$dbpath/$srcdb" \ > $dbpath/$srcdb.tmp || : mv "$dbpath/$srcdb.tmp" "$dbpath/$srcdb" done done } _program_exec_and_record_completion__operation () { message_section_title "Trimming dependency lists by removing uninspected ports" program_exec_restartable_loop_operation trim_dependency_lists_rm_uninspected_ports message_echo } program_exec_and_record_completion TRIM_DEPENDENCY_LISTS_RM_UNINSPECTED_PORTS fi # Inspection of dependents PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES CONVERT_REQUIREMENTS_LIST TRIM_DEPENDENCY_LISTS_RM_UNINSPECTED_PORTS' _program_exec_restartable_loop_operation__routine () { local dbpath origin tag level srcdb dstdb dbpath=$1 origin=`str_dirpath_to_origin "$dbpath"` for tag in all run build do for level in direct full do srcdb=requirements.${tag}.${level} dstdb=dependents.${tag}.${level} [ -e "$dbpath/$srcdb" ] || continue while read origin_requirement do dstpath=${DBDIR}/requires/$origin_requirement echo "$dstpath/$dstdb" >> ${DBDIR}/dependents_files.tmp [ "$dstpath/$dstdb" -nt "$dbpath/$srcdb" ] && continue [ -d "$dstpath" ] || mkdir -p "$dstpath" echo "$origin" >> $dstpath/$dstdb.raw echo "$dstpath/$dstdb" >> ${DBDIR}/stage.loop_list/make_dependents_lists_unique.tmp done < $dbpath/$srcdb done done } _program_exec_and_record_completion__operation () { local dbrequires_valesc message_section_title "Inspection of dependents" dbrequires_valesc=`str_escape_replaceval "${DBDIR}/requires/"` program_exec_restartable_loop_operation inspect_dependent sort -u "${DBDIR}/stage.loop_list/make_dependents_lists_unique.tmp" 2> /dev/null \ > ${DBDIR}/stage.loop_list/make_dependents_lists_unique || : sort -u "${DBDIR}/dependents_files.tmp" 2> /dev/null > ${DBDIR}/dependents_files || : [ -e "${DBDIR}/make_dependents_lists_unique.prev" ] && \ fileedit_manipulate_old_lines "${DBDIR}/dependents_files.prev" "${DBDIR}/dependents_files" \ | xargs rm -f message_echo } program_exec_and_record_completion INSPECT_DEPENDENTS # Remove duplicated lines in dependents lists PROGRAM_DEPENDS='CONVERT_REQUIREMENTS_LIST INSPECT_DEPENDENTS' _program_exec_restartable_loop_operation__routine () { local dbpath tag level dstdb dstdb=$1 cat "$dstdb" "$dstdb.raw" 2> /dev/null | sort -u > $dstdb.tmp mv "$dstdb.tmp" "$dstdb" rm -f "$dstdb.raw" } _program_exec_and_record_completion__operation () { local dbrequires_valesc message_section_title "Removing duplicated items in dependents lists" program_exec_restartable_loop_operation make_dependents_lists_unique message_echo } program_exec_and_record_completion MAKE_DEPENDENTS_LISTS_UNIQUE # Preparation of target attribute information for _TARGET_ATTR_INFO_table in requirements dependents itself do [ `cat "${DBDIR}/stage.loop_list/target_${_TARGET_ATTR_INFO_table}.replaced.specified" 2> /dev/null \ | wc -l` -gt 0 ] || continue PROGRAM_DEPENDS='DETERMINE_SPECIFIED_TARGETS CONVERT_REQUIREMENTS_LIST' _program_exec_restartable_loop_operation__routine () { local origin dbtargets_valesc table origin=$1 dbtargets_valesc=`str_escape_replaceval "${DBDIR}/targets/"` table=${_TARGET_ATTR_INFO_table} for database in requires initial do dbpath=${DBDIR}/$database/$origin dstpath=${DBDIR}/targets/$origin [ -d "$dstpath" ] || mkdir -p "$dstpath" touch "$dstpath/target_itself" echo "$origin" >> ${DBDIR}/all_targets.lst [ $table = itself ] && continue for tag in all run build do for level in direct full do srcdb=${table}.${tag}.${level} dstdb=target_${database}_${table}.${tag}.${level} [ -e "$dbpath/$srcdb" ] || continue cat "$dbpath/$srcdb" >> ${DBDIR}/all_targets.lst sed -E "s/^/$dbtargets_valesc/; s|$|/$dstdb|" "$dbpath/$srcdb" \ | fileedit_add_a_line_to_files_if_new "$origin" done done done } _program_exec_and_record_completion__operation () { local table table=${_TARGET_ATTR_INFO_table} message_section_title "Preparation of target attribute information for dependency [$table]" program_exec_restartable_loop_operation target_$table.replaced.specified message_echo } program_exec_and_record_completion TARGET_ATTR_INFO:${_TARGET_ATTR_INFO_table} done # Post-process after the preparation of target attribute information PROGRAM_DEPENDS='MAKE_DEPENDENTS_LISTS_UNIQUE TARGET_ATTR_INFO:requirements TARGET_ATTR_INFO:dependents' _program_exec_and_record_completion__operation () { message_section_title "Post-process after the preparation of target attribute information" sort -u "${DBDIR}/all_targets.lst" 2> /dev/null \ | grep -E -f "${DBDIR}/inspected_ports.grep_pattern" \ | sed -E -f "${DBDIR}/REPLACE.complete_sed_pattern" \ > ${DBDIR}/all_targets.lst.tmp || : mv "${DBDIR}/all_targets.lst.tmp" "${DBDIR}/all_targets.lst" find "${DBDIR}/targets" -depth 2 -type d > ${DBDIR}/stage.loop_list/build_complement_to_new_dependents_for_targets 2> /dev/null || : { cat "${DBDIR}/all_targets.lst" "${DBDIR}/need.with_replaced.list" 2> /dev/null || : find "${DBDIR}/requires" -depth 3 -type f -name installed_version \ | sed -E 's|.*/([^/]+/[^/]+)/[^/]*$|\1|' } | sort -u > ${DBDIR}/stage.loop_list/inspect_necessity cp /dev/null "${DBDIR}/stage.loop_list/parse_target_attr_info" find -E "${DBDIR}/requires" -depth 3 -type f -regex '.*/necessary_port\.(direct|full)$' -delete message_echo } program_exec_and_record_completion TARGET_ATTR_INFO_POSTPROCESS # Build of data on complement to new dependents for target attribute information PROGRAM_DEPENDS='TARGET_ATTR_INFO_POSTPROCESS TARGET_ATTR_INFO:requirements TARGET_ATTR_INFO:dependents CONVERT_REQUIREMENTS_LIST' _program_exec_restartable_loop_operation__routine () { local dbpath origin dbpath=$1 origin=`str_dirpath_to_origin "$dbpath"` database_build_complement_to_new_dependents_for_targets "$origin" } _program_exec_and_record_completion__operation () { message_section_title "Build of data on complement to new dependents for target attribute information" program_exec_restartable_loop_operation build_complement_to_new_dependents_for_targets sort -u "${DBDIR}/stage.loop_list/parse_target_attr_info" > ${DBDIR}/stage.loop_list/parse_target_attr_info.tmp mv "${DBDIR}/stage.loop_list/parse_target_attr_info.tmp" "${DBDIR}/stage.loop_list/parse_target_attr_info" message_echo } program_exec_and_record_completion COMPLEMENT_TO_NEW_DEPENDENTS_FOR_TARGET_ATTR_INFO # Parse target attribute information PROGRAM_DEPENDS='COMPLEMENT_TO_NEW_DEPENDENTS_FOR_TARGET_ATTR_INFO' _program_exec_restartable_loop_operation__routine () { local dbpath origin dbpath=$1 origin=`str_dirpath_to_origin "$dbpath"` database_build_target_attributes "$origin" } _program_exec_and_record_completion__operation () { message_section_title "Parsing target attribute information" program_exec_restartable_loop_operation parse_target_attr_info message_echo } program_exec_and_record_completion PARSE_TARGET_ATTR_INFO # Inspection of necessity PROGRAM_DEPENDS='TARGET_ATTR_INFO_POSTPROCESS REQUIREMENT_LISTS:run-time REQUIREMENT_LISTS:build-time INSPECT_ALL_DEPENDENCIES' _program_exec_restartable_loop_operation__routine () { local origin origin=$1 for level in direct full do database_build_inspect_necessity_for_only_new_upgrade "$origin" "$level" done } _program_exec_and_record_completion__operation () { message_section_title "Inspection of necessity" program_exec_restartable_loop_operation inspect_necessity for level in direct full do find "${DBDIR}/requires" -depth 3 -type f -name "necessary_port.${level}" \ > ${DBDIR}/stage.loop_list/necessary_ports.${level} done message_echo } program_exec_and_record_completion INSPECT_NECESSITY # Inspection of necessary upgrades for _NECESSARY_UPDATES_level in direct full do PROGRAM_DEPENDS='INSPECT_NECESSITY INSPECT_ALL_DEPENDENCIES MAKE_DEPENDENTS_LISTS_UNIQUE' _program_exec_restartable_loop_operation__routine () { local markerpath level dbpath origin tag markerpath=$1 level=${_NECESSARY_UPDATES_level} dbpath=`dirname "$markerpath"` origin=`str_dirpath_to_origin "$dbpath"` database_query_does_a_port_need_update "$origin" || return 0 for tag in all run build none do touch "$dbpath/necessary_upgrade.$tag.${level}" [ -e "$dbpath/dependents.$tag.${level}" ] || continue while read origin_dependent do touch "${DBDIR}/requires/$origin_dependent/necessary_upgrade.$tag.${level}" done < $dbpath/dependents.$tag.${level} done } _program_exec_and_record_completion__operation () { local level level=${_NECESSARY_UPDATES_level} message_section_title "Inspection of necessary upgrades at the $level level" program_exec_restartable_loop_operation necessary_ports.${level} message_echo } program_exec_and_record_completion NECESSARY_UPDATES:${_NECESSARY_UPDATES_level} done # Preparation for inspection of new leaf ports if [ ! -e "${DBDIR}/inspected_ports_only_partially" ] then PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES MAKE_DEPENDENTS_LISTS_UNIQUE PARSE_CONF' _program_exec_and_record_completion__operation () { message_section_title "Preparation for inspection of new leaf ports" find "${DBDIR}/requires" -depth 3 -type f -name dependents.all.full \ | sed -E 's|.*/([^/]+/[^/]+)/[^/]+$|\1|' \ | sort -u > ${TMPDIR}/PREPARE_INSPECT_LEAF_PORTS:nonleaf_ports sort -u "${DBDIR}/inspected_ports" > ${TMPDIR}/PREPARE_INSPECT_LEAF_PORTS:inspected_ports fileedit_manipulate_new_lines \ "${TMPDIR}/PREPARE_INSPECT_LEAF_PORTS:nonleaf_ports" \ "${TMPDIR}/PREPARE_INSPECT_LEAF_PORTS:inspected_ports" \ | grep -v -E -f "${DBDIR}/conf/HOLD_PORTS.grep_pattern" \ > ${DBDIR}/stage.loop_list/leaf_ports_primary_candidates || : cp /dev/null "${DBDIR}/grep.leaf_ports.pattern" cp /dev/null "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates" message_echo } program_exec_and_record_completion PREPARE_INSPECT_LEAF_PORTS fi # Inspection of new primary leaf ports if [ ! -e "${DBDIR}/inspected_ports_only_partially" ] then PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES MAKE_DEPENDENTS_LISTS_UNIQUE PREPARE_INSPECT_LEAF_PORTS PARSE_CONF' _program_exec_restartable_loop_operation__routine () { local origin origin_ini origin_esc dbpath origin_req origin=$1 pkgsys_is_pkgtool "$origin" && return dbpath=${DBDIR}/requires/$origin origin_esc=`str_escape_regexp "$origin"` grep -q -E "^$origin_esc$" "${DBDIR}/need.with_replaced.list" 2> /dev/null && return if ! grep -q -E "^$origin_esc$" "${DBDIR}/noneed.list" 2> /dev/null then if [ -e "$dbpath/initial_orig" ] then origin_ini=`cat "$dbpath/initial_orig"` [ -e "${DBDIR}/initial/$origin_ini/installed_version" \ -a `cat "${DBDIR}/initial/$origin_ini/dependents.all.full" 2> /dev/null | wc -l` -eq 0 ] \ && return fi [ -e "${DBDIR}/initial/$origin/installed_version" \ -a `cat "${DBDIR}/initial/$origin/dependents.all.full" 2> /dev/null | wc -l` -eq 0 ] \ && return fi if [ -e "$dbpath/requirements.all.full" ] then grep -v -E -f "${DBDIR}/conf/HOLD_PORTS.grep_pattern" "$dbpath/requirements.all.full" | \ fileedit_add_lines_if_new "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates" || : fi fileedit_add_a_line_if_new "^$origin_esc$" "${DBDIR}/grep.leaf_ports.pattern" } _program_exec_and_record_completion__operation () { local num_leaves num_leaves_prev message_section_title "Inspection of new primary leaf ports" program_exec_restartable_loop_operation leaf_ports_primary_candidates wc -l < ${DBDIR}/grep.leaf_ports.pattern | tr -d ' ' > ${DBDIR}/num_leaves cp /dev/null "${DBDIR}/leaf_ports_secondary_candidates.new_requirements" message_echo " `cat "${DBDIR}/num_leaves"` primary leaf port(s) is/are found." message_echo } program_exec_and_record_completion INSPECT_PRIMARY_LEAF_PORTS fi # Inspection of requirements of new leaf ports if [ ! -e "${DBDIR}/inspected_ports_only_partially" ] then PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES MAKE_DEPENDENTS_LISTS_UNIQUE INSPECT_PRIMARY_LEAF_PORTS PARSE_CONF' _program_exec_and_record_completion__operation () { local num_leaves num_leaves_prev num_inspect num_leaves_new message_section_title "Inspection of requirements of new leaf ports" message_echo "INFO: The inspection proceeds by iterative method." while : do _program_exec_restartable_loop_operation__routine () { local origin origin_esc dbpath origin=$1 pkgsys_is_pkgtool "$origin" && return dbpath=${DBDIR}/requires/$origin origin_esc=`str_escape_regexp "$origin"` grep -q -E "^$origin_esc$" "${DBDIR}/need.with_replaced.list" 2> /dev/null && return grep -E -v -f "${DBDIR}/grep.leaf_ports.pattern" \ "$dbpath/dependents.all.full" > /dev/null 2>&1 && return cat "$dbpath/requirements.all.full" 2> /dev/null \ >> ${DBDIR}/leaf_ports_secondary_candidates.new_requirements || : fileedit_add_a_line_if_new "^$origin_esc$" "${DBDIR}/grep.leaf_ports.pattern" } program_exec_restartable_loop_operation leaf_ports_secondary_candidates num_leaves_prev=`cat "${DBDIR}/num_leaves"` num_leaves=`wc -l < ${DBDIR}/grep.leaf_ports.pattern | tr -d ' '` num_leaves_new=`echo $(($num_leaves-$num_leaves_prev)) | tr -d ' '` if [ $num_leaves_new -eq 0 ] then message_echo " No more leaf port is found." message_echo " $num_leaves leaf port(s) is/are found in total." break fi { grep -E -v -f "${DBDIR}/grep.leaf_ports.pattern" \ "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates" || : cat "${DBDIR}/leaf_ports_secondary_candidates.new_requirements" || : } | grep -v -E -f "${DBDIR}/conf/HOLD_PORTS.grep_pattern" | sort -u \ > ${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates.tmp || : program_reset_loop_for_stage INSPECT_REQUIREMENTS_OF_LEAF_PORTS mv "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates.tmp" \ "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates" cp /dev/null "${DBDIR}/leaf_ports_secondary_candidates.new_requirements" echo "$num_leaves" > ${DBDIR}/num_leaves num_inspect=`wc -l < ${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates | tr -d ' '` message_echo " $num_leaves_new leaf port(s) is/are newly found; continue for $num_inspect candidate(s)." done grep -E -f "${DBDIR}/grep.leaf_ports.pattern" "${DBDIR}/inspected_ports" | sort -u > ${DBDIR}/leaf_ports || : message_echo } program_exec_and_record_completion INSPECT_REQUIREMENTS_OF_LEAF_PORTS fi # Order the ports considering dependencies PROGRAM_DEPENDS='CONVERT_REQUIREMENTS_LIST' _program_exec_and_record_completion__operation () { message_section_title "Ordering dependencies" if ! database_build_order_ports_considering_dependencies then message_echo "ERROR: Unsatisfied dependencies are remained:" >&2 message_cat "${DBDIR}/unsatisfied.list" message_echo "*** Aborted by ${APPNAME}" message_echo "The ports tree seems broken. You might have caught an incomplete version." message_echo "You are encouraged to update the ports tree by portsnap(8)." message_echo "Then execute" message_echo " ${APPNAME} clean" message_echo "before restart." temp_terminate_process () { :; } exit 1 fi message_echo } program_exec_and_record_completion ORDER_ALL_DEPENDENCIES # Selection of removing leaf ports PROGRAM_DEPENDS='INSPECT_REQUIREMENTS_OF_LEAF_PORTS' _program_exec_and_record_completion__operation () { message_section_title "Selection of removing leaf ports" deinstall_select_leaf_ports_to_delete message_echo } program_exec_and_record_completion SELECT_LEAF_PORTS # Selection of removing obsolete ports PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES PARSE_CONF' _program_exec_and_record_completion__operation () { message_section_title "Selection of removing obsolete ports" deinstall_select_obsolete_ports_to_delete message_echo } program_exec_and_record_completion SELECT_OBSOLETE_PORTS # Collection of leaf ports to delete if [ ! -e "${DBDIR}/inspected_ports_only_partially" ] then PROGRAM_DEPENDS='SELECT_LEAF_PORTS' _program_exec_and_record_completion__operation () { local src src_unselected reqptn_file src_with_initial_origins message_section_title "Collecting leaf ports to delete" src=${DBDIR}/leaf_ports src_unselected=${DBDIR}/leaf_ports_to_delete.unselected src_with_initial_origins=${DBDIR}/leaf_ports.with_ini reqptn_file=${DBDIR}/leaf_ports.requirements_of_unselected.grep_pattern cat "$src_unselected" 2> /dev/null | while read origin do cat "${DBDIR}/requires/$origin/requirements.all.full" || : done | sort -u | str_escape_regexp_filter \ | sed 's/^/^/;s/$/$/' > $reqptn_file database_query_add_initial_origins < $src > $src_with_initial_origins message_echo } program_exec_and_record_completion COLLECT_LEAF_PORTS_TO_DELETE fi # Collection of obsolete ports to delete PROGRAM_DEPENDS='SELECT_OBSOLETE_PORTS' _program_exec_and_record_completion__operation () { local src src_selected src_unselected dst_selected reqptn_file message_section_title "Collecting obsolete ports to delete" src=${DBDIR}/obsolete_ports.can_be_deleted src_selected=${DBDIR}/obsolete_ports_to_delete.selected src_unselected=${DBDIR}/obsolete_ports_to_delete.unselected dst_selected=${DBDIR}/obsolete_ports_to_delete reqptn_file=${DBDIR}/obsolete_ports.requirements_of_unselected.grep_pattern cat "$src_unselected" 2> /dev/null | while read origin do cat "${DBDIR}/initial/$origin/requirements.run.full" || : cat "${DBDIR}/obsolete/$origin/requirements.run.full" || : done | sort -u | str_escape_regexp_filter \ | sed 's/^/^/;s/$/$/' > $reqptn_file grep -v -E -f "$reqptn_file" "$src_selected" > $dst_selected 2> /dev/null || : message_echo } program_exec_and_record_completion COLLECT_OBSOLETE_PORTS_TO_DELETE # Set up the list of ports to reinstall PROGRAM_DEPENDS='ORDER_ALL_DEPENDENCIES' _program_exec_and_record_completion__operation () { message_section_title "Setting up the list of ports to reinstall" cp -p "${DBDIR}/reinst_order.list" "${DBDIR}/stage.loop_list/reinst_todo" message_echo } program_exec_and_record_completion SETUP_REINST_TODO # Composition of a list for deinstallation of obsolete and leaf packages PROGRAM_DEPENDS='COLLECT_LEAF_PORTS_TO_DELETE COLLECT_OBSOLETE_PORTS_TO_DELETE' _program_exec_and_record_completion__operation () { local reqptn_leaf reqptn_obs leaf_selected leaf_selected_src obs_selected obs_selected_src grepptn preserved message_section_title "Composing a list for deinstallation of obsolete and leaf packages" reqptn_leaf=${DBDIR}/leaf_ports.requirements_of_unselected.grep_pattern reqptn_obs=${DBDIR}/obsolete_ports.requirements_of_unselected.grep_pattern leaf_selected_src=${DBDIR}/leaf_ports_to_delete.selected leaf_selected=${DBDIR}/leaf_ports_to_delete obs_selected_src=${DBDIR}/obsolete_ports_to_delete.selected obs_selected=${DBDIR}/obsolete_ports_to_delete grepptn=${DBDIR}/ports_to_delete.grep_pattern grepptn_col1=${DBDIR}/ports_to_delete.grep_pattern_col1 preserved=${TMPDIR}/LIST_DEINST_PKGS::preserved if [ ! -e "${DBDIR}/inspected_ports_only_partially" ] then cat "$reqptn_leaf" "$reqptn_obs" 2> /dev/null | sort -u > $grepptn grep -v -E -f "$grepptn" "$leaf_selected_src" 2> /dev/null \ | database_query_add_initial_origins > $leaf_selected || : cat "$obs_selected" "$leaf_selected" 2> /dev/null || : else rm -f "$leaf_selected" cat "$obs_selected" 2> /dev/null fi | sort -u > ${DBDIR}/stage.loop_list/ports_to_delete str_escape_regexp_filter < ${DBDIR}/stage.loop_list/ports_to_delete \ | sed 's/^/^/;s/$/$/' > $grepptn str_escape_regexp_filter < ${DBDIR}/stage.loop_list/ports_to_delete \ | sed 's/^/^/;s/$/[[:space:]]/' > $grepptn_col1 cat "${DBDIR}/leaf_ports.with_ini" "${DBDIR}/obsolete_ports" 2> /dev/null \ | grep -E -v -f "$grepptn" > ${DBDIR}/stage.loop_list/ports_to_restore || : if [ $opt_batch_mode = no ] then if [ ! -e "${DBDIR}/inspected_ports_only_partially" ] && \ grep -v -E -f "$grepptn" "$leaf_selected_src" > $preserved 2> /dev/null then message_echo "INFO: Following leaf ports are preserved because required by other preserved leaf/obsolete ports." message_echo "----------------" while read origin do pkgtag=`cat "${DBDIR}/required/$origin/pkgtag" 2> /dev/null` || : if [ -n "$pkgtag" ] then echo "$origin" "($pkgtag)" else echo "$origin" fi done < $preserved message_echo "----------------" fi if grep -v -E -f "$grepptn" "$obs_selected_src" > $preserved 2> /dev/null then message_echo "INFO: Following obsolete ports are preserved because required by other obsolete ports." message_echo "----------------" while read origin do pkgtag=`cat "${DBDIR}/initial/$origin/installed_version" 2> /dev/null` || : if [ -n "$pkgtag" ] then echo "$origin" "($pkgtag)" else echo "$origin" fi done < $preserved message_echo "----------------" fi fi message_echo } program_exec_and_record_completion LIST_DEINST_PKGS # Collect entire distfiles list if [ $opt_inspect_entire_distinfo = yes ] then PROGRAM_DEPENDS='' _program_exec_and_record_completion__operation () { message_section_title "Collecting entire distfiles list" find "${PORTSDIR}" -depth 3 -name distinfo -exec cat {} \; \ | grep '^SHA256 ' | sed -E 's/^SHA256 \(([^)]*)\).*/\1/' \ | sort -u > ${DBDIR}/distfiles.entire.tmp mv "${DBDIR}/distfiles.entire.tmp" "${DBDIR}/distfiles.entire" message_echo } program_exec_and_record_completion COLLECT_ALL_DISTFILES_LIST fi # Inspection of all required distfiles PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES COLLECT_ALL_DISTFILES_LIST' _program_exec_and_record_completion__operation () { message_section_title "Summarizing distfiles list" cat "${DBDIR}/distfiles.entire" "${DBDIR}/distfiles.inspected" 2> /dev/null \ | sort -u | str_escape_regexp_filter \ | sed 's|^|^\\.\\/|; s|$|$|' > ${DBDIR}/distfiles.grep.pattern || : message_echo } program_exec_and_record_completion DISTFILES_LIST # Clean up of reinstallation status for preparation PROGRAM_DEPENDS='REDO_INIT INSPECT_ALL_DEPENDENCIES' _program_exec_and_record_completion__operation () { message_section_title "Cleaning up of reinstallation status for preparation" rm -rf "${DBDIR}/status.ports" message_echo } program_exec_and_record_completion CLEANUP_REINST_STATUS # Completion of building the temporary database PROGRAM_DEPENDS='REDO_INIT SETUP_REINST_TODO CLEANUP_REINST_STATUS PARSE_CONF INSPECT_ALL_DEPENDENCIES NECESSARY_UPDATES:direct NECESSARY_UPDATES:full PARSE_TARGET_ATTR_INFO MAKE_DEPENDENTS_LISTS_UNIQUE COLLECT_LEAF_PORTS_TO_DELETE' _program_exec_and_record_completion__operation () { message_section_title "The temporary database is completely built up" message_echo } program_exec_and_record_completion PREPARATION # ================================================== # ====================== MAIN ====================== # ================================================== # Execute command operations which must be done before actual (re/de)installation processes command_exec_before_actual_re_de_installation "$@" # Set termination messages temp_terminate_process () { temp_terminate_process_common } # Reinstallation of remained ports PROGRAM_DEPENDS='PREPARATION' _program_exec_restartable_loop_operation__routine () { reinstall_exec "$@" } _program_exec_and_record_completion__operation () { local _MSG_CURRENT_STAGE_general _MSG_CURRENT_STAGE_general="reinstallation" temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}" message_section_title "Reinstallation" program_exec_restartable_loop_operation reinst_todo reinstall_restore_conflicts temp_set_msg_current_stage message_echo } program_exec_and_record_completion REINSTALLATION # Restoration of obsolete and leaf packages which have been deinstalled but unselected from the deletion list again PROGRAM_DEPENDS='REDO_INIT LIST_DEINST_PKGS' _program_exec_restartable_loop_operation__routine () { deinstall_restore "$@" } _program_exec_and_record_completion__operation () { local _MSG_CURRENT_STAGE_general _MSG_CURRENT_STAGE_general="restoration of unselected obsolete/leaf packages" temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}" message_section_title "Restoration of unselected obsolete/leaf packages" program_exec_restartable_loop_operation ports_to_restore temp_set_msg_current_stage message_echo } program_exec_and_record_completion RESTORE_ONCE_DEINST_PKGS # Deinstallation of unused obsolete and leaf packages PROGRAM_DEPENDS='REDO_INIT LIST_DEINST_PKGS' _program_exec_restartable_loop_operation__routine () { deinstall_exec "$@" } _program_exec_and_record_completion__operation () { local _MSG_CURRENT_STAGE_general _MSG_CURRENT_STAGE_general="deinstallation of obsolete/leaf packages" temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}" message_section_title "Deinstallation of unused obsolete/leaf packages" program_exec_restartable_loop_operation ports_to_delete temp_set_msg_current_stage message_echo } program_exec_and_record_completion DEINST_UNUSED_PKGS # Clean up obsolete or unused distfiles if [ $opt_only_target_scope = no -a $opt_keep_distfiles = no ] then PROGRAM_DEPENDS='REINSTALLATION DISTFILES_LIST' _program_exec_and_record_completion__operation () { local tmp_distfiles_exists message_section_title "Cleaning up obsolete or unused distfiles" tmp_distfiles_exists=${TMPDIR}/CLEANUP_OBSLETE_DISTFILES::distfiles_exists [ $opt_dry_run = yes ] && message_echo "INFO: The operations are not actually carried out." ( set -e; cd "${DISTDIR}" && find . -type f ) \ | sed 's|^\./||' | sort -u > $tmp_distfiles_exists fileedit_manipulate_old_lines "$tmp_distfiles_exists" "${DBDIR}/distfiles.entire" \ | while read distfile do if [ $opt_batch_mode = no ] then echo " $distfile" fi [ $opt_dry_run = yes ] && continue rm -f "${DISTDIR}/$distfile" done message_echo } program_exec_and_record_completion CLEANUP_OBSLETE_DISTFILES fi # Rebuild of package database PROGRAM_DEPENDS='REINSTALLATION RESTORE_ONCE_DEINST_PKGS DEINST_UNUSED_PKGS' _program_exec_and_record_completion__operation () { which -s pkgdb || return 0 message_section_title "Rebuilding package database for portupgrade" pkgdb -fu message_echo } program_exec_and_record_completion REBUILD_PKGDB # ================================================== # ================ ENDING MESSAGES ================= # ================================================== # Notice of failures exists_unresolved_ports= message_summary_dependents_of_failed_reinstallation failure || exists_unresolved_ports=y message_summary_dependents_of_failed_reinstallation redo || exists_unresolved_ports=y message_summary_dependents_of_failed_reinstallation conflict || exists_unresolved_ports=y [ -n "$exists_unresolved_ports" ] && message_summary_advice_on_manual_solution # End temp_terminate_process () { :; } if [ -z "$exists_unresolved_ports" ] then message_section_title "COMPLETELY DONE" message_echo "- E N D -" else message_warn_no_achieved_progress || : message_section_title "Done with some unresolved problems" message_echo "- To be continued -" fi