2 # ==============================================================================
3 # portsreinstall library script
4 # - Operations for queries to the temporary database -
5 # Copyright (C) 2013-2018 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
6 # This software is distributed under the 2-Clause BSD License.
7 # ==============================================================================
9 # ============= Show a list of failed ports with their reasons =============
10 database_query_show_list_failure ()
13 tmp_valid=${TMPDIR}/database_query_show_list_failure:valid
14 if [ `cat "${DBDIR}/failed.list" 2> /dev/null | wc -l` -eq 0 ]
16 message_echo "INFO: No item is registered in this list."
19 grep -v -E -f "${DBDIR}/ports_to_delete.grep_pattern" "${DBDIR}/failed.list" 2> /dev/null \
22 grep -q -Fx "$origin" "${DBDIR}/stage.loop_list/ports_to_delete" 2> /dev/null \
25 if [ `cat "$tmp_valid" 2> /dev/null | wc -l` -eq 0 ]
27 message_echo "INFO: No valid item is registered in this list."
32 note=`cat "${DBDIR}/notes/$origin/note_failtre" 2> /dev/null || :`
34 grep -q -Fx "$origin" "${DBDIR}/manually_done.list" 2> /dev/null && resolved=yes
35 pkgtag=`cat "${DBDIR}/moved_from/$origin/pkgtag" 2> /dev/null || :`
36 if [ $opt_batch_mode = no ]
40 yes ) resolved=', resolved';;
44 detail="while [$note]"
46 detail="by unrecorded reasons"
50 echo "$origin ($pkgtag) (error $detail$resolved)"
52 echo "$origin (error $detail$resolved)"
55 printf "%s\t%s\t%s\t%s\n" "$origin" "$pkgtag" "$note" "$resolved"
61 # ============= Show a list of failed restoration of conflict =============
62 database_query_show_list_failed_conflicts_restoration ()
64 if [ `cat "${DBDIR}/deleted_conflicts" 2> /dev/null | wc -l` -eq 0 ]
66 message_echo "INFO: No item is registered in this list."
69 grep -v -E -f "${DBDIR}/ports_to_delete.grep_pattern_col1" "${DBDIR}/deleted_conflicts" \
70 | while read origin pkg
72 pkg_regexp=`str_escape_regexp "$pkg"`
73 against=`grep -E "^$pkg_regexp:" "${DBDIR}/forbidden_conflicts" 2> /dev/null | cut -d : -f 2,3 | sort -u`
74 if [ $opt_batch_mode = no ]
78 echo -n "$origin ($pkg)"
85 against=`echo "$against" | sed 's/:/(/;s/$/)/' | tr '\n' ' '`
86 str_linearize_list_and "$against"
91 against=`echo "$against" | tr '\n' '|' | sed 's/,$//'`
92 printf '%s\t%s\t%s\n' "$origin" "$pkg" "$against"
98 # ============= Insert initial flavored origins to a list of flavored origins =============
99 database_query_add_initial_origins ()
105 [ -e "${DBDIR}/moved_from/$origin/initial_orig" ] || continue
106 cat "${DBDIR}/moved_from/$origin/initial_orig"
111 # ============= Get target attributes =============
112 database_query_get_target_attributes ()
114 local prefix origin _is_all _is_target _is_requires_requirements _is_initial_requirements _is_requires_dependents _is_initial_dependents _is_requires_requirements_complement _is_relevant infofile tag level
119 _is_requires_requirements=
120 _is_initial_requirements=
121 _is_requires_dependents=
122 _is_initial_dependents=
123 _is_requires_requirements_complement=
125 if [ ! -e "${DBDIR}/target_all" -a -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ]
128 tag=`options_get_dependency_type`
130 [ $opt_only_target_scope = yes ] && level=direct
131 infofile=${DBDIR}/targets/$origin/attrs.${tag}.${level}
132 if [ -e "$infofile" ]
139 eval ${prefix}_is_all=\$\{_is_all\}
140 eval ${prefix}_is_target=\$\{_is_target\}
141 eval ${prefix}_is_requires_requirements=\$\{_is_requires_requirements\}
142 eval ${prefix}_is_initial_requirements=\$\{_is_initial_requirements\}
143 eval ${prefix}_is_requires_dependents=\$\{_is_requires_dependents\}
144 eval ${prefix}_is_initial_dependents=\$\{_is_initial_dependents\}
145 eval ${prefix}_is_requires_requirements_complement=\$\{_is_requires_requirements_complement\}
146 eval ${prefix}_is_relevant=\$\{_is_relevant\}
149 # ============= Check whether (re/de)installation of a port is suppressed =============
150 database_query_is_a_port_suppressed ()
152 local origin flags flag
155 [ $opt_suppress_self_upadte = yes ] && flags=SUPPRESSED_SELF
156 [ $opt_suppress_pkgtools_upadte = yes ] && flags="$flags SUPPRESSED_PKGNG"
159 for db in initial moved_from
161 [ -e "${DBDIR}/$db/$origin/$flag" ] && return
167 # ============= Check whether a port needs to be updated or upgraded =============
168 database_query_does_a_port_need_update ()
170 local origin dbpath frompath new_version current_version
172 dbpath=${DBDIR}/requires/$origin
173 frompath=${DBDIR}/moved_from/$origin
174 [ -e "$dbpath/conf_updated" ] && return
175 [ -e "$dbpath/new_version" ] || return
176 new_version=`cat "$dbpath/new_version"`
177 current_version=`cat "$frompath/current_version"`
178 [ "x$current_version" != "x$new_version" ]
181 # ============= Check before operations of a command which need the temporary database completely prepared =============
182 database_query_chk_preparation_completion ()
184 program_chk_stage_complete PREPARATION && return
185 message_echo "ERROR: Database has to be built completely before executing this command." >&2
189 # ============= Get a make variable value of a port =============
190 database_query_get_makevar_val ()
192 local origin variable dbdir cache value
195 dbdir=${DBDIR}/requires/$origin
196 cache=$dbdir/makevar/$variable
201 value=`database_build_make "$origin" -V "$variable"`
202 if [ -d "$dbdir" ] && misc_is_superuser_privilege
204 [ -d "$dbdir/makevar" ] || mkdir "$dbdir/makevar"
205 echo "$value" > $cache.tmp
206 mv "$cache.tmp" "$cache"
212 # ============= Get a configured value of a port =============
213 database_query_get_config_val ()
215 local origin variable dbdir cache value
218 dbfile=${DBDIR}/conf/each_port/$origin/$variable.conf
219 cat "$dbfile" 2> /dev/null || :
222 # ============= Check whether configurations for a port is default =============
223 database_query_is_default_conf ()
225 local origin mode dbpath tmp_msg is_customized is_requiremnt_replaced files tmp_old tmp_new origin_requirement tmp_msg_customized
228 dbpath=${DBDIR}/requires/$origin
229 if [ ! -e "$dbpath/is_customized" ]
231 tmp_msg=${TMPDIR}/database_query_is_default_conf:msg
232 cp /dev/null "$tmp_msg"
234 if [ `ls "${DBDIR}/conf/each_port/$origin" 2> /dev/null | wc -l` -gt 0 ]
236 files=`ls "${DBDIR}/conf/each_port/$origin" | sed -E 's/^([^.]+).*/\1/' | str_concat_items_for_sentence`
237 echo "Knobs and miscellaneous customization by $files," >> $tmp_msg
240 if ! diff -q "$dbpath/ports_options.default" "$dbpath/ports_options.current" > /dev/null 2>&1
242 echo "Non-default port options," >> $tmp_msg
245 if grep -q -Fx "$origin" "${DBDIR}/conf/NOPKG:PORTS.parsed" 2> /dev/null
247 echo "Explicit specification as non-default in ${APPNAME}.conf," >> $tmp_msg
250 tmp_old=${TMPDIR}/database_query_is_default_conf:old
251 tmp_new=${TMPDIR}/database_query_is_default_conf:new
252 is_requiremnt_replaced=no
253 if fileedit_manipulate_old_new_lines "$dbpath/requirements.all.direct.orig" "$dbpath/requirements.all.direct" \
254 "$tmp_old" "$tmp_new"
256 echo "Replacement in requirements:" >> $tmp_msg
257 echo "-------- FROM --------" >> $tmp_msg
258 sed 's/^/ /' "$tmp_old" >> $tmp_msg
259 echo "-------- TO --------" >> $tmp_msg
260 sed 's/^/ /' "$tmp_new" >> $tmp_msg
261 echo "----------------------" >> $tmp_msg
264 for origin_requirement in `cat "$dbpath/requirements.all.direct" 2> /dev/null`
266 database_query_is_default_conf "$origin_requirement" quiet && continue
267 echo "Non-default requirement $origin_requirement," >> $tmp_msg
270 { [ $is_customized = yes ] && cat "$tmp_msg"; } > $dbpath/is_customized.tmp
271 mv "$dbpath/is_customized.tmp" "$dbpath/is_customized"
273 [ `wc -c < $dbpath/is_customized` -eq 0 ] && return
274 if [ "x$mode" != xquiet ]
276 tmp_msg_customized=${TMPDIR}/database_query_is_default_conf:msg_customized
277 message_echo "INFO: This port is configured to be non-default because of"
278 sed 's/^/ /' "$dbpath/is_customized" > $tmp_msg_customized
279 message_cat "$tmp_msg_customized"
280 message_echo " so the prebuilt package is not used."
285 # ============= Output of lists in which each matching port is registered =============
286 database_query_show_list_inclusion_of_matching_port ()
288 local grandtitle lists pkgnamedb deptag level isfirst origin_target pkg_target table_target
295 message_echo "[$grandtitle]"
296 message_dependency_scope "$deptag" "$level"
299 for origin_target in `pkgsys_eval_ports_glob "$@"`
302 for table_target in $pkgnamedb
304 pkg_target=`cat "${DBDIR}/$table_target/$origin_target/pkgtag" 2> /dev/null` || :
305 [ -n "$pkg_target" ] && break
307 [ -n "$pkg_target" ] || continue
310 for subject in `echo "$lists" | tr \| ' '`
312 database_query_exists_in_list "$origin_target" "$subject" "$deptag" "$level" \
313 && match="$match $subject"
315 if [ $opt_batch_mode = no ]
317 echo -n "$origin_target ($pkg_target): "
318 echo "$match" | sed 's/^ *//;s/ /, /g'
320 printf '%s\t%s\t' "$origin_target" "$pkg_target"
321 echo "$match" | sed 's/^ *//;s/ /,/g'
324 if [ "$isfirst" = y ]
326 message_echo "ERROR: No inspected port matches the glob(s)." >&2
332 # ============= Output of "show" command for port lists =============
333 database_query_show_port_lists ()
335 local grandtitle title list listdb pkgnamedb deptag level isfirst origin_target pkg_target table_target list_target
344 message_echo "[$grandtitle]"
345 message_dependency_scope "$deptag" "$level"
348 for origin_target in `pkgsys_eval_ports_glob "$@"`
351 for table_target in $pkgnamedb
353 pkg_target=`cat "${DBDIR}/$table_target/$origin_target/pkgtag" 2> /dev/null` || :
354 [ -n "$pkg_target" ] && break
356 [ -n "$pkg_target" ] || continue
357 [ "$isfirst" = y ] || message_echo
359 [ $opt_batch_mode = no ] && printf "$title\n" "$origin_target ($pkg_target)"
361 for table_target in $listdb
363 list_target=${DBDIR}/$table_target/$origin_target/$list
364 [ -e "$list_target" ] && break
366 [ -e "$list_target" ] || continue
367 if [ $opt_batch_mode = no ]
372 for table in $pkgnamedb
374 pkg=`cat "${DBDIR}/$table/$origin/pkgtag" 2> /dev/null` || :
375 [ -n "$pkg" ] && break
377 [ -n "$pkg" ] || continue
378 echo "$origin ($pkg)"
384 for table in $pkgnamedb
386 pkg=`cat "${DBDIR}/$table/$origin/pkgtag" 2> /dev/null` || :
387 [ -n "$pkg" ] && break
389 [ -n "$pkg" ] || continue
390 printf '%s\t%s\t%s\t%s\n' "$origin_target" "$pkg_target" "$origin" "$pkg"
394 if [ "$isfirst" = y ]
396 message_echo "ERROR: No inspected port matches the glob(s)." >&2
402 # ============= Output of "show" command for log files =============
403 database_query_show_log ()
405 local grandtitle title list listdb pkgnamedb isfirst origin_target pkg_target table_target list_target
412 message_echo "[$grandtitle]"
415 for origin_target in `pkgsys_eval_ports_glob "$@"`
418 for table_target in $pkgnamedb
420 pkg_target=`cat "${DBDIR}/$table_target/$origin_target/pkgtag" 2> /dev/null` || :
421 [ -n "$pkg_target" ] && break
423 [ -n "$pkg_target" ] || continue
424 [ "$isfirst" = y ] || message_echo
426 [ $opt_batch_mode = no ] && printf "$title\n" "$origin_target ($pkg_target)"
428 for table_target in $listdb
430 list_target=${DBDIR}/$table_target/$origin_target/$list
431 [ -e "$list_target" ] && break
433 [ -e "$list_target" ] || continue
437 if [ "$isfirst" = y ]
439 message_echo "ERROR: No inspected port matches the glob(s)." >&2
445 # ============= Output of "show" command for two column lists =============
446 database_query_show_two_column_lists ()
448 local grandtitle title list listdb pkgnamedb isfirst origin_target pkg_target table_target list_target
455 message_echo "[$grandtitle]"
458 for origin_target in `pkgsys_eval_ports_glob "$@"`
461 for table_target in $pkgnamedb
463 pkg_target=`cat "${DBDIR}/$table_target/$origin_target/pkgtag" 2> /dev/null` || :
464 [ -n "$pkg_target" ] && break
466 [ -n "$pkg_target" ] || continue
467 [ "$isfirst" = y ] || message_echo
469 [ $opt_batch_mode = no ] && printf "$title\n" "$origin_target ($pkg_target)"
471 for table_target in $listdb
473 list_target=${DBDIR}/$table_target/$origin_target/$list
474 [ -e "$list_target" ] && break
476 [ -e "$list_target" ] || continue
477 if [ $opt_batch_mode = no ]
479 sed 's/[[:space:]]/: /' < $list_target
484 if [ "$isfirst" = y ]
486 message_echo "ERROR: No inspected port matches the glob(s)." >&2
492 # ============= Output of "show" command for a single list =============
493 database_query_show_single_list ()
495 local list pkgnamedb flag_filter_skip_unchanged flag_filter_only_target tmpflag_exists put_blankline
498 flag_filter_skip_unchanged=$3
499 flag_filter_only_target=$4
500 tmpflag_exists=${TMPDIR}/database_query_show_single_list::exists_item
501 if [ `cat "${DBDIR}/$list" 2> /dev/null | wc -l` -eq 0 ]
503 message_echo "INFO: No item is registered in this list."
506 if ! program_chk_stage_complete PREPARATION
508 message_echo "WARNING: The temporary database is incomplete. The raw list is shown." >&2
512 rm -f "$tmpflag_exists"
514 if [ -n "$flag_filter_only_target" \
515 -a -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ]
517 message_echo "WARNING: Ports outside of the target scope are excluded." >&2
520 if [ -n "$flag_filter_skip_unchanged" -a $opt_skip_unchanged = yes ]
522 message_echo "WARNING: Ports which have been the newest with their all requirements from the first are excluded." >&2
525 [ -n "$put_blankline" ] && message_echo
528 [ -n "$flag_filter_skip_unchanged" -a $opt_skip_unchanged = yes \
529 -a ! -e "${DBDIR}/requires/$origin/$flag_filter_skip_unchanged" ] \
531 if [ -n "$flag_filter_only_target" ]
533 database_query_get_target_attributes currentorigin "$origin"
534 [ -n "${currentorigin_is_relevant}" ] || continue
535 database_query_is_a_port_suppressed "$origin" && continue
538 for table in $pkgnamedb
540 pkg=`cat "${DBDIR}/$table/$origin/pkgtag" 2> /dev/null` || :
541 [ -n "$pkg" ] && break
543 [ -n "$pkg" ] || continue
544 touch "$tmpflag_exists"
545 if [ $opt_batch_mode = no ]
547 echo "$origin ($pkg)"
549 printf '%s\t%s\n' "$origin" "$pkg"
551 done < ${DBDIR}/$list
552 [ -e "$tmpflag_exists" ] && return
553 message_echo "INFO: No item is registered in this list."
557 # ============= Check whether the upgrade is necessary for a port =============
558 database_query_is_necessary_upgrade ()
560 local origin nodedir dbsuffix tmpfile_new tmpfile_old tmpfile_diff
562 nodedir=${DBDIR}/requires/$origin
563 [ -e "$nodedir/installed_by_pkg" ] && return 1
564 dbsuffix=`options_get_dependency_type`.`options_get_dependency_level`
565 tmpfile_new=${TMPDIR}/database_query_is_necessary_upgrade:failed_requirements.new
566 tmpfile_old=${TMPDIR}/database_query_is_necessary_upgrade:failed_requirements.old
567 tmpfile_diff=${TMPDIR}/database_query_is_necessary_upgrade:failed_requirements.diff
568 [ -e "$nodedir/failed_requirements.${dbsuffix}.previous" ] || return
569 sort -u "$nodedir/failed_requirements.${dbsuffix}" > $tmpfile_new 2> /dev/null || :
570 sort -u "$nodedir/failed_requirements.${dbsuffix}.previous" > $tmpfile_old 2> /dev/null || :
571 fileedit_exists_old_lines "$tmpfile_old" "$tmpfile_new"
574 # ============= Actual operations of "show" command for a single list =============
575 database_query_show_single_list_exec ()
577 local subject deptag level dbsuffix flag_filter_skip_unchanged flag_filter_only_target pkgnamedb
581 dbsuffix=$deptag.$level
582 flag_filter_skip_unchanged=
583 flag_filter_only_target=
584 pkgnamedb='moved_from obsolete initial'
587 message_echo "The following ports remain in the (re)installation queue for the current do/redo process:"
588 message_echo "It is noted that ports to be skipped can be included here."
589 message_dependency_scope "$deptag" "$level"
591 list=stage.loop_list/reinst_todo.remain
592 [ ${DBDIR}/reinst_order.list -nt ${DBDIR}/$list ] && list=reinst_order.list
593 flag_filter_skip_unchanged=necessary_upgrade.$dbsuffix
594 flag_filter_only_target=y
597 message_echo "The following ports have been successfully (re)installed or newly installed:"
598 message_dependency_scope "$deptag" "$level"
600 list=success.$dbsuffix.list
601 flag_filter_skip_unchanged=necessary_upgrade_completed.$dbsuffix
602 flag_filter_only_target=y
605 message_echo "The following ports need (re)installation but are to be skipped until any of their failed requirements succeeds:"
606 message_dependency_scope "$deptag" "$level"
608 list=todo_after_requirements_succeed.$dbsuffix.list
609 flag_filter_skip_unchanged=necessary_upgrade.$dbsuffix
610 flag_filter_only_target=y
613 message_echo "The following ports had problems which have been manually resolved:"
615 list=manually_done.list
618 message_echo "The following ports are configured default and installed by prebuilt packages"
620 list=installation_complete_by_pkg.list
623 message_echo "The following ports experienced failures and kept to be old or uninstalled:"
625 database_query_show_list_failure
629 message_echo "The following ports are temporarily deleted due to conflict:"
631 database_query_show_list_failed_conflicts_restoration
635 message_echo "The following ports are registered as taboo:"
640 message_echo "The following ports are registered to freeze:"
645 message_echo "The following ports are registered as necessary:"
650 message_echo "The following ports are registered as unnecessary:"
655 message_echo "The following leaf, obsolete or unneeded ports had been once deleted but are to be or have been restored:"
657 list=stage.loop_list/ports_to_restore
658 pkgnamedb='moved_from obsolete initial'
659 flag_filter_only_target=y
662 message_echo "The following leaf, obsolete or unneeded ports are to be or have been deleted:"
664 list=stage.loop_list/ports_to_delete
665 pkgnamedb='moved_from obsolete initial'
666 flag_filter_only_target=y
671 message_echo "The following ports are all detected leaf ports:"
674 message_echo "The following ports are all $deptag leaf ports:"
675 list=leaf_ports_to_delete.$deptag
678 pkgnamedb='moved_from obsolete initial'
679 flag_filter_only_target=y
684 message_echo "The following ports are all detected obsolete ports:"
685 list=obsolete_ports.can_be_deleted
687 message_echo "The following ports are all $deptag obsolete ports:"
688 list=obsolete_ports_to_delete.$deptag
691 pkgnamedb='moved_from obsolete initial'
692 flag_filter_only_target=y
695 database_query_show_single_list "$list" "$pkgnamedb" \
696 "$flag_filter_skip_unchanged" "$flag_filter_only_target"
699 # ============= Check whether a port is registered in a list =============
700 database_query_exists_in_list ()
702 local origin subject deptag level tmp_list dbsuffix origin_esc
707 tmp_list=${TMPDIR}/database_query_exists_in_list:list
708 dbsuffix=$deptag.$level
709 origin_esc=`str_escape_regexp "$origin"`
712 list=stage.loop_list/reinst_todo.remain
713 [ ${DBDIR}/reinst_order.list -nt ${DBDIR}/$list ] && list=reinst_order.list
716 list=success.$dbsuffix.list
719 list=todo_after_requirements_succeed.$dbsuffix.list
722 list=manually_done.list
725 list=installation_complete_by_pkg.list
731 grep -v -E -f "${DBDIR}/ports_to_delete.grep_pattern_col1" "${DBDIR}/deleted_conflicts" 2> /dev/null \
732 | grep -q -E "^${origin_esc}[[:space:]]"
748 list=stage.loop_list/ports_to_restore
751 list=stage.loop_list/ports_to_delete
754 grep -q -Fx "$origin" "${DBDIR}/$list" 2> /dev/null
757 # ============= Check whether the requirements of installed packages match the port configuration =============
758 database_query_dependency_matching ()
760 local origin pkg tmp_inst tmp_db
762 [ -d "${DBDIR}/requires/$origin" ] || return
763 tmp_inst=${TMPDIR}/database_query_dependency_matching.installed
764 tmp_db=${TMPDIR}/database_query_dependency_matching.configured
765 pkg=`database_build_get_new_pkgname "$origin"`
766 [ -n "$pkg" ] || return
767 pkg_info_e "$pkg" || return
768 pkg_info_qr "$pkg" | grep -v '^[[:space:]]*$' | sort -u > $tmp_inst
769 database_build_get_full_run_requirement_pkgs "$origin" > $tmp_db
770 diff "$tmp_inst" "$tmp_db" > /dev/null 2>/dev/null
773 # ============= Check whether any of the requirements are locked because being missing ports to freeze =============
774 database_query_are_requirements_not_locked ()
778 cat "${DBDIR}/requires/$origin/requirements.all.direct" 2> /dev/null | while read origin_requirement
780 pkg_requirement=`pkgsys_get_installed_pkg_from_origin "$origin_requirement"` || :
781 if grep -q -Fx "$origin_requirement" "${DBDIR}/freeze.all.list" 2> /dev/null
783 [ -n "$pkg_requirement" ] || return
784 elif [ -z "$pkg_requirement" ]
786 database_query_are_requirements_not_locked "$origin_requirement" || return
792 # ============= Check whether any of progress is made in the current run =============
793 database_query_is_any_progress ()
795 [ `cat "${DBDIR}/new_success_in_current_run" 2> /dev/null | wc -l` -gt 0 ]
798 # ============= Get the all initial origins, separated by line feed =============
799 database_query_initial_orgins ()
801 local origin origin_init
803 if [ -e "${DBDIR}/moved_from/$origin/old_origs" ]
805 for origin_init in `cat "${DBDIR}/moved_from/$origin/old_origs"`
807 [ -e "${DBDIR}/initial/$origin_init/installed_version" ] && echo "$origin_init"
810 [ -e "${DBDIR}/initial/$origin/installed_version" ] && echo "$origin"