2 # ==============================================================================
3 # portsreinstall library script
4 # - Common functions of main programs -
5 # Copyright (C) 2018 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
6 # This software is distributed under the 2-Clause BSD License.
7 # ==============================================================================
9 # ============= Define the software version =============
13 COMPATIBLE_VERSIONS='^(4\.[1]\.[0-9])$'
14 # Template for development versions
15 MYVERSION=4.0.0+toward_4.1.0_20180823215600
16 COMPATIBLE_VERSIONS='^(4\.[0-1]\.[0-9]]|4\.[0]\.[0]+(|\+toward_4\.[0-1]\.[0-9]+_[0-9]+))$'
19 # ============= Parse options, arguments and control parameters =============
20 # All arguments/options of the main program must be passed.
21 main_parse_options_arguments ()
23 # ============= Save arguments for upgraded restart =============
24 options_dump_args "$@" > ${TMPDIR}/restart_command.sh
26 # ============= Option check =============
29 options_getopts "$@" || :
30 if [ $OPTIONS_ERRNO -eq 2 ]
32 message_echo "INTERNAL ERROR: In parsing options" >&2
35 shift "${OPTIONS_SHIFT}"
39 # ============= Argument check for no-command options =============
40 if [ $opt_help_mode -ne 0 -o $opt_show_version = yes ]
44 message_echo "SYNTAX ERROR: No command is allowed for showing Help or Version" >&2
49 # ============= Output usage if the case of a help mode or option/argument errors =============
50 if [ $OPTIONS_ERRNO -ne 0 ]
53 elif [ $opt_help_mode -eq 1 ]
57 elif [ $opt_help_mode -eq 2 ]
63 # ============= Output version number =============
64 if [ $opt_show_version = yes ]
70 # ============= Set up variables for environment of ports and packages =============
72 conf_setup_packages_envs
74 # ============= Execute command operations before getting the temporary database ready =============
75 command_all_exec_before_db_creation "$@"
77 # ============= Creation of temporary database directory =============
78 database_maintain_create
80 # ============= Argument check for conventional runs =============
81 command_all_parse_args "$@"
82 shift "${COMMAND_SHIFT}"
85 # ============= Define the common termination messages =============
86 main_define_common_termination_messages ()
88 temp_terminate_process_common ()
92 [ $opt_batch_mode = yes -o $errno -eq 0 ] && return
93 msg_where=`temp_get_msg_current_stage`
94 [ -n "$msg_where" ] && msg_where=" during $msg_where"
98 message_echo "INFO: Terminated at `message_timestamp`$msg_where."
100 [ $opt_no_opening_message = yes ] && return
101 message_echo " You can restart this process from the terminated point by"
103 message_echo "INFO: Aborted at `message_timestamp`$msg_where."
105 [ $opt_no_opening_message = yes ] && return
106 message_echo " You may restart this process from the aborted point by"
108 message_echo "executing without options or arguments as:"
109 if [ -n "$COMMAND_RESTART" ]
111 message_echo " ${APPNAME} $COMMAND_RESTART"
113 message_echo " ${APPNAME}"
118 # ============= Set termination messages for special commands =============
119 main_set_termination_messages_special ()
123 # ============= Option settings =============
124 main_option_settings ()
127 # Load, renew and save option values
129 if [ \( "x$opt_reload_conf" = xyes -o "x$opt_reset_targets" = xyes \) -a "x$COMMAND_MODE" != xredo ]
131 message_echo "ERROR: Options -L and -N are available only in the initial run of redo command." >&2
135 if [ "x$opt_batch_ports_only" = xyes -a "x$opt_interactive_ports_only" = xyes ]
137 message_echo "ERROR: Options -A and -I conflict with each other." >&2
141 if [ -e "${DBDIR}/saved_options.sh" ]
143 options_chk_invalid_optvals_renewal non_renewable || optcomb_err=$?
145 options_renewed_optvals M renewable_anytime || optcomb_err=$?
146 options_renewed_optvals N renewable_in_redo_on_target || optcomb_err=$?
147 options_renewed_optvals L renewable_in_redo_on_conf || optcomb_err=$?
148 } > ${TMPDIR}/renewed_optvals.sh
149 [ $optcomb_err -eq 0 ] || exit $optcomb_err
150 . "${DBDIR}/saved_options.sh"
151 . "${TMPDIR}/renewed_optvals.sh"
153 misc_is_superuser_privilege && misc_get_all_vardefs | options_filter saved > ${DBDIR}/saved_options.sh
157 # ============= Save the previous configuration if exists =============
158 main_save_prev_conf ()
160 local PROGRAM_DEPENDS
162 _program_exec_and_record_completion__operation ()
164 rm -rf "${DBDIR}/conf.prev"
165 [ -d "${DBDIR}/conf" ] && \
166 cp -Rp "${DBDIR}/conf" "${DBDIR}/conf.prev"
169 program_exec_and_record_completion SAVE_PREV_CONF
172 # ============= Load the saved configuration =============
175 . "${DBDIR}/conf/setenv.sh"
178 # ============= Get complete configuration variable definitions by importing pkgtools.conf(5) if available =============
179 main_get_complete_conf ()
181 local PROGRAM_DEPENDS
182 PROGRAM_DEPENDS='SAVE_PREV_CONF'
183 _program_exec_and_record_completion__operation ()
187 rm -rf "${DBDIR}/conf"
188 mkdir -p "${DBDIR}/conf"
189 [ "x`options_get_effective_opt_load_pkgtoolsconf 2> /dev/null`" != xno -a $opt_batch_mode = no ] \
191 [ $need_msg = yes ] && \
192 message_section_title "Parsing pkgtools.conf (by using installed portupgrade)"
193 conf_get_complete_var_defs > ${DBDIR}/conf/complete_setup.sh
194 [ $need_msg = yes ] && { message_echo "===> ok"; message_echo; }
197 program_exec_and_record_completion GET_COMPLETE_CONF_VAR_DEF
200 # ============= Parse the configuration =============
203 local PROGRAM_DEPENDS
204 PROGRAM_DEPENDS='GET_COMPLETE_CONF_VAR_DEF'
205 _program_exec_and_record_completion__operation ()
207 message_section_title "Parsing the configuration"
208 conf_manipulate_available_var_defs
209 . "${DBDIR}/conf/manipulated_defs.sh"
211 conf_build_effective_MOVED
212 # Environmental variables
213 conf_setup_effective_env > ${DBDIR}/conf/setenv.sh
214 . "${DBDIR}/conf/setenv.sh"
216 conf_parse_vars_for_each_port_glob HOLD
218 conf_parse_vars_for_each_port_glob TABOO
219 fileedit_combine_lists "${DBDIR}/conf/TABOO:PORTS.parsed" "${DBDIR}/taboo.list" \
220 > ${DBDIR}/taboo.all.list
222 conf_parse_vars_for_each_port_glob FREEZE
223 fileedit_combine_lists "${DBDIR}/conf/FREEZE:PORTS.parsed" "${DBDIR}/freeze.list" \
224 > ${DBDIR}/freeze.all.list
226 conf_parse_vars_for_each_port_glob NOPKG
228 conf_build_replacement_patterns_from_REPLACE
230 conf_parse_vars_for_each_port_glob_with_bound_val CONFLICT TARGET DEF
232 conf_parse_vars_for_each_port_glob_with_bound_val BUILDCONFLICT TARGET DEF
234 conf_parse_vars_for_each_port_glob_with_bound_val INSTCONFLICT TARGET DEF
236 conf_parse_vars_for_each_port_glob_with_bound_val MARG TARGET DEF
238 conf_parse_vars_for_each_port_glob_with_bound_val MENV TARGET DEF
240 conf_parse_vars_for_each_port_glob_with_bound_val BEFOREBUILD TARGET COMMAND
242 conf_parse_vars_for_each_port_glob_with_bound_val BEFOREDEINSTALL TARGET COMMAND
244 conf_parse_vars_for_each_port_glob_with_bound_val AFTERINSTALL TARGET COMMAND
247 program_exec_and_record_completion PARSE_CONF
250 # ============= Set up parameters based on options, arguments, environment =============
251 main_setup_parameters ()
253 # ============= Termination messages during construction of the temporary database =============
254 main_define_common_termination_messages
255 temp_reset_termination_messages_common
256 main_set_termination_messages_special
258 # ============= Opening title =============
261 command_all_chk_need_opening_notice && message_opening_notice
264 # ============= Execute command operations which do not need package tools =============
266 command_all_exec_without_pkgtools "$@"
267 misc_is_superuser_privilege && database_maintain_mark_use
268 # ============= Definition of environment dependent functions =============
272 # ============= Option settings =============
274 # Execute command operations which are not affected by saved option settings
275 command_all_exec_irrespective_of_saved_options "$@"
277 # Load, renew and save option values
281 message_show_option_settings
283 # Execute command operations which should be carried out just after completing the option settings
284 command_all_exec_just_after_option_settings "$@"
286 # ============= Command-specific pre-configuration =============
288 # Execute command operations which must be done before the database construction
289 command_all_exec_command_specific_preconfiguration "$@"
291 # ============= Configurations =============
293 # Save the previous configuration if exists
296 # Get complete configuration variable definitions by importing pkgtools.conf(5) if available
297 main_get_complete_conf
299 # Parse the configuration
302 # Load the saved configuration
304 if [ $opt_just_save_options = yes ]
306 message_echo "(Save-options-only mode)"
311 # ============= Operation without packages management tools =============
312 main_operation_without_pkg_management_tools ()
314 # Execute command operations which should be done without upgrade of tools
315 command_all_exec_before_tools_upgrade "$@"
317 # Check whether the temporary database is newer than the ports tree and refresh if so
318 database_maintain_refresh_if_obsolete
321 # ============= Collect all installed packages =============
322 main_collect_all_installed_packages ()
324 local PROGRAM_DEPENDS
326 _program_exec_and_record_completion__operation ()
329 message_section_title "Collecting all installed packages"
330 mkdir -p "${DBDIR}/fossil_pkgs"
331 heritage_path=${DBDIR}/fossil_pkgs/heritage_since_`pkgsys_get_timestamp_portstree`
332 if [ ! -e "$heritage_path" ]
334 pkg_info_all_flavored_origins > $heritage_path.tmp
335 mv "$heritage_path.tmp" "$heritage_path"
337 if [ ! -e "${DBDIR}/installed_ports" ]
339 cp "$heritage_path" "${DBDIR}/installed_ports.tmp"
340 mv "${DBDIR}/installed_ports.tmp" "${DBDIR}/installed_ports"
342 pkgsys_gen_init_pkg_origin_table
345 program_exec_and_record_completion COLLECT_ALL_INSTALLED_PACKAGES
348 # ============= Preliminary inspection of tools which have to be up-to-date =============
349 # (No need depend on PARSE_CONF because INSPECT_ALL_DEPENDENCIES will take the task.)
350 main_preliminary_inspection_of_tools ()
352 local PROGRAM_DEPENDS
354 _program_exec_restartable_loop_operation__routine ()
358 database_build_inspect_dependencies "$origin"
360 _program_exec_and_record_completion__operation ()
363 message_section_title "Preliminary inspection of tools which have to be up-to-date"
365 [ "$PKGSYS_USE_PKGNG" = yes ] && pkgsys_portsmgmt_pkg
366 pkgsys_is_dialog4ports_used && pkgsys_portsmgmt_dialog4ports
367 [ -n "$MYPORTORIGIN" ] && echo "$MYPORTORIGIN"
368 } 2> /dev/null > ${DBDIR}/stage.loop_list/tools_to_inspect
369 cp /dev/null "${DBDIR}/done_required_ports_to_inspect"
371 program_exec_restartable_loop_operation tools_to_inspect
372 database_build_post_inspect_dependencies
375 program_exec_and_record_completion PRELIMINARY_INSPECTION_OF_TOOLS
378 # ============= Upgrade of pkg(8) if new =============
379 # (No need depend on PARSE_CONF because REINSTALLATION will take the task.)
380 main_upgrade_pkg8_if_new ()
382 local PROGRAM_DEPENDS
383 if [ \( "$COMMAND_MODE" = do -o "$COMMAND_MODE" = redo \) \
384 -a $opt_dry_run = no -a $opt_suppress_pkgtools_upadte = no \
385 -a "$PKGSYS_USE_PKGNG" = yes ]
387 PROGRAM_DEPENDS='PRELIMINARY_INSPECTION_OF_TOOLS'
388 _program_exec_and_record_completion__operation ()
390 local _MSG_CURRENT_STAGE_general origin
391 _MSG_CURRENT_STAGE_general="pkg(8) upgrade"
392 origin=`pkgsys_portsmgmt_pkg`
393 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
394 message_section_title "Upgrade of $origin if new"
395 touch "${DBDIR}/target_all"
396 cp "${DBDIR}/requires/$origin/requirements.all.direct.src" "${DBDIR}/requires/$origin/requirements.all.full"
397 reinstall_exec "$origin"
398 reinstall_restore_conflicts
399 rm -f "${DBDIR}/target_all"
400 temp_set_msg_current_stage
403 program_exec_and_record_completion UPGRADE_PKGNG
407 # ============= Upgrade of dialog4ports(1) if new =============
408 # (No need depend on PARSE_CONF because REINSTALLATION will take the task.)
409 main_upgrade_dialog4ports1_if_new ()
411 local PROGRAM_DEPENDS
412 if [ \( "$COMMAND_MODE" = do -o "$COMMAND_MODE" = redo \) \
413 -a $opt_dry_run = no -a $opt_suppress_pkgtools_upadte = no ] \
414 && pkgsys_is_dialog4ports_used
416 PROGRAM_DEPENDS='PRELIMINARY_INSPECTION_OF_TOOLS'
417 _program_exec_and_record_completion__operation ()
419 local _MSG_CURRENT_STAGE_general origin
420 _MSG_CURRENT_STAGE_general="dialog4ports(1) upgrade"
421 origin=`pkgsys_portsmgmt_dialog4ports`
422 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
423 message_section_title "Upgrade of $origin if new"
424 touch "${DBDIR}/target_all"
425 cp "${DBDIR}/requires/$origin/requirements.all.direct.src" "${DBDIR}/requires/$origin/requirements.all.full"
426 reinstall_exec "$origin"
427 reinstall_restore_conflicts
428 rm -f "${DBDIR}/target_all"
429 temp_set_msg_current_stage
432 program_exec_and_record_completion UPGRADE_DIALOG4PORTS
436 # ============= Upgrade of this utility if new =============
437 # (No need depend on PARSE_CONF because REINSTALLATION will take the task.)
440 local PROGRAM_DEPENDS
441 if [ \( "$COMMAND_MODE" = do -o "$COMMAND_MODE" = redo \) \
442 -a $opt_dry_run = no -a $opt_suppress_self_upadte = no \
443 -a -n "$MYPORTORIGIN" ]
445 PROGRAM_DEPENDS='PRELIMINARY_INSPECTION_OF_TOOLS'
446 _program_exec_and_record_completion__operation ()
448 local _MSG_CURRENT_STAGE_general
449 _MSG_CURRENT_STAGE_general="pkgng upgrade"
450 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
451 message_section_title "Upgrade of this utility if new"
452 touch "${DBDIR}/target_all"
453 cp "${DBDIR}/requires/$MYPORTORIGIN/requirements.all.direct.src" "${DBDIR}/requires/$MYPORTORIGIN/requirements.all.full"
454 reinstall_exec "$MYPORTORIGIN"
455 reinstall_restore_conflicts
456 rm -f "${DBDIR}/target_all"
457 temp_set_msg_current_stage
460 program_exec_and_record_completion UPGRADE_SELF
462 if [ "x`${APPNAME} -aV 2> /dev/null`" != "x$MYVERSION" ]
464 message_echo "INFO: ${APPNAME} is upgraded and the temporary database needs refresh."
465 database_maintain_clean_for_self_upgrade || :
466 message_echo "INFO: Restarting with the new version."
468 temp_trap_for_invoking_new_version
469 . "${TMPDIR}"/restart_command.sh
474 # ============= Overlay onto the temporary database by reflecting changes in configuration =============
475 main_reflect_conf_changes ()
477 local PROGRAM_DEPENDS
478 PROGRAM_DEPENDS='PARSE_CONF'
479 _program_exec_and_record_completion__operation ()
481 local tmpfile_diff tmpfile_old tmpfile_new key
482 [ -d "${DBDIR}/conf.prev" ] || return 0
483 message_section_title "Overlay onto the temporary database by reflecting changes in configuration"
484 tmpfile_old=${TMPDIR}/PATCH_TO_TMPDB_REFLECT_CONF_CHANGES::old
485 tmpfile_new=${TMPDIR}/PATCH_TO_TMPDB_REFLECT_CONF_CHANGES::new
486 tmpfile_updated_ports=${TMPDIR}/PATCH_TO_TMPDB_REFLECT_CONF_CHANGES::updated_ports
487 if fileedit_manipulate_old_new_lines \
488 "${DBDIR}/conf.prev/setenv.sh" "${DBDIR}/conf/setenv.sh" "$tmpfile_old" "$tmpfile_new"
490 if grep -q -e ^LOCALBASE= -e ^LINUXBASE= -e ^PORTSDIR= "$tmpfile_old" "$tmpfile_new"
492 message_echo "ERROR: Migration of the temporary database is unavailable because LOCALBASE, LINUXBASE or PORTSDIR was changed." >&2
493 message_echo " ${APPNAME} clean" >&2
494 message_echo "must be executed in advance." >&2
498 cut -s -d '|' -f 1,2 "${DBDIR}/conf.prev/MOVED_ALT.parsed" | tr '|' '\t' > ${TMPDIR}/MOVED_ALT.old
499 cut -s -d '|' -f 1,2 "${DBDIR}/conf/MOVED_ALT.parsed" | tr '|' '\t' > ${TMPDIR}/MOVED_ALT.new
500 if fileedit_manipulate_old_new_lines \
501 "${TMPDIR}/MOVED_ALT.old" "${TMPDIR}/MOVED_ALT.new" "$tmpfile_old" "$tmpfile_new"
503 cat "$tmpfile_old" "$tmpfile_new" | while read from to
506 [ -n "$to" ] && echo "$to"
508 fi > $tmpfile_updated_ports
509 sort -u "${DBDIR}/conf/NOPKG:PORTS.parsed" 2> /dev/null > ${TMPDIR}/NOPKG:PORTS.parsed.new || :
510 sort -u "${DBDIR}/conf.prev/NOPKG:PORTS.parsed" 2> /dev/null > ${TMPDIR}/NOPKG:PORTS.parsed.old || :
511 diff "${TMPDIR}/NOPKG:PORTS.parsed.old" "${TMPDIR}/NOPKG:PORTS.parsed.new" | sed -n 's/^[<>] //p' >> $tmpfile_updated_ports
512 if fileedit_manipulate_old_new_lines \
513 "${DBDIR}/conf.prev/REPLACE.csv" "${DBDIR}/conf/REPLACE.csv" "$tmpfile_old" "$tmpfile_new"
515 cat "$tmpfile_old" "$tmpfile_new" | while read from to
518 [ -n "$to" ] && echo "$to"
520 fi >> $tmpfile_updated_ports
521 [ `wc -l < $tmpfile_updated_ports` -gt 0 ] && rm -f "${DBDIR}/REPLACE.complete_sed_pattern"
522 [ -d "${DBDIR}/conf/each_port" ] && find "${DBDIR}/conf/each_port" -depth 2 \
525 origin=`str_dirpath_to_origin "$dbpath"`
526 dbpath_prev=${DBDIR}/conf.prev/each_port/$origin
527 diff -r "$dbpath_prev" "$dbpath" > /dev/null 2>&1 && continue
529 done >> $tmpfile_updated_ports
530 [ -d "${DBDIR}/conf.prev/each_port" ] && find "${DBDIR}/conf.prev/each_port" -depth 2 \
531 | while read dbpath_prev
533 origin=`str_dirpath_to_origin "$dbpath_prev"`
534 dbpath=${DBDIR}/conf/each_port/$origin
535 [ -d "$dbpath" ] && continue
537 done >> $tmpfile_updated_ports
538 if [ `wc -l < $tmpfile_updated_ports` -gt 0 ]
540 sort -u "$tmpfile_updated_ports" | while read origin
542 message_echo "Reset for $origin"
543 database_build_patch_reconf "$origin"
545 program_deregister_stage_complete PREPARE_FOR_INSPECT_ALL_DEPENDENCIES
546 program_deregister_stage_complete ALL_COMPLETE
550 program_exec_and_record_completion PATCH_TO_TMPDB_REFLECT_CONF_CHANGES