2 # ==============================================================================
3 # portsreinstall library script
4 # - Operations for queries to the temporary database -
5 # Copyright (C) 2013-2015 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" \
22 origin_regexp=`str_escape_regexp "$origin"`
23 grep -q -E "^$origin_regexp$" "${DBDIR}/stage.loop_list/ports_to_delete" 2> /dev/null \
26 if [ `cat "$tmp_valid" 2> /dev/null | wc -l` -eq 0 ]
28 message_echo "INFO: No valid item is registered in this list."
33 note=`cat "${DBDIR}/notes/$origin/note_failtre" 2> /dev/null || :`
35 grep -q -E "^`str_escape_regexp \"$origin\"`$" \
36 "${DBDIR}/manually_done.list" 2> /dev/null \
38 pkgtag=`cat "${DBDIR}/requires/$origin/pkgtag" 2> /dev/null || :`
39 if [ $opt_batch_mode = no ]
43 yes) resolved=', resolved';;
47 detail="while [$note]"
49 detail="by unrecorded reasons"
53 echo "$origin ($pkgtag) (error $detail$resolved)"
55 echo "$origin (error $detail$resolved)"
58 printf "%s\t%s\t%s\t%s\n" "$origin" "$pkgtag" "$note" "$resolved"
64 # ============= Show a list of failed restoration of conflicts =============
65 database_query_show_list_failed_conflicts_restoration ()
67 if [ `cat "${DBDIR}/deleted_conflicts" 2> /dev/null | wc -l` -eq 0 ]
69 message_echo "INFO: No item is registered in this list."
72 grep -v -E -f "${DBDIR}/ports_to_delete.grep_pattern_col1" "${DBDIR}/deleted_conflicts" \
73 | while read origin pkg
75 pkg_regexp=`str_escape_regexp "$pkg"`
76 against=`grep -E "^$pkg_regexp:" "${DBDIR}/forbidden_conflicts" 2> /dev/null | cut -d : -f 2 | sort -u`
77 if [ $opt_batch_mode = no ]
81 echo -n "$origin ($pkg)"
88 against=`echo "$against" | tr '\n' ' '`
89 str_linearize_list_and "$against"
94 against=`echo "$against" | tr '\n' , | sed 's/,$//'`
95 printf '%s\t%s\t%s\n' "$origin" "$pkg" "$against"
101 # ============= Insert initial origins to a list of origins =============
102 database_query_add_initial_origins ()
108 [ -e "${DBDIR}/requires/$origin/initial_orig" ] || continue
109 cat "${DBDIR}/requires/$origin/initial_orig"
114 # ============= Get target attributes =============
115 database_query_get_target_attributes ()
117 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
122 _is_requires_requirements=
123 _is_initial_requirements=
124 _is_requires_dependents=
125 _is_initial_dependents=
126 _is_requires_requirements_complement=
128 if [ ! -e "${DBDIR}/target_all" -a -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ]
131 tag=`options_get_dependency_type`
133 [ $opt_only_target_scope = yes ] && level=direct
134 infofile=${DBDIR}/targets/$origin/attrs.${tag}.${level}
135 if [ -e "$infofile" ]
142 eval ${prefix}_is_all=\$\{_is_all\}
143 eval ${prefix}_is_target=\$\{_is_target\}
144 eval ${prefix}_is_requires_requirements=\$\{_is_requires_requirements\}
145 eval ${prefix}_is_initial_requirements=\$\{_is_initial_requirements\}
146 eval ${prefix}_is_requires_dependents=\$\{_is_requires_dependents\}
147 eval ${prefix}_is_initial_dependents=\$\{_is_initial_dependents\}
148 eval ${prefix}_is_requires_requirements_complement=\$\{_is_requires_requirements_complement\}
149 eval ${prefix}_is_relevant=\$\{_is_relevant\}
152 # ============= Check whether (re/de)installation of a port is suppressed =============
153 database_query_is_a_port_suppressed ()
157 if [ $opt_suppress_self_upadte = yes ]
160 elif [ $opt_suppress_pkgtools_upadte = yes ]
162 flag=SUPPRESSED_PKGNG
166 for db in initial requires
168 [ -e "${DBDIR}/$db/$origin/$flag" ] && return
173 # ============= Check whether a port needs to be updated or upgraded =============
174 database_query_does_a_port_need_update ()
176 local origin dbpath new_version current_version
178 dbpath=${DBDIR}/requires/$origin
179 [ -e "$dbpath/conf_updated" ] && return
180 [ -e "$dbpath/new_version" ] || return
181 new_version=`cat "$dbpath/new_version"`
182 current_version=`cat "$dbpath/current_version"`
183 [ "x$current_version" != "x$new_version" ]
186 # ============= Check before operations of a command which need the temporary database completely prepared =============
187 database_query_chk_preparation_completion ()
189 program_chk_stage_complete PREPARATION && return
190 message_echo "ERROR: Database has to be built completely before executing this command." >&2
194 # ============= Get a make variable value of a port =============
195 database_query_get_makevar_val ()
197 local origin variable dbdir cache value
200 dbdir=${DBDIR}/requires/$origin
201 cache=$dbdir/makevar/$variable
206 value=`database_build_make "$origin" -V "$variable"`
207 if [ -d "$dbdir" ] && misc_is_superuser_privilege
209 [ -d "$dbdir/makevar" ] || mkdir "$dbdir/makevar"
210 echo "$value" > $cache.tmp
211 mv "$cache.tmp" "$cache"
217 # ============= Check whether configurations for a port is default =============
218 database_query_is_default_conf ()
220 local origin mode dbpath tmp_msg is_customized is_requiremnt_replaced files origin_regexp tmp_old tmp_new origin_requirement tmp_msg_customized
223 dbpath=${DBDIR}/requires/$origin
224 if [ ! -e "$dbpath/is_customized" ]
226 tmp_msg=${TMPDIR}/database_query_is_default_conf:msg
227 cp /dev/null "$tmp_msg"
229 if [ `ls "${DBDIR}/conf/each_port/$origin" 2> /dev/null | wc -l` -gt 0 ]
231 files=`ls "${DBDIR}/conf/each_port/$origin" | sed -E 's/^([^.]+).*/\1/' | str_concat_items_for_sentence`
232 echo "Knobs and miscellaneous customization by $files," >> $tmp_msg
235 if ! diff "$dbpath/ports_options.default" "$dbpath/ports_options.current" > /dev/null 2>&1
237 echo "Non-default port options," >> $tmp_msg
240 origin_regexp=`str_escape_regexp "$origin"`
241 if grep -q -E "^$origin_regexp$" "${DBDIR}/conf/NOPKG:PORTS.parsed" 2> /dev/null
243 echo "Explicit specification as non-default in ${APPNAME}.conf," >> $tmp_msg
246 tmp_old=${TMPDIR}/database_query_is_default_conf:old
247 tmp_new=${TMPDIR}/database_query_is_default_conf:new
248 is_requiremnt_replaced=no
249 if fileedit_manipulate_old_new_lines "$dbpath/requirements.all.direct.orig" "$dbpath/requirements.all.direct" \
250 "$tmp_old" "$tmp_new"
252 echo "Replacement in requirements:" >> $tmp_msg
253 echo "-------- FROM --------" >> $tmp_msg
254 sed 's/^/ /' "$tmp_old" >> $tmp_msg
255 echo "-------- TO --------" >> $tmp_msg
256 sed 's/^/ /' "$tmp_new" >> $tmp_msg
257 echo "----------------------" >> $tmp_msg
260 for origin_requirement in `cat "$dbpath/requirements.all.direct" 2> /dev/null`
262 database_query_is_default_conf "$origin_requirement" quiet && continue
263 echo "Non-default requirement $origin_requirement," >> $tmp_msg
266 { [ $is_customized = yes ] && cat "$tmp_msg"; } > $dbpath/is_customized.tmp
267 mv "$dbpath/is_customized.tmp" "$dbpath/is_customized"
269 [ `wc -c < $dbpath/is_customized` -eq 0 ] && return
270 if [ "x$mode" != xquiet ]
272 tmp_msg_customized=${TMPDIR}/database_query_is_default_conf:msg_customized
273 message_echo "INFO: This port is configured to be non-default because of"
274 sed 's/^/ /' "$dbpath/is_customized" > $tmp_msg_customized
275 message_cat "$tmp_msg_customized"
276 message_echo " so the prebuilt package is not used."
281 # ============= Output of lists in which each matching port is registered =============
282 database_query_for_list_inclusion_of_matching_port ()
284 local grandtitle lists pkgnamedb deptag level isfirst origin_target pkg_target table_target
291 message_echo "[$grandtitle]"
292 message_dependency_scope
295 for origin_target in `pkgsys_eval_ports_glob "$@"`
298 for table_target in $pkgnamedb
300 pkg_target=`cat "${DBDIR}/$table_target/$origin_target/pkgtag" 2> /dev/null` || :
301 [ -n "$pkg_target" ] && break
303 [ -n "$pkg_target" ] || continue
306 for subject in `echo "$lists" | tr \| ' '`
308 database_query_exists_in_list "$origin_target" "$subject" "$deptag" "$level" \
309 && match="$match $subject"
311 if [ $opt_batch_mode = no ]
313 echo -n "$origin_target ($pkg_target): "
314 echo "$match" | sed 's/^ *//;s/ /, /g'
316 printf '%s\t%s\t' "$origin_target" "$pkg_target"
317 echo "$match" | sed 's/^ *//;s/ /,/g'
320 if [ "$isfirst" = y ]
322 message_echo "ERROR: No inspected port matches the glob(s)." >&2
329 # ============= Output of "show" command for each matching port =============
330 database_query_for_each_matching_port ()
332 local grandtitle title list pkgnamedb deptag level isfirst origin_target pkg_target table_target list_target
340 message_echo "[$grandtitle]"
341 message_dependency_scope
344 for origin_target in `pkgsys_eval_ports_glob "$@"`
347 for table_target in $pkgnamedb
349 pkg_target=`cat "${DBDIR}/$table_target/$origin_target/pkgtag" 2> /dev/null` || :
350 [ -n "$pkg_target" ] && break
352 [ -n "$pkg_target" ] || continue
353 [ "$isfirst" = y ] || message_echo
355 [ $opt_batch_mode = no ] && printf "$title\n" "$origin_target ($pkg_target)"
357 for table_target in $pkgnamedb
359 list_target=${DBDIR}/$table_target/$origin_target/$list
360 [ -e "$list_target" ] && break
362 [ -e "$list_target" ] || continue
363 if [ $opt_batch_mode = no ]
368 for table in $pkgnamedb
370 pkg=`cat "${DBDIR}/$table/$origin/pkgtag" 2> /dev/null` || :
371 [ -n "$pkg" ] && break
373 [ -n "$pkg" ] || continue
374 echo "$origin ($pkg)"
380 for table in $pkgnamedb
382 pkg=`cat "${DBDIR}/$table/$origin/pkgtag" 2> /dev/null` || :
383 [ -n "$pkg" ] && break
385 [ -n "$pkg" ] || continue
386 printf '%s\t%s\t%s\t%s\n' "$origin_target" "$pkg_target" "$origin" "$pkg"
390 if [ "$isfirst" = y ]
392 message_echo "ERROR: No inspected port matches the glob(s)." >&2
398 # ============= Output of "show" command for a single list =============
399 database_query_show_single_list ()
401 local list pkgnamedb flag_filter_skip_unchanged flag_filter_only_target tmpflag_exists put_blankline
404 flag_filter_skip_unchanged=$3
405 flag_filter_only_target=$4
406 tmpflag_exists=${TMPDIR}/database_query_show_single_list::exists_item
407 if [ `cat "${DBDIR}/$list" 2> /dev/null | wc -l` -eq 0 ]
409 message_echo "INFO: No item is registered in this list."
412 rm -f "$tmpflag_exists"
414 if [ -n "$flag_filter_only_target" \
415 -a -n "$opt_target_itself$opt_target_dependents$opt_target_requirements" ]
417 message_echo "INFO: Ports outside of the target scope are excluded."
420 if [ -n "$flag_filter_skip_unchanged" -a $opt_skip_unchanged = yes ]
422 message_echo "INFO: Ports which have been the newest with their all requirements from the first are excluded."
425 [ -n "$put_blankline" ] && message_echo
428 [ -n "$flag_filter_skip_unchanged" -a $opt_skip_unchanged = yes \
429 -a ! -e "${DBDIR}/requires/$origin/$flag_filter_skip_unchanged" ] \
431 if [ -n "$flag_filter_only_target" ]
433 database_query_get_target_attributes currentorigin "$origin"
434 [ -n "${currentorigin_is_relevant}" ] || continue
435 database_query_is_a_port_suppressed "$origin" && continue
438 for table in $pkgnamedb
440 pkg=`cat "${DBDIR}/$table/$origin/pkgtag" 2> /dev/null` || :
441 [ -n "$pkg" ] && break
443 [ -n "$pkg" ] || continue
444 touch "$tmpflag_exists"
445 if [ $opt_batch_mode = no ]
447 echo "$origin ($pkg)"
449 printf '%s\t%s\n' "$origin" "$pkg"
451 done < ${DBDIR}/$list
452 [ -e "$tmpflag_exists" ] && return
453 message_echo "INFO: No item is registered in this list."
457 # ============= Check whether the upgrade is necessary for a port =============
458 database_query_is_necessary_upgrade ()
460 local origin nodedir dbsuffix tmpfile_new tmpfile_old tmpfile_diff
462 nodedir=${DBDIR}/requires/$origin
463 [ -e "$nodedir/installed_by_pkg" ] && return 1
464 dbsuffix=`options_get_dependency_type`.`options_get_dependency_level`
465 tmpfile_new=${TMPDIR}/database_query_is_necessary_upgrade:failed_requirements.new
466 tmpfile_old=${TMPDIR}/database_query_is_necessary_upgrade:failed_requirements.old
467 tmpfile_diff=${TMPDIR}/database_query_is_necessary_upgrade:failed_requirements.diff
468 [ -e "$nodedir/failed_requirements.${dbsuffix}.previous" ] || return
469 sort -u "$nodedir/failed_requirements.${dbsuffix}" > $tmpfile_new 2> /dev/null || :
470 sort -u "$nodedir/failed_requirements.${dbsuffix}.previous" > $tmpfile_old 2> /dev/null || :
471 fileedit_exists_old_lines "$tmpfile_old" "$tmpfile_new"
474 # ============= Actual operations of "show" command for a single list =============
475 database_query_show_single_list_exec ()
477 local subject deptag level dbsuffix flag_filter_skip_unchanged flag_filter_only_target pkgnamedb
481 dbsuffix=$deptag.$level
482 flag_filter_skip_unchanged=
483 flag_filter_only_target=
484 pkgnamedb='requires obsolete initial'
487 message_echo "The following ports remain in the (re)installation queue for the current do/redo process:"
488 message_echo "It is noted that ports to be skipped can be included here."
489 message_dependency_scope
491 list=stage.loop_list/reinst_todo.remain
492 [ ${DBDIR}/reinst_order.list -nt ${DBDIR}/$list ] && list=reinst_order.list
493 flag_filter_skip_unchanged=necessary_upgrade.$dbsuffix
494 flag_filter_only_target=y
497 message_echo "The following ports have been successfully (re)installed or newly installed:"
498 message_dependency_scope
500 list=success.$dbsuffix.list
501 flag_filter_skip_unchanged=necessary_upgrade_completed.$dbsuffix
502 flag_filter_only_target=y
505 message_echo "The following ports need (re)installation but are to be skipped until any of their failed requirements succeeds:"
506 message_dependency_scope
508 list=todo_after_requirements_succeed.$dbsuffix.list
509 flag_filter_skip_unchanged=necessary_upgrade.$dbsuffix
510 flag_filter_only_target=y
513 message_echo "The following ports had problems which have been manually resolved:"
515 list=manually_done.list
518 message_echo "The following ports experienced failures and kept to be old or uninstalled:"
520 database_query_show_list_failure
524 message_echo "The following ports are temporarily deleted due to conflicts:"
526 database_query_show_list_failed_conflicts_restoration
530 message_echo "The following ports are registered as taboo:"
535 message_echo "The following ports are registered as necessary:"
540 message_echo "The following ports are registered as unnecessary:"
545 message_echo "The following leaf, obsolete or unneeded ports had been once deleted but are to be or have been restored:"
547 list=stage.loop_list/ports_to_restore
548 pkgnamedb='obsolete initial'
549 flag_filter_only_target=y
552 message_echo "The following leaf, obsolete or unneeded ports are to be or have been deleted:"
554 list=stage.loop_list/ports_to_delete
555 pkgnamedb='obsolete initial'
556 flag_filter_only_target=y
559 database_query_show_single_list "$list" "$pkgnamedb" \
560 "$flag_filter_skip_unchanged" "$flag_filter_only_target"
563 # ============= Check whether a port is registered in a list =============
564 database_query_exists_in_list ()
566 local origin subject deptag level tmp_list dbsuffix origin_esc origin_ptn
571 tmp_list=${TMPDIR}/database_query_exists_in_list:list
572 dbsuffix=$deptag.$level
573 origin_esc=`str_escape_regexp "$origin"`
574 origin_ptn="^$origin_esc$"
577 list=stage.loop_list/reinst_todo.remain
578 [ ${DBDIR}/reinst_order.list -nt ${DBDIR}/$list ] && list=reinst_order.list
581 list=success.$dbsuffix.list
584 list=todo_after_requirements_succeed.$dbsuffix.list
587 list=manually_done.list
593 grep -v -E -f "${DBDIR}/ports_to_delete.grep_pattern_col1" "${DBDIR}/deleted_conflicts" 2> /dev/null \
594 | grep -q -E "^${origin_esc}[[:space:]]"
607 list=stage.loop_list/ports_to_restore
610 list=stage.loop_list/ports_to_delete
613 grep -q -E "$origin_ptn" "${DBDIR}/$list" 2> /dev/null