OSDN Git Service

Fixed a bug that incompletion of necessary build dependent detection caused incomlete...
[portsreinstall/current.git] / lib / libcommand_do.sh
1 #!/bin/sh -e
2 # ==============================================================================
3 # portsreinstall library script
4 # - "do"/"redo" command operation -
5 # Copyright (C) 2018 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
6 # This software is distributed under the 2-Clause BSD License.
7 # ==============================================================================
8
9 # ============= Operation of redo command before the database reconstruction =============
10 command_do_do__command_all_exec_command_specific_preconfiguration ()
11 {
12         program_deregister_stage_complete FORGET::PREPARATION_INSPECT_MASTER
13         program_deregister_stage_complete ALL_COMPLETE
14 }
15
16 # ============= Operation of redo command before the database reconstruction =============
17 command_do_redo__command_all_exec_command_specific_preconfiguration ()
18 {
19         program_deregister_stage_complete REDO_INIT
20         if [ $opt_reset_targets = yes ]
21         then
22                 program_deregister_stage_complete DETERMINE_SPECIFIED_TARGETS
23                 program_deregister_stage_complete PREPARE_FOR_INSPECT_ALL_DEPENDENCIES
24                 rm -rf "${DBDIR}/targets"
25         fi
26         command_do_do__command_all_exec_command_specific_preconfiguration
27 }
28
29 # ============= Meta process for redo =============
30 command_do_meta_process_for_redo ()
31 {
32         local PROGRAM_DEPENDS
33         PROGRAM_DEPENDS=''
34         _program_exec_and_record_completion__operation ()
35         {
36                 rm -f "${DBDIR}/new_success_in_current_run"
37                 [ "x$COMMAND_MODE" = xredo ] || return 0
38                 message_echo "[REDO mode]"
39                 message_echo
40         }
41         program_exec_and_record_completion REDO_INIT
42 }
43
44 # ============= Determine specified targets =============
45 command_do_determine_specified_targets ()
46 {
47         local PROGRAM_DEPENDS
48         PROGRAM_DEPENDS=''
49         _program_exec_and_record_completion__operation ()
50         {
51                 local tag level dbsuffix
52                 message_section_title "Determining specified targets"
53                 cat "${DBDIR}/stage.loop_list/target_itself.specified" \
54                         "${DBDIR}/stage.loop_list/target_dependents.specified" \
55                         "${DBDIR}/stage.loop_list/target_requirements.specified" \
56                         "${DBDIR}/need.list" \
57                         "${DBDIR}/targets_specified_so_far" 2> /dev/null \
58                         | sort -u > ${DBDIR}/targets_specified_so_far.tmp
59                 mv "${DBDIR}/targets_specified_so_far.tmp" "${DBDIR}/targets_specified_so_far"
60                 rm -f "${DBDIR}/stage.loop_list/target_itself.specified" \
61                         "${DBDIR}/stage.loop_list/target_dependents.specified" \
62                         "${DBDIR}/stage.loop_list/target_requirements.specified"
63                 if [ -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ]
64                 then
65                         options_select_new_ports_if_duplicated O \
66                                 "${DBDIR}/stage.loop_list/target_itself.specified" "$opt_target_itself"
67                         options_select_new_ports_if_duplicated t \
68                                 "${DBDIR}/stage.loop_list/target_dependents.specified" "$opt_target_dependents"
69                         options_select_new_ports_if_duplicated T \
70                                 "${DBDIR}/stage.loop_list/target_requirements.specified" "$opt_target_requirements"
71                         if [ `cat "${DBDIR}/stage.loop_list/target_itself.specified" \
72                                 "${DBDIR}/stage.loop_list/target_dependents.specified" \
73                                 "${DBDIR}/stage.loop_list/target_requirements.specified" | wc -l` -eq 0 ]
74                         then
75                                 message_echo "ERROR: No matching port for target globs." >&2
76                                 message_echo >&2
77                                 exit 1
78                         fi
79                         cat "${DBDIR}/stage.loop_list/target_itself.specified" \
80                                 "${DBDIR}/stage.loop_list/target_dependents.specified" \
81                                 "${DBDIR}/stage.loop_list/target_requirements.specified" \
82                                 | sort -u > ${TMPDIR}/DETERMINE_SPECIFIED_TARGETS.reset
83                         cat "${TMPDIR}/DETERMINE_SPECIFIED_TARGETS.reset" "${DBDIR}/need.list" 2> /dev/null \
84                                 | sort -u > ${DBDIR}/need.list.tmp
85                         mv "${DBDIR}/need.list.tmp" "${DBDIR}/need.list"
86                         sort -u "${DBDIR}/need.list" "${DBDIR}/targets_specified_so_far" \
87                                 > ${DBDIR}/targets_specified_so_far.tmp
88                         mv "${DBDIR}/targets_specified_so_far.tmp" "${DBDIR}/targets_specified_so_far"
89                         for tag in all run build none
90                         do
91                                 for level in direct full
92                                 do
93                                         dbsuffix=$tag.$level
94                                         {
95                                                 cat "${TMPDIR}/DETERMINE_SPECIFIED_TARGETS.reset"
96                                                 cat "${DBDIR}/stage.loop_list/target_dependents.specified" | while read origin
97                                                 do
98                                                         nodedir=${DBDIR}/requires/$origin
99                                                         cat "$nodedir/dependents.$dbsuffix" 2> /dev/null
100                                                 done
101                                                 cat "${DBDIR}/stage.loop_list/target_requirements.specified" | while read origin
102                                                 do
103                                                         nodedir=${DBDIR}/requires/$origin
104                                                         cat "$nodedir/requirements.$dbsuffix" 2> /dev/null
105                                                 done
106                                         } | sort -u | while read origin
107                                         do
108                                                 fileedit_rm_a_line "$origin" "${DBDIR}/success.$dbsuffix.list"
109                                                 fileedit_rm_a_line "$origin" "${DBDIR}/todo_after_requirements_succeed.$dbsuffix.list"
110                                                 rm -f "${DBDIR}/requires/$origin/succeeded_once"
111                                         done
112                                 done
113                         done
114                 fi
115                 message_echo
116         }
117         program_exec_and_record_completion DETERMINE_SPECIFIED_TARGETS
118 }
119
120 # ============= Show specified targets =============
121 command_do_show_specified_targets ()
122 {
123         if [ -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" -a $opt_batch_mode = no ]
124         then
125                 message_echo "INFO: (Re/de-)installation will be carried out only for the targets:"
126                 echo
127                 if [ `wc -l < ${DBDIR}/stage.loop_list/target_itself.specified` -gt 0 ]
128                 then
129                         message_echo "[Targets only]"
130                         echo "----------------------------------------"
131                         cat "${DBDIR}/stage.loop_list/target_itself.specified"
132                         echo "----------------------------------------"
133                         echo
134                 fi
135                 if [ `wc -l < ${DBDIR}/stage.loop_list/target_dependents.specified` -gt 0 ]
136                 then
137                         message_echo "[Targets with their `options_get_dependency_msgterm` dependents]"
138                         echo "----------------------------------------"
139                         cat "${DBDIR}/stage.loop_list/target_dependents.specified"
140                         echo "----------------------------------------"
141                         echo
142                 fi
143                 if [ `wc -l < ${DBDIR}/stage.loop_list/target_requirements.specified` -gt 0 ]
144                 then
145                         message_echo "[Targets with their `options_get_dependency_msgterm` requirements]"
146                         echo "----------------------------------------"
147                         cat "${DBDIR}/stage.loop_list/target_requirements.specified"
148                         echo "----------------------------------------"
149                         echo
150                 fi
151         fi
152 }
153
154 # ============= Determine all target ports =============
155 command_do_determine_all_target_ports ()
156 {
157         local PROGRAM_DEPENDS
158         PROGRAM_DEPENDS='DETERMINE_SPECIFIED_TARGETS COLLECT_ALL_INSTALLED_PACKAGES'
159         _program_exec_and_record_completion__operation ()
160         {
161                 message_section_title "Determining all target ports"
162                 {
163                         if [ $opt_only_target_scope = no ]
164                         then
165                                 cat "${DBDIR}/installed_ports" 2> /dev/null || :
166                         fi
167                         cat "${DBDIR}/stage.loop_list/target_itself.specified" || :
168                         cat "${DBDIR}/stage.loop_list/target_dependents.specified" || :
169                         cat "${DBDIR}/stage.loop_list/target_requirements.specified" || :
170                         cat "${DBDIR}/targets_specified_so_far" || :
171                 }  2> /dev/null | sort -u > "${DBDIR}/stage.loop_list/ports_to_inspect"
172                 cp "${DBDIR}/stage.loop_list/ports_to_inspect" "${DBDIR}/stage.loop_list/ports_to_inspect_initial"
173                 while read origin
174                 do
175                         [ -d "${PORTSDIR}/$origin" ] || echo "$origin"
176                 done < ${DBDIR}/stage.loop_list/ports_to_inspect > ${DBDIR}/obsoletes_to_escape_for_inspection
177                 message_echo
178         }
179         program_exec_and_record_completion DETERMINE_ALL_TARGET_PORTS
180 }
181
182 # ============= Inspection of all initial dependencies =============
183 command_do_inspection_of_all_initial_dependencies ()
184 {
185         local PROGRAM_DEPENDS
186         PROGRAM_DEPENDS='DETERMINE_ALL_TARGET_PORTS'
187         _program_exec_restartable_loop_operation__routine ()
188         {
189                 local origin
190                 origin=$1
191                 database_build_setup_initial_node "$origin"
192         }
193         _program_exec_and_record_completion__operation ()
194         {
195                 local DEPTH_INDEX 
196                 message_section_title "Inspecting initial dependencies of the all installed packages"
197                 [ $opt_only_target_scope = no -a -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ] && \
198                         message_echo "INFO: Ports which seem irrelevant to the targets are also inspected in order to get complete information."
199                 program_exec_restartable_loop_operation ports_to_inspect_initial
200                 database_build_post_inspect_initial_dependencies
201                 message_echo
202         }
203         program_exec_and_record_completion INSPECT_ALL_INITIAL_DEPENDENCIES
204 }
205
206 # ============= Prepare for inspecting all dependencies =============
207 command_do_prepare_for_inspect_all_dependencies ()
208 {
209         local PROGRAM_DEPENDS
210         PROGRAM_DEPENDS='PARSE_CONF  INSPECT_ALL_INITIAL_DEPENDENCIES'
211         _program_exec_and_record_completion__operation ()
212         {
213                 message_section_title "Preparing for inspection of all dependencies"
214                 database_build_escape "${DBDIR}/escaped_obsoletes" < ${DBDIR}/obsoletes_to_escape_for_inspection
215                 cp /dev/null "${DBDIR}/done_required_ports_to_inspect"
216                 message_echo
217         }
218         program_exec_and_record_completion PREPARE_FOR_INSPECT_ALL_DEPENDENCIES
219 }
220
221 # ============= Check ports of which the port options are changed and reset their databases =============
222 # Return status 0 for no need to update of inspected ports and 1 for needed to do it
223 command_do_reset_changed_portdb ()
224 {
225         local tmp_ls
226         program_chk_stage_complete INSPECT_DEPENDENTS || return
227         pkgsys_exists_saved_port_oprions_timestamps || return
228         message_section_title "Inspecting changes of port options"
229         tmp_ls=${TMPDIR}/command_do_reset_changed_portdb
230         rm -f "$tmp_ls.updated"
231         if [ ! -d "${PORT_DBDIR}" ]
232         then
233                 message_echo "WARNING: ${PORT_DBDIR} is missing. All port options are recognized as default."
234         fi
235         pkgsys_get_saved_port_oprions_timestamps_all > $tmp_ls.db
236         pkgsys_get_current_port_oprions_timestamp > $tmp_ls.log
237         pkgsys_get_changed_port_oprions "$tmp_ls.db" "$tmp_ls.log" > $tmp_ls.diff
238         if ! [ `wc -l < $tmp_ls.diff` -gt 0 ]
239         then
240                 message_echo
241                 return
242         fi
243         message_echo "INFO: There are some changes. Inspecting the detail..."
244         cp /dev/null "$tmp_ls.uninspected.dbfile"
245         cp /dev/null "$tmp_ls.uninspected.origin"
246         cp /dev/null "$tmp_ls.nonexistent.db"
247         pkgsys_conv_portoptiondbs_to_globs < $tmp_ls.diff > $tmp_ls.glob
248         str_escape_replaceval_filter < $tmp_ls.diff > $tmp_ls.diff.rpl
249         paste "$tmp_ls.diff" "$tmp_ls.diff.rpl" "$tmp_ls.glob" | while read -r dbfile dbfile_rpl glob
250         do
251                 pkgsys_eval_ports_glob "$glob" > $tmp_ls.origins
252                 if [ `wc -l < $tmp_ls.origins` -gt 0 ]
253                 then
254                         sed -E "s/^/$dbfile_rpl /" < $tmp_ls.origins
255                 else
256                         echo $dbfile >> $tmp_ls.nonexistent.db
257                 fi
258         done | while read dbfile origin
259         do
260                 if [ -d "${DBDIR}/requires/$origin" ]
261                 then
262                         message_echo "Change detected on $origin: Resetting"
263                         database_build_patch_reconf "$origin"
264                         program_deregister_stage_complete PREPARE_FOR_INSPECT_ALL_DEPENDENCIES
265                         program_deregister_stage_complete ALL_COMPLETE
266                         touch "$tmp_ls.updated"
267                 else
268                         echo "$dbfile" >> $tmp_ls.uninspected.dbfile
269                         echo "$origin" >> $tmp_ls.uninspected.origin
270                 fi
271         done
272         message_echo "INFO: Recording for not inspected ports..."
273         pkgsys_conv_portorigin_to_port_oprion_timestamp_logname < $tmp_ls.uninspected.origin > $tmp_ls.uninspected.logname
274         str_escape_regexp_filter < $tmp_ls.uninspected.dbfile | sed 's/^/^/;s/$/[[:space:]]/' > $tmp_ls.uninspected.dbfile_ptn
275         paste "$tmp_ls.uninspected.dbfile_ptn" "$tmp_ls.uninspected.logname" | while read -r dbfile_ptn logname
276         do
277                 grep -E "$dbfile_ptn" < $tmp_ls.log > ${DBDIR}/ls_dbdir/$logname.log 2> /dev/null || :
278         done
279         str_escape_regexp_filter < $tmp_ls.nonexistent.db | sed 's/^/^/;s/$/[[:space:]]/' > $tmp_ls.nonexistent.db_ptn
280         grep -E -f "$tmp_ls.nonexistent.db_ptn" < $tmp_ls.log | pkgsys_register_list_nonexistent_portopriondb
281         message_echo
282         [ ! -e "$tmp_ls.updated" ]
283 }
284
285 # ============= Inspection of all dependencies =============
286 command_do_inspection_of_all_dependencies ()
287 {
288         local PROGRAM_DEPENDS
289         PROGRAM_DEPENDS='PREPARE_FOR_INSPECT_ALL_DEPENDENCIES'
290         _program_exec_restartable_loop_operation__routine ()
291         {
292                 local origin
293                 origin=$1
294                 database_build_inspect_dependencies "$origin"
295         }
296         _program_exec_and_record_completion__operation ()
297         {
298                 local DEPTH_INDEX 
299                 message_section_title "Inspecting dependencies of the all installed packages"
300                 [ $opt_only_target_scope = no -a -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ] && \
301                         message_echo "INFO: Ports which seem irrelevant to the targets are also inspected in order to get complete information."
302                 DEPTH_INDEX='--'
303                 program_exec_restartable_loop_operation ports_to_inspect
304                 database_build_post_inspect_dependencies
305                 database_maintain_clear_prevset
306                 message_echo
307         }
308         program_exec_and_record_completion INSPECT_ALL_DEPENDENCIES
309 }
310
311 # ============= Convert dependency-lists to actual ones =============
312 command_do_convert_dependency_lists_to_actual_ones ()
313 {
314         local PROGRAM_DEPENDS
315         PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES'
316         _program_exec_restartable_loop_operation__routine ()
317         {
318                 local origin table dbtag level tag target
319                 origin=$1
320                 for table in dependents requirements
321                 do
322                         for dbtag in requires obsolete
323                         do
324                                 for level in direct full
325                                 do
326                                         for tag in all run build
327                                         do
328                                                 target=${DBDIR}/$dbtag/$origin/${table}.${tag}.${level}
329                                                 if [ -e "$target.src" ]
330                                                 then
331                                                         sed -E -f "${DBDIR}/REPLACE.complete_sed_pattern" "$target.src" \
332                                                                 | grep -v '^$' | sort -u > $target.tmp
333                                                         [ -e "$target" ] && ! diff -q "$target.tmp" "$target" > /dev/null \
334                                                                 && echo "$origin" >> ${DBDIR}/update_dependencies
335                                                         mv "$target.tmp" "$target"
336                                                 else
337                                                         [ -e "$target" ] && echo "$origin" >> ${DBDIR}/update_dependencies
338                                                         rm -f "$target"
339                                                 fi
340                                         done
341                                 done
342                         done
343                 done
344         }
345         _program_exec_and_record_completion__operation ()
346         {
347                 message_section_title "Conversion of dependency-lists to actual ones"
348                 program_exec_restartable_loop_operation convert_dependency_lists
349                 sort -u "${DBDIR}/update_dependencies" > ${DBDIR}/update_dependencies.tmp
350                 mv "${DBDIR}/update_dependencies.tmp" "${DBDIR}/update_dependencies"
351                 for tag in all run build
352                 do
353                         ( cd "${DBDIR}/requires" && \
354                                 find . -depth 3 -type f -name requirements.${tag}.full -or -name requirements.${tag}.full.orig ) \
355                                 | sort -u \
356                                 | sed 's|^./||;s|/[^/]*$||' \
357                                 | grep -v -Fx -f "${DBDIR}/update_dependencies" \
358                                 > ${TMPDIR}/convert_requirements_list:full_complete.grep_pattern || :
359                         ( cd "${DBDIR}/requires" && \
360                                 find . -depth 3 -type f -name requirements.${tag}.direct -or -name requirements.${tag}.direct.orig ) \
361                                 | sort -u \
362                                 | sed 's|^./||;s|/[^/]*$||' \
363                                 | grep -v -Fx -f "${TMPDIR}/convert_requirements_list:full_complete.grep_pattern" \
364                                 > ${DBDIR}/stage.loop_list/complete_recursive_${tag}time_reqlists || :
365                 done
366                 for inspected_level_tmp in direct node
367                 do
368                         cat "${DBDIR}/ports.inspected.${inspected_level_tmp}.list" || :
369                 done 2> /dev/null | sort -u > ${DBDIR}/stage.loop_list/trim_dependency_lists_rm_uninspected_ports
370                 find "${DBDIR}/requires" -depth 2 -type d > ${DBDIR}/stage.loop_list/inspect_dependent
371                 [ -e "${DBDIR}/dependents_files" ] && \
372                         mv "${DBDIR}/dependents_files" "${DBDIR}/dependents_files.prev"
373                 rm -f "${DBDIR}/stage.loop_list/make_dependents_lists_unique.tmp" "${DBDIR}/dependents_files.tmp"
374                 message_echo
375         }
376         program_exec_and_record_completion CONVERT_REQUIREMENTS_LIST
377 }
378
379 # ============= Completion of recursive requirement lists =============
380 command_do_completion_of_recursive_requirement_lists ()
381 {
382         local PROGRAM_DEPENDS _REQUIREMENT_LISTS_tag
383         for _REQUIREMENT_LISTS_tag in all run build
384         do
385                 PROGRAM_DEPENDS='CONVERT_REQUIREMENTS_LIST'
386                 _program_exec_restartable_loop_operation__routine ()
387                 {
388                         local tag dbpath origin suffix
389                         tag=${_REQUIREMENT_LISTS_tag}
390                         dbpath=$1
391                         origin=`str_dirpath_to_origin "$dbpath"`
392                         for suffix in '' .orig
393                         do
394                                 database_build_get_complete_recursive_dependency "$tag" "$origin" "$suffix" > /dev/null
395                         done
396                 }
397                 _program_exec_and_record_completion__operation ()
398                 {
399                         local tag
400                         tag=${_REQUIREMENT_LISTS_tag}
401                         message_section_title "Completion of ${tag}-time requirement lists"
402                         program_exec_restartable_loop_operation complete_recursive_${tag}time_reqlists
403                         message_echo
404                 }
405                 program_exec_and_record_completion RECURSIVE_REQUIREMENT_LISTS:${_REQUIREMENT_LISTS_tag}
406         done
407 }
408
409 # ============= Trim dependency lists by removing uninspected ports =============
410 command_do_trim_dependency_lists_by_removing_uninspected_ports ()
411 {
412         local PROGRAM_DEPENDS
413         if [ $opt_only_target_scope = yes ]
414         then
415                 PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES CONVERT_REQUIREMENTS_LIST'
416                 _program_exec_restartable_loop_operation__routine ()
417                 {
418                         local dbpath tag level srcdb
419                         dbpath=$1
420                         for tag in all run build
421                         do
422                                 for level in direct full
423                                 do
424                                         srcdb=requirements.${tag}.${level}
425                                         [ -e "$dbpath/$srcdb" ] || continue
426                                         grep -Fx -f "${DBDIR}/inspected_ports" "$dbpath/$srcdb" > $dbpath/$srcdb.tmp || :
427                                         mv "$dbpath/$srcdb.tmp" "$dbpath/$srcdb"
428                                 done
429                         done
430                 }
431                 _program_exec_and_record_completion__operation ()
432                 {
433                         message_section_title "Trimming dependency lists by removing uninspected ports"
434                         program_exec_restartable_loop_operation trim_dependency_lists_rm_uninspected_ports
435                         message_echo
436                 }
437                 program_exec_and_record_completion TRIM_DEPENDENCY_LISTS_RM_UNINSPECTED_PORTS
438         fi
439 }
440
441 # ============= Inspection of dependents =============
442 command_do_inspection_of_dependents ()
443 {
444         local PROGRAM_DEPENDS
445         PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES CONVERT_REQUIREMENTS_LIST TRIM_DEPENDENCY_LISTS_RM_UNINSPECTED_PORTS'
446         _program_exec_restartable_loop_operation__routine ()
447         {
448                 local dbpath origin tag level suffix srcdb dstdb
449                 dbpath=$1
450                 origin=`str_dirpath_to_origin "$dbpath"`
451                 for tag in all run build
452                 do
453                         for suffix in '' .orig
454                         do
455                                 for level in direct full
456                                 do
457                                         srcdb=requirements.${tag}.${level}${suffix}
458                                         [ -e "$dbpath/$srcdb" ] || continue
459                                         dstdb=dependents.${tag}.${level}${suffix}
460                                         while read origin_requirement
461                                         do
462                                                 dstpath=${DBDIR}/requires/$origin_requirement
463                                                 echo "$dstpath/$dstdb" >> ${DBDIR}/dependents_files.tmp
464                                                 [ "$dstpath/$dstdb" -nt "$dbpath/$srcdb" ] && continue
465                                                 mkdir -p "$dstpath"
466                                                 echo "$origin" >> $dstpath/$dstdb.raw
467                                                 echo "$dstpath/$dstdb" >> ${DBDIR}/stage.loop_list/make_dependents_lists_unique.tmp
468                                         done < $dbpath/$srcdb
469                                 done
470                                 srcdb=ignored_requirements.${tag}${suffix}
471                                 [ -e "$dbpath/$srcdb" ] || continue
472                                 dstdb=ignored_dependents.${tag}${suffix}
473                                 while read origin_requirement
474                                 do
475                                         dstpath=${DBDIR}/requires/$origin_requirement
476                                         echo "$dstpath/$dstdb" >> ${DBDIR}/ignored_dependents_files.tmp
477                                         [ "$dstpath/$dstdb" -nt "$dbpath/$srcdb" ] && continue
478                                         mkdir -p "$dstpath"
479                                         echo "$origin" >> $dstpath/$dstdb.raw
480                                         echo "$dstpath/$dstdb" >> ${DBDIR}/stage.loop_list/make_ignored_dependents_lists_unique.tmp
481                                 done < $dbpath/$srcdb
482                         done
483                 done
484         }
485         _program_exec_and_record_completion__operation ()
486         {
487                 local dbrequires_valesc
488                 message_section_title "Inspection of dependents"
489                 dbrequires_valesc=`str_escape_replaceval "${DBDIR}/requires/"`
490                 program_exec_restartable_loop_operation inspect_dependent
491                 for dbtype in dependents ignored_dependents
492                 do
493                         sort -u "${DBDIR}/stage.loop_list/make_${dbtype}_lists_unique.tmp" 2> /dev/null \
494                                 > ${DBDIR}/stage.loop_list/make_${dbtype}_lists_unique || :
495                         sort -u "${DBDIR}/${dbtype}_files.tmp" 2> /dev/null > ${DBDIR}/${dbtype}_files || :
496                         [ -e "${DBDIR}/make_${dbtype}_lists_unique.prev" ] && \
497                                 fileedit_manipulate_old_lines "${DBDIR}/${dbtype}_files.prev" "${DBDIR}/${dbtype}_files" \
498                                 | xargs rm -f
499                 done
500                 message_echo
501         }
502         program_exec_and_record_completion INSPECT_DEPENDENTS
503 }
504
505 # ============= Restore escaped obsolete packages for inspection =============
506 command_do_restore_escaped_obsoletes ()
507 {
508         local PROGRAM_DEPENDS
509         PROGRAM_DEPENDS='INSPECT_DEPENDENTS'
510         _program_exec_and_record_completion__operation ()
511         {
512                 message_section_title "Restoring escaped obsolete packages for inspection"
513                 cat "${DBDIR}/escaped_obsoletes" 2> /dev/null | database_build_restore
514                 rm -f "${DBDIR}/escaped_obsoletes"
515                 message_echo
516         }
517         program_exec_and_record_completion RESTORE_ESCAPED_OBSOLETE_PACKAGES_FOR_INSPECTION
518 }
519
520 # ============= Remove duplicated lines in dependents lists =============
521 command_do_remove_duplicated_lines_in_dependents_lists ()
522 {
523         local PROGRAM_DEPENDS
524         PROGRAM_DEPENDS='CONVERT_REQUIREMENTS_LIST INSPECT_DEPENDENTS'
525         _program_exec_restartable_loop_operation__routine ()
526         {
527                 local dbpath tag level dstdb
528                 dstdb=$1
529                 cat "$dstdb" "$dstdb.raw" 2> /dev/null | sort -u > $dstdb.tmp
530                 mv "$dstdb.tmp" "$dstdb"
531                 rm -f "$dstdb.raw"
532         }
533         _program_exec_and_record_completion__operation ()
534         {
535                 local dbrequires_valesc
536                 message_section_title "Removing duplicated items in dependents lists"
537                 program_exec_restartable_loop_operation make_dependents_lists_unique
538                 message_echo
539         }
540         program_exec_and_record_completion MAKE_DEPENDENTS_LISTS_UNIQUE
541 }
542
543 # ============= Remove duplicated lines in ignored dependents lists =============
544 command_do_remove_duplicated_lines_in_ignored_dependents_lists ()
545 {
546         local PROGRAM_DEPENDS
547         PROGRAM_DEPENDS='CONVERT_REQUIREMENTS_LIST INSPECT_DEPENDENTS'
548         _program_exec_restartable_loop_operation__routine ()
549         {
550                 local dbpath tag level dstdb
551                 dstdb=$1
552                 cat "$dstdb" "$dstdb.raw" 2> /dev/null | sort -u > $dstdb.tmp
553                 mv "$dstdb.tmp" "$dstdb"
554                 rm -f "$dstdb.raw"
555         }
556         _program_exec_and_record_completion__operation ()
557         {
558                 local dbrequires_valesc
559                 message_section_title "Removing duplicated items in ignored dependents lists"
560                 program_exec_restartable_loop_operation make_ignored_dependents_lists_unique
561                 message_echo
562         }
563         program_exec_and_record_completion MAKE_IGNORED_DEPENDENTS_LISTS_UNIQUE
564 }
565
566 # ============= Preparation of target attribute information =============
567 command_do_preparation_of_target_attribute_information ()
568 {
569         local PROGRAM_DEPENDS _TARGET_ATTR_INFO_table
570         for _TARGET_ATTR_INFO_table in requirements dependents itself
571         do
572                 [ `cat "${DBDIR}/stage.loop_list/target_${_TARGET_ATTR_INFO_table}.replaced.specified" 2> /dev/null \
573                         | wc -l` -gt 0 ] || continue
574                 PROGRAM_DEPENDS='DETERMINE_SPECIFIED_TARGETS CONVERT_REQUIREMENTS_LIST'
575                 _program_exec_restartable_loop_operation__routine ()
576                 {
577                         local origin dbtargets_valesc table
578                         origin=$1
579                         dbtargets_valesc=`str_escape_replaceval "${DBDIR}/targets/"`
580                         table=${_TARGET_ATTR_INFO_table}
581                         for database in requires initial
582                         do
583                                 dbpath=${DBDIR}/$database/$origin
584                                 dstpath=${DBDIR}/targets/$origin
585                                 mkdir -p "$dstpath"
586                                 touch "$dstpath/target_itself"
587                                 echo "$origin" >> ${DBDIR}/all_targets.lst
588                                 [ $table = itself ] && continue
589                                 for tag in all run build
590                                 do
591                                         for level in direct full
592                                         do
593                                                 srcdb=${table}.${tag}.${level}
594                                                 dstdb=target_${database}_${table}.${tag}.${level}
595                                                 [ -e "$dbpath/$srcdb" ] || continue
596                                                 cat "$dbpath/$srcdb" >> ${DBDIR}/all_targets.lst
597                                                 sed -E "s/^/$dbtargets_valesc/; s|$|/$dstdb|" "$dbpath/$srcdb" \
598                                                         | fileedit_add_a_line_to_files_if_new "$origin"
599                                         done
600                                 done
601                         done
602                 }
603                 _program_exec_and_record_completion__operation ()
604                 {
605                         local table
606                         table=${_TARGET_ATTR_INFO_table}
607                         message_section_title "Preparation of target attribute information for dependency [$table]"
608                         program_exec_restartable_loop_operation target_$table.replaced.specified
609                         message_echo
610                 }
611                 program_exec_and_record_completion TARGET_ATTR_INFO:${_TARGET_ATTR_INFO_table}
612         done
613 }
614
615 # ============= Post-process after the preparation of target attribute information =============
616 command_do_post_process_after_the_preparation_of_target_attribute_information ()
617 {
618         local PROGRAM_DEPENDS
619         PROGRAM_DEPENDS='MAKE_DEPENDENTS_LISTS_UNIQUE MAKE_IGNORED_DEPENDENTS_LISTS_UNIQUE TARGET_ATTR_INFO:requirements TARGET_ATTR_INFO:dependents'
620         _program_exec_and_record_completion__operation ()
621         {
622                 message_section_title "Post-process after the preparation of target attribute information"
623                 sort -u "${DBDIR}/all_targets.lst" 2> /dev/null \
624                         | grep -Fx -f "${DBDIR}/inspected_ports" \
625                         | sed -E -f "${DBDIR}/REPLACE.complete_sed_pattern" 2> /dev/null \
626                         > ${DBDIR}/all_targets.lst.tmp || :
627                 mv "${DBDIR}/all_targets.lst.tmp" "${DBDIR}/all_targets.lst"
628                 find "${DBDIR}/targets" -depth 2 -type d > ${DBDIR}/stage.loop_list/build_complement_to_new_dependents_for_targets 2> /dev/null || :
629                 {
630                         cat "${DBDIR}/all_targets.lst" "${DBDIR}/need.with_replaced.list" 2> /dev/null || :
631                         find "${DBDIR}/moved_from" -depth 3 -type f -name installed_version \
632                                 | sed -E 's|.*/([^/]+/[^/]+)/[^/]*$|\1|'
633                 } | sort -u > ${DBDIR}/stage.loop_list/inspect_necessity
634                 cp /dev/null "${DBDIR}/stage.loop_list/parse_target_attr_info"
635                 find -E "${DBDIR}/requires" -depth 3 -type f -regex '.*/necessary_port\.(direct|full)$' -delete
636                 message_echo
637         }
638         program_exec_and_record_completion TARGET_ATTR_INFO_POSTPROCESS
639 }
640
641 # ============= Build of data on complement to new dependents for target attribute information =============
642 command_do_build_of_data_on_complement_to_new_dependents_for_target_attribute_information ()
643 {
644         local PROGRAM_DEPENDS
645         PROGRAM_DEPENDS='TARGET_ATTR_INFO_POSTPROCESS TARGET_ATTR_INFO:requirements TARGET_ATTR_INFO:dependents CONVERT_REQUIREMENTS_LIST'
646         _program_exec_restartable_loop_operation__routine ()
647         {
648                 local dbpath origin
649                 dbpath=$1
650                 origin=`str_dirpath_to_origin "$dbpath"`
651                 database_build_complement_to_new_dependents_for_targets "$origin"
652         }
653         _program_exec_and_record_completion__operation ()
654         {
655                 message_section_title "Build of data on complement to new dependents for target attribute information"
656                 program_exec_restartable_loop_operation build_complement_to_new_dependents_for_targets
657                 sort -u "${DBDIR}/stage.loop_list/parse_target_attr_info" > ${DBDIR}/stage.loop_list/parse_target_attr_info.tmp
658                 mv "${DBDIR}/stage.loop_list/parse_target_attr_info.tmp" "${DBDIR}/stage.loop_list/parse_target_attr_info"
659                 message_echo
660         }
661         program_exec_and_record_completion COMPLEMENT_TO_NEW_DEPENDENTS_FOR_TARGET_ATTR_INFO
662 }
663
664 # ============= Parse target attribute information =============
665 command_do_parse_target_attribute_information ()
666 {
667         local PROGRAM_DEPENDS
668         PROGRAM_DEPENDS='COMPLEMENT_TO_NEW_DEPENDENTS_FOR_TARGET_ATTR_INFO'
669         _program_exec_restartable_loop_operation__routine ()
670         {
671                 local dbpath origin
672                 dbpath=$1
673                 origin=`str_dirpath_to_origin "$dbpath"`
674                 database_build_target_attributes "$origin"
675         }
676         _program_exec_and_record_completion__operation ()
677         {
678                 message_section_title "Parsing target attribute information"
679                 program_exec_restartable_loop_operation parse_target_attr_info
680                 message_echo
681         }
682         program_exec_and_record_completion PARSE_TARGET_ATTR_INFO
683 }
684
685 # ============= Inspection of necessity =============
686 command_do_inspection_of_necessity ()
687 {
688         local PROGRAM_DEPENDS
689         PROGRAM_DEPENDS='TARGET_ATTR_INFO_POSTPROCESS RECURSIVE_REQUIREMENT_LISTS:run RECURSIVE_REQUIREMENT_LISTS:build INSPECT_ALL_DEPENDENCIES'
690         _program_exec_restartable_loop_operation__routine ()
691         {
692                 local origin
693                 origin=$1
694                 for level in direct full
695                 do
696                         database_build_inspect_necessity_for_only_new_upgrade "$origin" "$level"
697                 done
698         }
699         _program_exec_and_record_completion__operation ()
700         {
701                 message_section_title "Inspection of necessity"
702                 program_exec_restartable_loop_operation inspect_necessity
703                 for level in direct full
704                 do
705                         find "${DBDIR}/requires" -depth 3 -type f -name "necessary_port.${level}" \
706                                 > ${DBDIR}/stage.loop_list/necessary_ports.${level}
707                         cp "${DBDIR}/stage.loop_list/necessary_ports.${level}" "${DBDIR}/stage.loop_list/complete_necessary_ports.${level}"
708                 done
709                 message_echo
710         }
711         program_exec_and_record_completion INSPECT_NECESSITY
712 }
713
714 # ============= Inspection of necessary upgrades =============
715 command_do_inspection_of_necessary_upgrades ()
716 {
717         local PROGRAM_DEPENDS _NECESSARY_UPDATES_level
718         for _NECESSARY_UPDATES_level in direct full
719         do
720                 PROGRAM_DEPENDS='INSPECT_NECESSITY INSPECT_ALL_DEPENDENCIES MAKE_DEPENDENTS_LISTS_UNIQUE MAKE_IGNORED_DEPENDENTS_LISTS_UNIQUE'
721                 _program_exec_restartable_loop_operation__routine ()
722                 {
723                         local markerpath level dbpath origin tag
724                         markerpath=$1
725                         level=${_NECESSARY_UPDATES_level}
726                         dbpath=`dirname "$markerpath"`
727                         origin=`str_dirpath_to_origin "$dbpath"`
728                         database_query_does_a_port_need_update "$origin" || return 0
729                         for tag in all run build none
730                         do
731                                 touch "$dbpath/necessary_upgrade.${tag}.${level}"
732                                 [ -e "$dbpath/dependents.${tag}.${level}" -o "$dbpath/ignored_dependents.${tag}" ] || continue
733                                 cat "$dbpath/dependents.${tag}.${level}" "$dbpath/ignored_dependents.${tag}" 2> /dev/null | \
734                                         while read origin_dependent
735                                         do
736                                                 touch "${DBDIR}/requires/$origin_dependent/necessary_upgrade.${tag}.${level}"
737                                         done
738                         done
739                 }
740                 _program_exec_and_record_completion__operation ()
741                 {
742                         local level
743                         level=${_NECESSARY_UPDATES_level}
744                         message_section_title "Inspection of necessary upgrades at the $level level"
745                         program_exec_restartable_loop_operation necessary_ports.${level}
746                         message_echo
747                 }
748                 program_exec_and_record_completion NECESSARY_UPDATES:${_NECESSARY_UPDATES_level}
749         done
750 }
751
752 # ============= Completion of necessary upgrades for build =============
753 command_do_complete_necessary_upgrades_for_build ()
754 {
755         local PROGRAM_DEPENDS _NECESSARY_UPDATES_level
756         for _NECESSARY_UPDATES_level in direct full
757         do
758                 PROGRAM_DEPENDS="INSPECT_NECESSITY NECESSARY_UPDATES:${_NECESSARY_UPDATES_level}"
759                 _program_exec_restartable_loop_operation__routine ()
760                 {
761                         local markerpath level dbpath origin_requirement dbpath_requirement
762                         markerpath=$1
763                         level=${_NECESSARY_UPDATES_level}
764                         dbpath=`dirname "$markerpath"`
765                         [ -e "$dbpath/requirements.build.${level}" -a -e "$dbpath/necessary_upgrade.run.${level}" ] || return 0
766                         while read origin_requirement
767                         do
768                                 dbpath_requirement=${DBDIR}/requires/$origin_requirement
769                                 [ -e "$dbpath_requirement/necessary_upgrade.build.${level}" ] || continue
770                                 touch "$dbpath_requirement/necessary_upgrade.run.${level}"
771                         done < $dbpath/requirements.build.${level}
772                         :
773                 }
774                 _program_exec_and_record_completion__operation ()
775                 {
776                         local level
777                         level=${_NECESSARY_UPDATES_level}
778                         message_section_title "Completion of necessary upgrades for build at the $level level"
779                         program_exec_restartable_loop_operation complete_necessary_ports.${level}
780                         message_echo
781                 }
782                 program_exec_and_record_completion COMPLETE_NECESSARY_UPDATES:${_NECESSARY_UPDATES_level}
783         done
784 }
785
786 # ============= Preparation for inspection of new leaf ports =============
787 command_do_preparation_for_inspection_of_new_leaf_ports ()
788 {
789         local PROGRAM_DEPENDS
790         if [ ! -e "${DBDIR}/inspected_ports_only_partially" ]
791         then
792                 PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES MAKE_DEPENDENTS_LISTS_UNIQUE MAKE_IGNORED_DEPENDENTS_LISTS_UNIQUE PARSE_CONF'
793                 _program_exec_and_record_completion__operation ()
794                 {
795                         message_section_title "Preparation for inspection of new leaf ports"
796                         find "${DBDIR}/requires" -depth 3 -type f -name dependents.all.full -or -name ignored_dependents.all \
797                                 | sed -E 's|.*/([^/]+/[^/]+)/[^/]+$|\1|' \
798                                 | sort -u > ${TMPDIR}/PREPARE_INSPECT_LEAF_PORTS:nonleaf_ports
799                         sort -u "${DBDIR}/inspected_ports" > ${TMPDIR}/PREPARE_INSPECT_LEAF_PORTS:inspected_ports
800                         fileedit_manipulate_new_lines \
801                                 "${TMPDIR}/PREPARE_INSPECT_LEAF_PORTS:nonleaf_ports" \
802                                 "${TMPDIR}/PREPARE_INSPECT_LEAF_PORTS:inspected_ports" \
803                                 | grep -v -Fx -f "${DBDIR}/conf/HOLD:PORTS.parsed" 2> /dev/null \
804                                 > ${DBDIR}/stage.loop_list/leaf_ports_primary_candidates || :
805                         cp /dev/null "${DBDIR}/leaf_ports.filter"
806                         cp /dev/null "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates"
807                         message_echo
808                 }
809                 program_exec_and_record_completion PREPARE_INSPECT_LEAF_PORTS
810         fi
811 }
812
813 # ============= Inspection of new primary leaf ports =============
814 command_do_inspection_of_new_primary_leaf_ports ()
815 {
816         local PROGRAM_DEPENDS
817         if [ ! -e "${DBDIR}/inspected_ports_only_partially" ]
818         then
819                 PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES MAKE_DEPENDENTS_LISTS_UNIQUE MAKE_IGNORED_DEPENDENTS_LISTS_UNIQUE PREPARE_INSPECT_LEAF_PORTS PARSE_CONF'
820                 _program_exec_restartable_loop_operation__routine ()
821                 {
822                         local origin origin_ini dbpath origin_req
823                         origin=$1
824                         pkgsys_is_pkgtool "$origin" && return
825                         dbpath=${DBDIR}/requires/$origin
826                         grep -q -Fx "$origin" "${DBDIR}/need.with_replaced.list" 2> /dev/null && return
827                         if ! grep -q -Fx "$origin" "${DBDIR}/noneed.list" 2> /dev/null
828                         then
829                                 if [ -e "$dbpath/initial_orig" ]
830                                 then
831                                         origin_ini=`cat "$dbpath/initial_orig"`
832                                         [ -e "${DBDIR}/initial/$origin_ini/installed_version" \
833                                                 -a `cat "${DBDIR}/initial/$origin_ini/dependents.all.full" 2> /dev/null | wc -l` -eq 0 ] \
834                                                 && return
835                                 fi
836                                 [ -e "${DBDIR}/initial/$origin/installed_version" \
837                                         -a `cat "${DBDIR}/initial/$origin/dependents.all.full" 2> /dev/null | wc -l` -eq 0 ] \
838                                         && return
839                         fi
840                         if [ -e "$dbpath/requirements.all.full" -o -e "$dbpath/ignored_requirements.all" ]
841                         then
842                                 cat "$dbpath/requirements.all.full" "$dbpath/ignored_requirements.all" 2> /dev/null | \
843                                         grep -v -Fx -f "${DBDIR}/conf/HOLD:PORTS.parsed" 2> /dev/null| \
844                                         fileedit_add_lines_if_new "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates" || :
845                         fi
846                         fileedit_add_a_line_if_new "$origin" "${DBDIR}/leaf_ports.filter"
847                 }
848                 _program_exec_and_record_completion__operation ()
849                 {
850                         local num_leaves num_leaves_prev
851                         message_section_title "Inspection of new primary leaf ports"
852                         program_exec_restartable_loop_operation leaf_ports_primary_candidates
853                         wc -l < ${DBDIR}/leaf_ports.filter | tr -d ' ' > ${DBDIR}/num_leaves
854                         cp /dev/null "${DBDIR}/leaf_ports_secondary_candidates.new_requirements"
855                         message_echo "  `cat "${DBDIR}/num_leaves"` primary leaf port(s) is/are found."
856                         message_echo
857                 }
858                 program_exec_and_record_completion INSPECT_PRIMARY_LEAF_PORTS
859         fi
860 }
861
862 # ============= Inspection of requirements of new leaf ports =============
863 command_do_inspection_of_requirements_of_new_leaf_ports ()
864 {
865         local PROGRAM_DEPENDS
866         if [ ! -e "${DBDIR}/inspected_ports_only_partially" ]
867         then
868                 PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES MAKE_DEPENDENTS_LISTS_UNIQUE MAKE_IGNORED_DEPENDENTS_LISTS_UNIQUE INSPECT_PRIMARY_LEAF_PORTS PARSE_CONF'
869                 _program_exec_and_record_completion__operation ()
870                 {
871                         local num_leaves num_leaves_prev num_inspect num_leaves_new
872                         message_section_title "Inspection of requirements of new leaf ports"
873                         message_echo "INFO: The inspection proceeds by iterative method."
874                         while :
875                         do
876                                 _program_exec_restartable_loop_operation__routine ()
877                                 {
878                                         local origin dbpath
879                                         origin=$1
880                                         pkgsys_is_pkgtool "$origin" && return
881                                         dbpath=${DBDIR}/requires/$origin
882                                         grep -q -Fx "$origin" "${DBDIR}/need.with_replaced.list" 2> /dev/null && return
883                                         cat "$dbpath/dependents.all.full" "$dbpath/ignored_dependents.all"  2> /dev/null \
884                                                 | grep -Fxq -v -f "${DBDIR}/leaf_ports.filter" 2> /dev/null && return
885                                         cat "$dbpath/requirements.all.full" "$dbpath/ignored_requirements.all" 2> /dev/null \
886                                                 >> ${DBDIR}/leaf_ports_secondary_candidates.new_requirements || :
887                                         fileedit_add_a_line_if_new "$origin" "${DBDIR}/leaf_ports.filter"
888                                 }
889                                 program_exec_restartable_loop_operation leaf_ports_secondary_candidates
890                                 num_leaves_prev=`cat "${DBDIR}/num_leaves"`
891                                 num_leaves=`wc -l < ${DBDIR}/leaf_ports.filter | tr -d ' '`
892                                 num_leaves_new=`echo $(($num_leaves-$num_leaves_prev)) | tr -d ' '`
893                                 if [ $num_leaves_new -eq 0 ]
894                                 then
895                                         message_echo "  No more leaf port is found."
896                                         message_echo "  $num_leaves leaf port(s) is/are found in total."
897                                         break
898                                 fi
899                                 {
900                                         grep -Fx -v -f "${DBDIR}/leaf_ports.filter" \
901                                                 "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates" || :
902                                         cat "${DBDIR}/leaf_ports_secondary_candidates.new_requirements" || :
903                                 } 2> /dev/null | grep -v -Fx -f "${DBDIR}/conf/HOLD:PORTS.parsed" 2> /dev/null | sort -u \
904                                         > ${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates.tmp || :
905                                 program_reset_loop_for_stage INSPECT_REQUIREMENTS_OF_LEAF_PORTS
906                                 mv "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates.tmp" \
907                                         "${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates"
908                                 cp /dev/null "${DBDIR}/leaf_ports_secondary_candidates.new_requirements"
909                                 echo "$num_leaves" > ${DBDIR}/num_leaves
910                                 num_inspect=`wc -l < ${DBDIR}/stage.loop_list/leaf_ports_secondary_candidates | tr -d ' '`
911                                 message_echo "  $num_leaves_new leaf port(s) is/are newly found; continue for $num_inspect candidate(s)."
912                         done
913                         grep -Fx -f "${DBDIR}/leaf_ports.filter" "${DBDIR}/inspected_ports" 2> /dev/null | sort -u > ${DBDIR}/leaf_ports || :
914                         message_echo
915                 }
916                 program_exec_and_record_completion INSPECT_REQUIREMENTS_OF_LEAF_PORTS
917         fi
918 }
919
920 # ============= Order the ports considering dependencies =============
921 command_do_order_the_ports_considering_dependencies ()
922 {
923         local PROGRAM_DEPENDS
924         PROGRAM_DEPENDS='CONVERT_REQUIREMENTS_LIST'
925         _program_exec_and_record_completion__operation ()
926         {
927                 message_section_title "Ordering dependencies"
928                 if ! database_build_order_ports_considering_dependencies
929                 then
930                         message_echo "ERROR: Unsatisfied dependencies are remained:" >&2
931                         message_cat "${DBDIR}/unsatisfied.list"
932                         message_echo "*** Aborted by ${APPNAME}"
933                         message_echo "The ports tree seems broken. You might have caught an incomplete version."
934                         message_echo "You are encouraged to update the ports tree by portsnap(8)."
935                         message_echo "Then execute"
936                         message_echo " ${APPNAME} clean"
937                         message_echo "before restart."
938                         temp_terminate_process () { :; }
939                         exit 1
940                 fi
941                 message_echo
942         }
943         program_exec_and_record_completion ORDER_ALL_DEPENDENCIES
944 }
945
946 # ============= Selection of removing leaf ports =============
947 command_do_selection_of_removing_leaf_ports ()
948 {
949         local PROGRAM_DEPENDS
950         PROGRAM_DEPENDS='INSPECT_REQUIREMENTS_OF_LEAF_PORTS'
951         _program_exec_and_record_completion__operation ()
952         {
953                 message_section_title "Selection of removing leaf ports"
954                 deinstall_select_leaf_ports_to_delete
955                 message_echo
956         }
957         program_exec_and_record_completion SELECT_LEAF_PORTS
958 }
959
960 # ============= Selection of removing obsolete ports =============
961 command_do_selection_of_removing_obsolete_ports ()
962 {
963         local PROGRAM_DEPENDS
964         PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES PARSE_CONF'
965         _program_exec_and_record_completion__operation ()
966         {
967                 message_section_title "Selection of removing obsolete ports"
968                 deinstall_select_obsolete_ports_to_delete
969                 message_echo
970         }
971         program_exec_and_record_completion SELECT_OBSOLETE_PORTS
972 }
973
974 # ============= Collection of leaf ports to delete =============
975 command_do_collection_of_leaf_ports_to_delete ()
976 {
977         local PROGRAM_DEPENDS
978         if [ ! -e "${DBDIR}/inspected_ports_only_partially" ]
979         then
980                 PROGRAM_DEPENDS='SELECT_LEAF_PORTS'
981                 _program_exec_and_record_completion__operation ()
982                 {
983                         local src src_unselected reqptn_file src_with_initial_origins
984                         message_section_title "Collecting leaf ports to delete"
985                         src=${DBDIR}/leaf_ports
986                         src_unselected=${DBDIR}/leaf_ports_to_delete.unselected
987                         src_with_initial_origins=${DBDIR}/leaf_ports.with_ini
988                         reqptn_file=${DBDIR}/leaf_ports.requirements_of_unselected
989                         cat "$src_unselected" 2> /dev/null | while read origin
990                         do
991                                 cat "${DBDIR}/requires/$origin/requirements.all.full" "${DBDIR}/requires/$origin/ignored_requirements.all" || :
992                         done 2> /dev/null | sort -u > $reqptn_file
993                         database_query_add_initial_origins < $src > $src_with_initial_origins
994                         message_echo
995                 }
996                 program_exec_and_record_completion COLLECT_LEAF_PORTS_TO_DELETE
997         fi
998 }
999
1000 # ============= Collection of obsolete ports to delete =============
1001 command_do_collection_of_obsolete_ports_to_delete ()
1002 {
1003         local PROGRAM_DEPENDS
1004         PROGRAM_DEPENDS='SELECT_OBSOLETE_PORTS'
1005         _program_exec_and_record_completion__operation ()
1006         {
1007                 local src src_selected src_unselected dst_selected reqptn_file
1008                 message_section_title "Collecting obsolete ports to delete"
1009                 src=${DBDIR}/obsolete_ports.can_be_deleted
1010                 src_selected=${DBDIR}/obsolete_ports_to_delete.selected
1011                 src_unselected=${DBDIR}/obsolete_ports_to_delete.unselected
1012                 dst_selected=${DBDIR}/obsolete_ports_to_delete
1013                 reqptn_file=${DBDIR}/obsolete_ports.requirements_of_unselected
1014                 cat "$src_unselected" 2> /dev/null | while read origin
1015                 do
1016                         cat "${DBDIR}/initial/$origin/requirements.run.full" || :
1017                         cat "${DBDIR}/obsolete/$origin/requirements.run.full" || :
1018                 done | sort -u > $reqptn_file
1019                 grep -v -Fx -f "$reqptn_file" "$src_selected" > $dst_selected 2> /dev/null || :
1020                 message_echo
1021         }
1022         program_exec_and_record_completion COLLECT_OBSOLETE_PORTS_TO_DELETE
1023 }
1024
1025 # ============= Set up the list of ports to reinstall =============
1026 command_do_set_up_the_list_of_ports_to_reinstall ()
1027 {
1028         local PROGRAM_DEPENDS
1029         PROGRAM_DEPENDS='ORDER_ALL_DEPENDENCIES'
1030         _program_exec_and_record_completion__operation ()
1031         {
1032                 message_section_title "Setting up the list of ports to reinstall"
1033                 cp -p "${DBDIR}/reinst_order.list" "${DBDIR}/stage.loop_list/reinst_todo"
1034                 message_echo
1035         }
1036         program_exec_and_record_completion SETUP_REINST_TODO
1037 }
1038
1039 # ============= Composition of a list for deinstallation of obsolete and leaf packages =============
1040 command_do_composition_of_a_list_for_deinstallation_of_obsolete_and_leaf_packages ()
1041 {
1042         local PROGRAM_DEPENDS
1043         PROGRAM_DEPENDS='COLLECT_LEAF_PORTS_TO_DELETE COLLECT_OBSOLETE_PORTS_TO_DELETE'
1044         _program_exec_and_record_completion__operation ()
1045         {
1046                 local reqptn_leaf reqptn_obs leaf_selected leaf_selected_src obs_selected obs_selected_src grepptn preserved
1047                 message_section_title "Composing a list for deinstallation of obsolete and leaf packages"
1048                 reqptn_leaf=${DBDIR}/leaf_ports.requirements_of_unselected
1049                 reqptn_obs=${DBDIR}/obsolete_ports.requirements_of_unselected
1050                 leaf_selected_src=${DBDIR}/leaf_ports_to_delete.selected
1051                 leaf_selected=${DBDIR}/leaf_ports_to_delete
1052                 obs_selected_src=${DBDIR}/obsolete_ports_to_delete.selected
1053                 obs_selected=${DBDIR}/obsolete_ports_to_delete
1054                 grepptn=${DBDIR}/ports_to_delete.grep_pattern
1055                 grepptn_col1=${DBDIR}/ports_to_delete.grep_pattern_col1
1056                 preserved=${TMPDIR}/LIST_DEINST_PKGS::preserved
1057                 if [ ! -e "${DBDIR}/inspected_ports_only_partially" ]
1058                 then
1059                         cat "$reqptn_leaf" "$reqptn_obs" 2> /dev/null | sort -u > $grepptn
1060                         grep -v -Fx -f "$grepptn" "$leaf_selected_src" 2> /dev/null \
1061                                 | database_query_add_initial_origins > $leaf_selected || :
1062                         cat "$obs_selected" "$leaf_selected" 2> /dev/null || :
1063                 else
1064                         rm -f "$leaf_selected"
1065                         cat "$obs_selected" 2> /dev/null
1066                 fi | sort -u > ${DBDIR}/stage.loop_list/ports_to_delete
1067                 str_escape_regexp_filter < ${DBDIR}/stage.loop_list/ports_to_delete \
1068                         | sed 's/^/^/;s/$/[[:space:]]/' > $grepptn_col1
1069                 cat "${DBDIR}/leaf_ports.with_ini" "${DBDIR}/obsolete_ports" 2> /dev/null \
1070                         | grep -Fx -v -f "${DBDIR}/stage.loop_list/ports_to_delete" > ${DBDIR}/stage.loop_list/ports_to_restore 2> /dev/null || :
1071                 if [ $opt_batch_mode = no ]
1072                 then
1073                         if [ ! -e "${DBDIR}/inspected_ports_only_partially" ] && \
1074                                 grep -v -Fx -f "${DBDIR}/stage.loop_list/ports_to_delete" "$leaf_selected_src" > $preserved 2> /dev/null
1075                         then
1076                                 message_echo "INFO: Following leaf ports are preserved because required by other preserved leaf/obsolete ports."
1077                                 message_echo "----------------"
1078                                 while read origin
1079                                 do
1080                                         pkgtag=`cat "${DBDIR}/moved_from/$origin/pkgtag" 2> /dev/null` || :
1081                                         if [ -n "$pkgtag" ]
1082                                         then
1083                                                 echo "$origin" "($pkgtag)"
1084                                         else
1085                                                 echo "$origin"
1086                                         fi
1087                                 done < $preserved
1088                                 message_echo "----------------"
1089                         fi
1090                         if grep -v -Fx -f "${DBDIR}/stage.loop_list/ports_to_delete" "$obs_selected_src" > $preserved 2> /dev/null
1091                         then
1092                                 message_echo "INFO: Following obsolete ports are preserved because required by other obsolete ports."
1093                                 message_echo "----------------"
1094                                 while read origin
1095                                 do
1096                                         pkgtag=`cat "${DBDIR}/initial/$origin/installed_version" 2> /dev/null` || :
1097                                         if [ -n "$pkgtag" ]
1098                                         then
1099                                                 echo "$origin" "($pkgtag)"
1100                                         else
1101                                                 echo "$origin"
1102                                         fi
1103                                 done < $preserved
1104                                 message_echo "----------------"
1105                         fi
1106                 fi
1107                 message_echo
1108         }
1109         program_exec_and_record_completion LIST_DEINST_PKGS
1110 }
1111
1112 # ============= Collect entire distfiles list =============
1113 command_do_collect_entire_distfiles_list ()
1114 {
1115         local PROGRAM_DEPENDS
1116         if [ $opt_inspect_entire_distinfo = yes ]
1117         then
1118                 PROGRAM_DEPENDS=''
1119                 _program_exec_and_record_completion__operation ()
1120                 {
1121                         message_section_title "Collecting entire distfiles list"
1122                         find "${PORTSDIR}" -depth 3 -name distinfo -exec cat {} \; \
1123                                 | grep '^SHA256 ' | sed -E 's/^SHA256 \(([^)]*)\).*/\1/' \
1124                                 | sort -u > ${DBDIR}/distfiles.entire.tmp
1125                         mv "${DBDIR}/distfiles.entire.tmp" "${DBDIR}/distfiles.entire"
1126                         message_echo
1127                 }
1128                 program_exec_and_record_completion COLLECT_ALL_DISTFILES_LIST
1129         fi
1130 }
1131
1132 # ============= Inspection of all required distfiles =============
1133 command_do_inspection_of_all_required_distfiles ()
1134 {
1135         local PROGRAM_DEPENDS
1136         PROGRAM_DEPENDS='INSPECT_ALL_DEPENDENCIES COLLECT_ALL_DISTFILES_LIST'
1137         _program_exec_and_record_completion__operation ()
1138         {
1139                 message_section_title "Summarizing distfiles list"
1140                 {
1141                         cat "${DBDIR}/distfiles.entire" || :
1142                         cat "${DBDIR}/distfiles.inspected" || :
1143                 } 2> /dev/null | sort -u | str_escape_regexp_filter \
1144                         | sed 's|^|^\\.\\/|; s|$|$|' > ${DBDIR}/distfiles.grep.pattern || :
1145                 message_echo
1146         }
1147         program_exec_and_record_completion DISTFILES_LIST
1148 }
1149
1150 # ============= Clean up of reinstallation status for preparation =============
1151 command_do_clean_up_of_reinstallation_status_for_preparation ()
1152 {
1153         local PROGRAM_DEPENDS
1154         PROGRAM_DEPENDS='REDO_INIT INSPECT_ALL_DEPENDENCIES'
1155         _program_exec_and_record_completion__operation ()
1156         {
1157                 message_section_title "Cleaning up of reinstallation status for preparation"
1158                 rm -rf "${DBDIR}/status.ports"
1159                 message_echo
1160         }
1161         program_exec_and_record_completion CLEANUP_REINST_STATUS
1162 }
1163
1164 # ============= Completion of building the temporary database =============
1165 command_do_completion_of_building_the_temporary_database ()
1166 {
1167         local PROGRAM_DEPENDS
1168         PROGRAM_DEPENDS='REDO_INIT SETUP_REINST_TODO CLEANUP_REINST_STATUS PARSE_CONF INSPECT_ALL_DEPENDENCIES RESTORE_ESCAPED_OBSOLETE_PACKAGES_FOR_INSPECTION NECESSARY_UPDATES:direct NECESSARY_UPDATES:full PARSE_TARGET_ATTR_INFO MAKE_DEPENDENTS_LISTS_UNIQUE MAKE_IGNORED_DEPENDENTS_LISTS_UNIQUE COLLECT_LEAF_PORTS_TO_DELETE'
1169         _program_exec_and_record_completion__operation ()
1170         {
1171                 message_section_title "The temporary database is completely built up"
1172                 message_echo
1173         }
1174         program_exec_and_record_completion PREPARATION
1175 }
1176
1177 # ============= End of do/redo prepare  =============
1178 command_do_end_at_prepare_complete ()
1179 {
1180         local tmp_msg
1181         tmp_msg=${TMPDIR}/command_do_end_at_prepare_complete:msg
1182         cat > "$tmp_msg" << eof
1183 Done (skipped reinstallation) at `message_timestamp`
1184
1185  You can restart this process from the aborted/terminated point by executing without options or arguments as:
1186   ${APPNAME}
1187 eof
1188         message_cat "$tmp_msg"
1189         temp_terminate_process () { :; }
1190 }
1191
1192 # ============= Reinstallation of remained ports =============
1193 command_do_reinstallation_of_remained_ports ()
1194 {
1195         local PROGRAM_DEPENDS
1196         PROGRAM_DEPENDS='PREPARATION'
1197         _program_exec_restartable_loop_operation__routine ()
1198         {
1199                 reinstall_exec "$@"
1200                 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
1201         }
1202         _program_exec_and_record_completion__operation ()
1203         {
1204                 local _MSG_CURRENT_STAGE_general
1205                 _MSG_CURRENT_STAGE_general="reinstallation"
1206                 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
1207                 message_section_title "Reinstallation"
1208                 program_exec_restartable_loop_operation reinst_todo
1209                 [ "x$PROGRAM_STEP_COUNTER_LAST_SKIPPED" = xyes ] && message_stage_title "$PROGRAM_STEP_COUNTER"
1210                 reinstall_restore_conflicts
1211                 temp_set_msg_current_stage
1212                 message_echo
1213         }
1214         program_exec_and_record_completion REINSTALLATION
1215 }
1216
1217 # ============= Restoration of obsolete and leaf packages which have been deinstalled but unselected from the deletion list again  =============
1218 command_do_restore_needed_obsolete_and_leaf_packages ()
1219 {
1220         local PROGRAM_DEPENDS
1221         PROGRAM_DEPENDS='REDO_INIT LIST_DEINST_PKGS'
1222         _program_exec_restartable_loop_operation__routine ()
1223         {
1224                 deinstall_restore "$@"
1225         }
1226         _program_exec_and_record_completion__operation ()
1227         {
1228                 local _MSG_CURRENT_STAGE_general
1229                 _MSG_CURRENT_STAGE_general="restoration of unselected obsolete/leaf packages"
1230                 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
1231                 message_section_title "Restoration of unselected obsolete/leaf packages"
1232                 program_exec_restartable_loop_operation ports_to_restore
1233                 [ "x$PROGRAM_STEP_COUNTER_LAST_SKIPPED" = xyes ] && message_stage_title "$PROGRAM_STEP_COUNTER"
1234                 temp_set_msg_current_stage
1235                 message_echo
1236         }
1237         program_exec_and_record_completion RESTORE_ONCE_DEINST_PKGS
1238 }
1239
1240 # ============= Deinstallation of unused obsolete and leaf packages =============
1241 command_do_deinstallation_of_unused_obsolete_and_leaf_packages ()
1242 {
1243         local PROGRAM_DEPENDS
1244         PROGRAM_DEPENDS='REDO_INIT LIST_DEINST_PKGS'
1245         _program_exec_restartable_loop_operation__routine ()
1246         {
1247                 deinstall_exec "$@"
1248         }
1249         _program_exec_and_record_completion__operation ()
1250         {
1251                 local _MSG_CURRENT_STAGE_general
1252                 _MSG_CURRENT_STAGE_general="deinstallation of obsolete/leaf packages"
1253                 temp_set_msg_current_stage "${_MSG_CURRENT_STAGE_general}"
1254                 message_section_title "Deinstallation of unused obsolete/leaf packages"
1255                 program_exec_restartable_loop_operation ports_to_delete
1256                 [ "x$PROGRAM_STEP_COUNTER_LAST_SKIPPED" = xyes ] && message_stage_title "$PROGRAM_STEP_COUNTER"
1257                 temp_set_msg_current_stage
1258                 message_echo
1259         }
1260         program_exec_and_record_completion DEINST_UNUSED_PKGS
1261 }
1262
1263 # ============= Clean up obsolete or unused distfiles =============
1264 command_do_clean_up_obsolete_or_unused_distfiles ()
1265 {
1266         local PROGRAM_DEPENDS
1267         if [ $opt_only_target_scope = no -a $opt_keep_distfiles = no ]
1268         then
1269                 PROGRAM_DEPENDS='REINSTALLATION DISTFILES_LIST'
1270                 _program_exec_and_record_completion__operation ()
1271                 {
1272                         local tmp_distfiles_exists
1273                         message_section_title "Cleaning up obsolete or unused distfiles"
1274                         tmp_distfiles_exists=${TMPDIR}/CLEANUP_OBSLETE_DISTFILES::distfiles_exists
1275                         [ $opt_dry_run = yes ] && message_echo "INFO: The operations are not actually carried out."
1276                         ( set -e; cd "${DISTDIR}" && find . -type f ) \
1277                                 | sed 's|^\./||' | sort -u > $tmp_distfiles_exists
1278                         fileedit_manipulate_old_lines "$tmp_distfiles_exists" "${DBDIR}/distfiles.entire" \
1279                                 | while read distfile
1280                         do
1281                                 if [ $opt_batch_mode = no ]
1282                                 then
1283                                         echo "  $distfile"
1284                                 fi
1285                                 [ $opt_dry_run = yes ] && continue
1286                                 rm -f "${DISTDIR}/$distfile"
1287                         done
1288                         message_echo
1289                 }
1290                 program_exec_and_record_completion CLEANUP_OBSLETE_DISTFILES
1291         fi
1292 }
1293
1294 # ============= Rebuild of package database =============
1295 command_do_rebuild_of_package_database ()
1296 {
1297         local PROGRAM_DEPENDS
1298         PROGRAM_DEPENDS='REINSTALLATION RESTORE_ONCE_DEINST_PKGS DEINST_UNUSED_PKGS'
1299         _program_exec_and_record_completion__operation ()
1300         {
1301                 which -s pkgdb || return 0
1302                 message_section_title "Rebuilding package database for portupgrade"
1303                 if grep -q @ "${DBDIR}/stage.loop_list/reinst_todo"
1304                 then
1305                         message_echo "INFO: Skipped because of lacking flavor support."
1306                 else
1307                         pkgdb -fu
1308                 fi
1309                 message_echo
1310         }
1311         program_exec_and_record_completion REBUILD_PKGDB
1312 }
1313
1314 # =============Operation of redo command irrespective of option settings =============
1315 command_do_redo__command_all_exec_irrespective_of_saved_options ()
1316 {
1317         [ $opt_reload_conf = yes ] || return 0
1318         program_deregister_stage_complete SAVE_PREV_CONF
1319         program_deregister_stage_complete ALL_COMPLETE
1320         rm -f "${DBDIR}"/complete
1321 }
1322
1323 # ============= Preparation of the temporary database =============
1324 command_do_prepare ()
1325 {
1326         # Meta process for redo
1327         command_do_meta_process_for_redo
1328         
1329         # Determine specified targets
1330         command_do_determine_specified_targets
1331         
1332         # Show specified targets
1333         command_do_show_specified_targets
1334         
1335         # Determine all target ports
1336         command_do_determine_all_target_ports
1337         
1338         # Inspection of all initial dependencies
1339         command_do_inspection_of_all_initial_dependencies
1340         
1341         # Loop considering cases that port options are changed after inspection
1342         while true
1343         do
1344                 # Prepare for inspecting all dependencies
1345                 command_do_prepare_for_inspect_all_dependencies
1346                 
1347                 # Inspection of all dependencies
1348                 command_do_inspection_of_all_dependencies
1349                 
1350                 # Convert dependency-lists to actual ones
1351                 command_do_convert_dependency_lists_to_actual_ones
1352                 
1353                 # Completion of recursive requirement lists
1354                 command_do_completion_of_recursive_requirement_lists
1355                 
1356                 # Trim dependency lists by removing uninspected ports
1357                 command_do_trim_dependency_lists_by_removing_uninspected_ports
1358                 
1359                 # Inspection of dependents
1360                 command_do_inspection_of_dependents
1361                 
1362                 # End the loop when no change is made on port options after the inspection
1363                 command_do_reset_changed_portdb && break
1364         done
1365         
1366         # Restore escaped obsolete packages for inspection
1367         command_do_restore_escaped_obsoletes
1368         
1369         # Remove duplicated lines in dependents lists
1370         command_do_remove_duplicated_lines_in_dependents_lists
1371         
1372         # Remove duplicated lines in ignored dependents lists
1373         command_do_remove_duplicated_lines_in_ignored_dependents_lists
1374         
1375         # Preparation of target attribute information
1376         command_do_preparation_of_target_attribute_information
1377         
1378         # Post-process after the preparation of target attribute information
1379         command_do_post_process_after_the_preparation_of_target_attribute_information
1380         
1381         # Build of data on complement to new dependents for target attribute information
1382         command_do_build_of_data_on_complement_to_new_dependents_for_target_attribute_information
1383         
1384         # Parse target attribute information
1385         command_do_parse_target_attribute_information
1386         
1387         # Inspection of necessity
1388         command_do_inspection_of_necessity
1389         
1390         # Inspection of necessary upgrades
1391         command_do_inspection_of_necessary_upgrades
1392         
1393         # Completion of necessary upgrades for build
1394         command_do_complete_necessary_upgrades_for_build
1395         
1396         # Preparation for inspection of new leaf ports
1397         command_do_preparation_for_inspection_of_new_leaf_ports
1398         
1399         # Inspection of new primary leaf ports
1400         command_do_inspection_of_new_primary_leaf_ports
1401         
1402         # Inspection of requirements of new leaf ports
1403         command_do_inspection_of_requirements_of_new_leaf_ports
1404         
1405         # Order the ports considering dependencies
1406         command_do_order_the_ports_considering_dependencies
1407         
1408         # Selection of removing leaf ports
1409         command_do_selection_of_removing_leaf_ports
1410         
1411         # Selection of removing obsolete ports
1412         command_do_selection_of_removing_obsolete_ports
1413         
1414         # Collection of leaf ports to delete
1415         command_do_collection_of_leaf_ports_to_delete
1416         
1417         # Collection of obsolete ports to delete
1418         command_do_collection_of_obsolete_ports_to_delete
1419         
1420         # Set up the list of ports to reinstall
1421         command_do_set_up_the_list_of_ports_to_reinstall
1422         
1423         # Composition of a list for deinstallation of obsolete and leaf packages
1424         command_do_composition_of_a_list_for_deinstallation_of_obsolete_and_leaf_packages
1425         
1426         # Collect entire distfiles list
1427         command_do_collect_entire_distfiles_list
1428         
1429         # Inspection of all required distfiles
1430         command_do_inspection_of_all_required_distfiles
1431         
1432         # Clean up of reinstallation status for preparation
1433         command_do_clean_up_of_reinstallation_status_for_preparation
1434         
1435         # Completion of building the temporary database
1436         command_do_completion_of_building_the_temporary_database
1437 }
1438
1439 # ============= Reset the progress of reinstallation for retrial =============
1440 command_do_reset_for_reinst_retrial ()
1441 {
1442         program_deregister_stage_complete REINSTALLATION
1443         program_deregister_stage_complete RESTORE_ONCE_DEINST_PKGS
1444         program_deregister_stage_complete DEINST_UNUSED_PKGS
1445         rm -rf "${DBDIR}/status.ports" "${DBDIR}/new_success_in_current_run"
1446 }
1447
1448 # ============= Main operation of do/redo =============
1449 command_do_main ()
1450 {
1451         local ntrial
1452         # Reset termination messages
1453         temp_reset_termination_messages_common
1454         
1455         ntrial=0
1456         while true
1457         do
1458                 if [ $ntrial -gt 0 ]
1459                 then
1460                         message_echo "########## RETRIAL ($ntrial) OF (RE)INSTALLATION ##########"
1461                         message_echo
1462                 fi
1463                 
1464                 if [ $opt_fetch_only = yes ]
1465                 then
1466                         # Reinstallation of remained ports
1467                         command_do_reinstallation_of_remained_ports
1468                         
1469                         message_echo "Completed the fetch only mode."
1470                         exit
1471                 elif [ $opt_delete_then_reinstall = no ]
1472                 then
1473                         # Reinstallation of remained ports
1474                         command_do_reinstallation_of_remained_ports
1475                         
1476                         # Restoration of obsolete and leaf packages which have been deinstalled but unselected from the deletion list again 
1477                         command_do_restore_needed_obsolete_and_leaf_packages
1478                         
1479                         # Deinstallation of unused obsolete and leaf packages
1480                         command_do_deinstallation_of_unused_obsolete_and_leaf_packages
1481                 else
1482                         # Deinstallation of unused obsolete and leaf packages
1483                         command_do_deinstallation_of_unused_obsolete_and_leaf_packages
1484                         
1485                         # Reinstallation of remained ports
1486                         command_do_reinstallation_of_remained_ports
1487                         # Restoration of obsolete and leaf packages which have been deinstalled but unselected from the deletion list again 
1488                         
1489                         command_do_restore_needed_obsolete_and_leaf_packages
1490                 fi
1491                 
1492                 # Clean up obsolete or unused distfiles
1493                 command_do_clean_up_obsolete_or_unused_distfiles
1494                 
1495                 # Rebuild of package database
1496                 command_do_rebuild_of_package_database
1497                 
1498                 # Retry if incomplete
1499                 command_do_is_everything_resolved && break
1500                 database_query_is_any_progress || break
1501                 command_do_reset_for_reinst_retrial
1502                 ntrial=$(($ntrial+1))
1503         done
1504         :
1505 }
1506
1507 # ============= Check whether everything is resolved =============
1508 command_do_is_everything_resolved ()
1509 {
1510         local subject
1511         for subject in failure redo conflict
1512         do
1513                 database_query_show_single_list_exec "$subject" \
1514                         `options_get_dependency_type` `options_get_dependency_level` > /dev/null 2> /dev/null && return 1
1515         done
1516         :
1517 }
1518
1519 # ============= Notice of failures =============
1520 command_do_failure_notice ()
1521 {
1522         local exists_unresolved_ports
1523         exists_unresolved_ports=
1524         message_summary_dependents_of_failed_reinstallation failure || exists_unresolved_ports=y
1525         message_summary_dependents_of_failed_reinstallation redo || exists_unresolved_ports=y
1526         message_summary_dependents_of_failed_reinstallation conflict || exists_unresolved_ports=y
1527         [ "x$exists_unresolved_ports" = xy ] || return 0
1528         message_summary_advice_on_manual_solution
1529         return 1
1530 }
1531
1532 # ============= Ending process =============
1533 command_do_ending_process ()
1534 {
1535         local PROGRAM_DEPENDS
1536         temp_terminate_process () { :; }
1537         if command_do_failure_notice
1538         then
1539                 if [ $opt_no_opening_message = yes ]
1540                 then
1541                         message_echo "Done as ${APPNAME}"
1542                 else
1543                         message_section_title "COMPLETELY DONE"
1544                 fi
1545                 if [ $opt_fetch_only = no -a $opt_dry_run = no ]
1546                 then
1547                         PROGRAM_DEPENDS='REBUILD_PKGDB CLEANUP_OBSLETE_DISTFILES '
1548                         _program_exec_and_record_completion__operation ()
1549                         {
1550                         }
1551                         program_exec_and_record_completion ALL_COMPLETE
1552                         [ $opt_no_opening_message = yes ] || message_echo "- E N D -"
1553                 else
1554                         message_echo "INFO: Redo for the real (re)installation."
1555                 fi
1556         else
1557                 message_warn_no_achieved_progress
1558                 message_section_title "Done with some unresolved problems"
1559                 message_echo "- To be continued -"
1560         fi
1561 }