2 # ==============================================================================
3 # portsreinstall library script
4 # - Operations for building the temporary database -
5 # Copyright (C) 2013 Mamoru Sakaue, MwGhennndo, All Rights Reserved.
6 # This software is distributed under the 2-Clause BSD License.
7 # ==============================================================================
9 # ============= Variables =============
11 DATABASE_IS_OBSOLETE=no
13 # ============= Creation =============
14 database_build_create ()
16 [ `id -u` -eq 0 -a ! -d "${DBDIR}" ] && mkdir -p "${DBDIR}"
17 misc_lock_duplicated_executions "${DBDIR}/.lock"
18 if [ -e "${DBDIR}/MYVERSION" ]
20 if ! grep -m 1 -E "$COMPATIBLE_VERSIONS" "${DBDIR}/MYVERSION" > /dev/null 2>&1
22 message_echo "ERROR: The current temporary database is incompatible. You must delete it by" >&2
23 message_echo " ${APPNAME} clean force" >&2
24 message_echo " in order to enable the current version." >&2
27 elif misc_is_superuser_privilege
29 echo "$MYVERSION" > ${DBDIR}/MYVERSION
31 DATABASE_VERSION=`cat "${DBDIR}"/MYVERSION 2> /dev/null || :`
32 misc_is_superuser_privilege || return 0
33 for subdir in initial requires replace targets obsolete backup_packages \
34 stage.loop_list stage.complete stage.reinit_loop stage.depends
36 [ -d "${DBDIR}/$subdir" ] || mkdir -p "${DBDIR}/$subdir"
40 # ============= Refresh the temporary database =============
41 database_build_refresh ()
43 misc_is_superuser_privilege || return
44 [ $opt_suppress_obsolete_db_clean = no ] || return
45 message_echo "INFO: The temporary database is cleaned up."
47 [ -d "${DBDIR}" -a ! -d "${DBDIR}.tmp" ] && mv "${DBDIR}" "${DBDIR}.tmp"
49 mv "${DBDIR}.tmp/saved_options.sh" "${DBDIR}" 2> /dev/null || :
50 mv "${DBDIR}.tmp/backup_packages" "${DBDIR}" 2> /dev/null || :
51 mv "${DBDIR}.tmp/backup_pkgarcs.lst" "${DBDIR}" 2> /dev/null || :
55 # ============= Clean up the temporary database for upgrade of this utility =============
56 database_build_clean_for_self_upgrade ()
58 misc_is_superuser_privilege || return
59 [ $opt_suppress_obsolete_db_clean = no ] || return
62 [ -e "${DBDIR}/MYVERSION" ] && mv "${DBDIR}/MYVERSION" "${DBDIR}/MYVERSION.prev"
66 # ============= Check whether the temporary database is newer than the ports tree and refresh if so =============
67 database_build_refresh_if_obsolete ()
69 if [ "${PORTS_INDEX_DB}" -nt "${DBDIR}"/MYVERSION ] && misc_is_superuser_privilege
71 if [ $opt_suppress_obsolete_db_clean = no -a "z${command}" = zclean ]
73 DATABASE_IS_OBSOLETE=no
74 message_echo "WARNING: The temporary database is older than the ports tree." >&2
75 database_build_refresh || DATABASE_IS_OBSOLETE=yes
77 DATABASE_IS_OBSOLETE=yes
80 DATABASE_IS_OBSOLETE=no
84 # ============= Register an obsolete origin =============
85 database_build_register_obsolete_port ()
87 local origin dbpath pkgtag
89 dbpath=${DBDIR}/obsolete/$origin
90 [ -e "$dbpath/complete_as_node" ] && return
91 [ -d "${DBDIR}/obsolete/$origin" ] || mkdir -p "${DBDIR}/obsolete/$origin"
92 pkgtag=`pkgsys_pkg_info_qO_init "$origin"`
93 [ -n "$pkgtag" ] || pkgtag='[not installed]'
94 echo "$pkgtag" > ${DBDIR}/obsolete/$origin/pkgtag
95 for table in dependents requirements
97 for level in direct full
99 for tag in all run build
101 ln -f "${DBDIR}/initial/$origin/${table}.${tag}.${level}" "$dbpath/${table}.${tag}.${level}.src"
105 touch "$dbpath/complete_as_node"
108 # ============= Convert and register if an origin is obsolete =============
109 database_build_convert_and_register_origin_if_obsolete ()
111 local origin recursedb_in recursedb output_origin iline_db origin_new date_moved why_moved
114 recursedb=${recursedb_in:-${PORTS_MOVED_DB}}
115 echo "$origin" > ${TMPDIR}/database_build_convert_and_register_origin_if_obsolete:origin
116 [ -d "${PORTSDIR}/$origin" ] && return
117 database_build_register_obsolete_port "$origin"
118 grep -n -m 1 -E "^`str_escape_regexp \"$origin\"`\|" "$recursedb" 2> /dev/null > ${TMPDIR}/moved.info || :
119 if [ `wc -l < ${TMPDIR}/moved.info` -eq 0 ]
121 fileedit_add_a_line_if_new "$origin" "${DBDIR}/obsolete_ports"
122 if [ -n "$recursedb_in" ]
124 message_echo "${DEPTH_INDEX} ===> Disappeared port (MOVED broken?)"
126 message_echo "${DEPTH_INDEX} ===> Nonexistent port (your original?)"
130 iline_db=`cut -d : -f 1 "${TMPDIR}/moved.info"`
131 sed 1,${iline_db}d "${PORTS_MOVED_DB}" > ${TMPDIR}/MOVED.DB
132 origin_new=`sed -E 's/^[0-9]+://' "${TMPDIR}/moved.info" | cut -d '|' -f 2 || :`
133 date_moved=`cut -d '|' -f 3 "${TMPDIR}/moved.info" || :`
134 why_moved=`cut -d '|' -f 4 "${TMPDIR}/moved.info" || :`
135 if [ -n "$origin_new" ]
137 message_echo "${DEPTH_INDEX} ===> Moved to $origin_new at $date_moved because \"$why_moved\""
138 database_build_convert_and_register_origin_if_obsolete "$origin_new" "${TMPDIR}/MOVED.DB" || return 1
140 message_echo "${DEPTH_INDEX} ===> Deleted at $date_moved because \"$why_moved\""
141 fileedit_add_a_line_if_new "$origin" "${DBDIR}/obsolete_ports"
146 # ============= [Sub-function] Get the output value of converted origin =============
147 _database_build_convert_and_register_origin_if_obsolete__get_origin ()
149 cat "${TMPDIR}/database_build_convert_and_register_origin_if_obsolete:origin"
152 # ============= Get the make arguments for building the temporary database =============
153 database_build_setup_make_args ()
158 for key in LOCALBASE LINUXBASE PORT_DBDIR PORTSDIR DISTDIR PACKAGES PKGREPOSITORY
160 eval echo $key=\$$key
162 echo 'FORCE_PKG_REGISTER=yes'
163 echo 'DISABLE_VULNERABILITIES=yes'
164 [ $opt_apply_default_config = yes ] && echo 'BATCH=yes'
165 dbdir=${DBDIR}/requires/$origin
166 [ -d "$dbdir" ] || dbdir=${DBDIR}/conf/each_port/$origin
167 cat "$dbdir/MARG.conf" 2> /dev/null || :
171 # ============= Get the make environment variables for building the temporary database =============
172 database_build_setup_make_envs ()
176 dbdir=${DBDIR}/requires/$origin
177 [ -d "$dbdir" ] || dbdir=${DBDIR}/conf/each_port/$origin
178 cat "$dbdir/MENV.conf" 2> /dev/null || :
181 # ============= Execute make command for building the temporary database =============
182 database_build_make ()
184 local origin MAKE_ARGS MAKE_ENVS
187 MAKE_ARGS=`database_build_setup_make_args "$origin"`
188 MAKE_ENVS=`database_build_setup_make_envs "$origin"`
189 env $MAKE_ENVS make -C "${PORTSDIR}/$origin" "$@" $MAKE_ARGS
192 # ============= Set up a temporary database node for the initial state of a port =============
193 database_build_setup_initial_node ()
195 local origin pkg dbpath
197 dbpath=${DBDIR}/initial/$origin
198 [ -e "$dbpath/complete_as_node" ] && return
201 pkg=`pkg_info_qO "$origin"`
204 echo "$pkg" > $dbpath/installed_version
205 ln -f "$dbpath/installed_version" "$dbpath/pkgtag"
206 pkg_info_qr "$pkg" | while read requirement
208 origin_requirement=`pkgsys_init_pkg_orig_by_ambiguous_matching "$requirement" || :`
209 [ -n "$origin_requirement" ] && echo "$origin_requirement"
210 done > $dbpath/requirements.all.full
211 pkg_info_qR "$pkg" | while read dependent
213 origin_dependent=`pkgsys_init_pkg_orig_by_ambiguous_matching "$dependent" || :`
214 [ -n "$origin_dependent" ] && echo "$origin_dependent"
215 done > $dbpath/dependents.all.full
216 for table in dependents requirements
218 for level in direct full
220 for tag in all run build
222 [ "${tag}.${level}" = all.full ] && continue
223 ln -f "$dbpath/${table}.all.full" "$dbpath/${table}.${tag}.${level}"
228 if [ `expr "$pkg" : "^${APPNAME}-[0-9].*"` -gt 0 ]
230 [ -d "$dbpath" ] && touch "$dbpath/SUPPRESSED_SELF"
231 elif [ `expr "$pkg" : "^pkg-[0-9].*"` -gt 0 ]
233 [ -d "$dbpath" ] && touch "$dbpath/SUPPRESSED_PKGNG"
235 touch "$dbpath/complete_as_node"
238 # ============= Set up a temporary database node for the replaced/moved information of a port =============
239 database_build_setup_replace_node ()
241 local origin_orig origin dbpath
243 dbpath=${DBDIR}/replace/$origin_orig
244 if [ ! -e "$dbpath/complete_as_node" ]
249 if echo "$origin_orig" | grep -m 1 -E -f "${DBDIR}/conf/REPLACE.grep_from_pattern" > /dev/null
251 origin=`echo "$origin_orig" | sed -E -f "${DBDIR}/conf/REPLACE.sed_pattern"`
252 if [ "x$origin_orig" != "x$origin" ]
256 message_echo "${DEPTH_INDEX} ===> Replaced with $origin by user configuration"
258 database_build_register_obsolete_port "$origin_orig"
259 message_echo "${DEPTH_INDEX} ===> Deleted by user configuration"
265 if database_build_convert_and_register_origin_if_obsolete "$origin" >> $dbpath/message
267 origin=`_database_build_convert_and_register_origin_if_obsolete__get_origin`
269 if [ "x$origin" != "x$origin_orig" ]
271 message_echo "${DEPTH_INDEX} ===> Going back to the original port $origin_orig"
272 if database_build_convert_and_register_origin_if_obsolete "$origin_orig"
274 origin=`_database_build_convert_and_register_origin_if_obsolete__get_origin`
280 fi >> $dbpath/message
283 [ "x$origin_orig" = "x$origin" ] || echo "$origin" > $dbpath/origin
284 touch "$dbpath/complete_as_node"
286 cat "$dbpath/message" 2> /dev/null || :
289 # ============= Get the inspected level for a port with the current option settings =============
290 database_build_get_inspected_level ()
292 local origin origin_dependent origin_esc origin_dependent_esc
295 origin_esc='^'`str_escape_regexp "$origin"`'$'
296 origin_dependent_esc='^'`str_escape_regexp "$origin_dependent"`'$'
297 if [ $opt_only_target_scope = no ]
300 elif ! pkgsys_pkg_info_eO "$origin" \
301 || grep -E "$origin_esc" "${DBDIR}/stage.loop_list/ports_to_inspect" > /dev/null \
302 || [ ! -e "${DBDIR}/requires/$origin_dependent/installed_version" ] \
303 || grep -E "$origin_dependent_esc" "${DBDIR}/stage.loop_list/ports_to_inspect" > /dev/null
311 # ============= Check whether a port has been inspected in a required level =============
312 database_build_is_port_already_inspected_in_required_level ()
314 local origin origin_dependent origin_actual origin_esc inspected_level
317 origin_actual=`echo "$origin" | sed -E -f "${DBDIR}/REPLACE.complete_sed_pattern" 2> /dev/null || :`
318 [ -n "$origin_actual" ] || origin_actual=$origin
319 origin_esc='^'`str_escape_regexp "$origin_actual"`'$'
320 inspected_level=`database_build_get_inspected_level "$origin_actual" "$origin_dependent"`
321 grep -m 1 -E "^$origin_esc$" "${DBDIR}/ports.inspected.${inspected_level}.list" \
322 "${DBDIR}/obsolete_ports" > /dev/null 2>&1 || return
323 fileedit_rm_a_line "$origin" "${DBDIR}/stage.loop_list/ports_to_inspect.remain"
324 [ "x$origin" = "$origin_actual" ] || \
325 fileedit_rm_a_line "$origin_actual" "${DBDIR}/stage.loop_list/ports_to_inspect.remain"
329 # ============= Update the current package name of a port =============
330 database_build_update_pkgname ()
332 local origin pkg savefile
334 savefile=${DBDIR}/requires/$origin/current_version
335 pkg=`pkg_info_qO "$origin" || :`
336 if [ -z "$pkg" -a -e "${DBDIR}/requires/$origin/initial_orig" ]
338 origin_orig=`cat "${DBDIR}/requires/$origin/initial_orig"`
339 pkg=`pkg_info_qO "$origin_orig" || :`
341 echo -n "$pkg" > $savefile
345 # ============= Get the current package name of a port =============
346 database_build_get_pkgname ()
348 local origin savefile
350 savefile=${DBDIR}/requires/$origin/current_version
351 if [ -e "$savefile" ]
355 database_build_update_pkgname "$origin"
359 # ============= Get the new package name of a port =============
360 database_build_get_new_pkgname ()
362 local origin savefile pkg
364 savefile=${DBDIR}/requires/$origin/new_version
365 if [ ! -e "$savefile" ]
367 database_build_make "$origin" package-name \
368 | tr -d '\n' > $savefile
373 # ============= Build the original message tag showing the version upgrade =============
374 database_build_create_pkgtag ()
376 local origin dbdir pkg_init pkg_new pkgtag
378 dbdir=${DBDIR}/requires/$origin
379 pkg_init=`database_build_get_pkgname "$origin"`
380 [ -n "$pkg_init" -a ! -e "$dbdir/installed_version" ] && \
381 echo -n "$pkg_init" > $dbdir/installed_version
382 pkg_new=`database_build_get_new_pkgname "$origin"`
384 [ -n "$pkgtag" ] || pkgtag=$pkg_new
389 elif [ "x$pkg_init" != "x$pkg_new" ]
391 if [ -n "$pkg_init" ]
393 pkgtag="$pkg_init => $pkg_new"
395 pkgtag="[new] $pkg_new"
398 echo "$pkgtag" > $dbdir/pkgtag.orig
399 echo "$pkgtag" > $dbdir/pkgtag
402 # ============= Update the message tag showing the version upgrade =============
403 database_build_update_pkgtag ()
405 local origin pkg_init pkg_bak pkg_cur detail pkgtag
407 pkg_init=`cat "${DBDIR}/requires/$origin/installed_version" 2> /dev/null || :`
408 pkg_bak=`cat "${DBDIR}/requires/$origin/backedup_version" 2> /dev/null || :`
409 pkg_cur=`database_build_get_pkgname "$origin"`
411 if [ "x$pkg_init" != "x$pkg_cur" ]
415 detail=" [currently installed version: $pkg_cur]"
416 elif [ -n "$pkg_bak" ]
418 detail=" [currently deinstalled, previously installed version: $pkg_bak]"
420 detail=" [currently deinstalled]"
423 pkgtag=`cat "${DBDIR}/requires/$origin/pkgtag.orig"`
424 echo "$pkgtag$detail" > ${DBDIR}/requires/$origin/pkgtag
427 # ============= Check whether the currently installed package version is the latest =============
428 database_build_is_currentpkg_latest ()
430 local origin pkg_cur pkg_new
432 pkg_cur=`database_build_get_pkgname "$origin"`
433 pkg_new=`database_build_get_new_pkgname "$origin"`
434 [ "x$pkg_cur" = "x$pkg_new" ]
437 # ============= Recursively inspect dependencies of a port and build a node database of the information =============
438 database_build_inspect_dependencies ()
440 local origin_orig origin_dependent origin_orig_regexp origin origin_regexp tag stage dbpath origin_id origin_dependency DEPTH_INDEX_orig nlines iline dist_subdir_rpl inspected_level inspected_levels_compatible origin_tmp inspected_level_tmp conf_updated
443 [ -z "$origin_orig" ] && return
444 database_build_is_port_already_inspected_in_required_level "$origin_orig" "$origin_dependent" && return
445 origin_orig_regexp=`str_escape_regexp "$origin_orig"`
446 DEPTH_INDEX_orig=${DEPTH_INDEX}
447 DEPTH_INDEX="${DEPTH_INDEX}--"
448 message_echo "${DEPTH_INDEX} $origin_orig"
449 origin_id=`echo "$origin_orig" | tr / :`
450 database_build_setup_initial_node "$origin_orig"
451 database_build_setup_replace_node "$origin_orig"
452 if [ -e "${DBDIR}/replace/$origin_orig/origin" ]
454 origin=`cat "${DBDIR}/replace/$origin_orig/origin"`
458 origin_regexp=`str_escape_regexp "$origin"`
460 inspected_levels_compatible=
463 fileedit_rm_a_line "$origin" "${DBDIR}/obsolete_ports"
464 dbpath=${DBDIR}/requires/$origin
465 if [ ! -e "$dbpath/complete_as_node" ]
468 if grep -m 1 -E -e "^$origin_orig_regexp$" -e "^$origin_regexp$" "${DBDIR}/to_be_reconf" > /dev/null 2>&1
470 message_echo "${DEPTH_INDEX} ===> Reconfigured"
475 [ -n "$conf_updated" ] && touch "$dbpath/conf_updated"
476 [ "x$origin_orig" = "x$origin" ] || echo "$origin_orig" > $dbpath/initial_orig
477 [ -e "${DBDIR}/initial/$origin_orig/SUPPRESSED_SELF" ] && touch "$dbpath/SUPPRESSED_SELF"
478 [ -e "${DBDIR}/initial/$origin_orig/SUPPRESSED_PKGNG" ] && touch "$dbpath/SUPPRESSED_PKGNG"
479 if [ -d "${DBDIR}/conf/each_port/$origin" ]
481 cp -R "${DBDIR}/conf/each_port/$origin/"* "$dbpath/" > /dev/null 2>&1 || :
483 tmp_portsdb_work=${TMPDIR}/database_build_inspect_dependencies:portsdb_work
484 [ -d "$tmp_portsdb_work" ] || mkdir "$tmp_portsdb_work"
486 export PORT_DBDIR=$tmp_portsdb_work
487 database_build_make "$origin" showconfig > $dbpath/ports_options.default
489 if [ `wc -c < $dbpath/ports_options.default` -gt 0 ]
491 if [ $opt_apply_default_config = yes ]
493 if pkgsys_is_dialog4ports_used
497 message_echo "ERROR: script(1) prevents automatic configurations of port options via dialog4ports(1) (at least found for dialog4ports-0.1.3)." >&2
498 message_echo "If you want to enable the automatic configurations, rerun outside of script(1) environment at least until the end of section [Inspecting dependencies of the all installed packages]." >&2
499 message_echo "If you can accept interactive configurations, disable -C option with the aid of -M option." >&2
502 printf '\n' | database_build_make "$origin" config-conditional
504 printf '\t\n' | database_build_make "$origin" config-conditional > /dev/null
507 database_build_make "$origin" config-conditional
509 database_build_make "$origin" showconfig > $dbpath/ports_options.current
511 cp /dev/null "$dbpath/ports_options.current"
513 if [ ! -e "${DBDIR}/initial/$origin_orig/installed_version" ]
515 cp "${DBDIR}/initial/$origin_orig/installed_version" "$dbpath" 2> /dev/null || :
517 database_build_create_pkgtag "$origin"
518 # for tag in all run build
521 database_build_make "$origin" $tag-depends-list \
522 | sed -E "s/^`str_escape_regexp "${PORTSDIR}"`\///" \
523 > $dbpath/requirements.$tag.orig || :
524 sed -E -f "${DBDIR}/conf/REPLACE.sed_pattern" "$dbpath/requirements.$tag.orig" \
525 | grep -v '^$' > $dbpath/requirements.$tag.src || :
527 for stage in orig src
529 sort -u "$dbpath/requirements.run.${stage}" "$dbpath/requirements.build.${stage}" \
530 > $dbpath/requirements.all.direct.${stage}
531 # mv "$dbpath/requirements.all.${stage}" "$dbpath/requirements.all.full.${stage}"
532 mv "$dbpath/requirements.build.${stage}" "$dbpath/requirements.build.direct.${stage}"
533 mv "$dbpath/requirements.run.${stage}" "$dbpath/requirements.run.direct.${stage}"
535 # grep -E -f "${DBDIR}/conf/REPLACE.grep_from_pattern" "$dbpath/requirements.all.full.orig" \
536 # | grep -v -E "^`str_escape_regexp \"$origin\"`$" \
537 # | fileedit_add_lines_if_new "${DBDIR}/replaced_dest_ports.list" || :
538 touch "$dbpath/complete_as_node"
539 fileedit_rm_a_line "$origin_orig" "${DBDIR}/to_be_reconf"
540 fileedit_rm_a_line "$origin" "${DBDIR}/to_be_reconf"
542 for level in direct full
546 rm -f "$dbpath/requirements.${tag}.${level}"
549 for origin_tmp in "$origin" "$origin_orig"
551 for inspected_level_tmp in full direct node
553 fileedit_rm_a_line "$origin_tmp" "${DBDIR}/ports.inspected.${inspected_level_tmp}.list"
557 inspected_level=`database_build_get_inspected_level "$origin" "$origin_dependent"`
558 case $inspected_level in
560 # grep -v -E -f "${DBDIR}/installed_ports.grep_pattern" \
561 # "$dbpath/requirements.all.full.src" > ${TMPDIR}/missing.$origin_id || :
562 grep -v -E -f "${DBDIR}/installed_ports.grep_pattern" \
563 "$dbpath/requirements.all.direct.src" > ${TMPDIR}/missing.$origin_id || :
564 inspected_levels_compatible='full direct node'
567 grep -v -E -f "${DBDIR}/installed_ports.grep_pattern" \
568 "$dbpath/requirements.all.direct.src" > ${TMPDIR}/missing.$origin_id || :
569 # cp "$dbpath/requirements.all.direct.src" "${TMPDIR}/missing.$origin_id"
570 inspected_levels_compatible='direct node'
573 cp /dev/null "${TMPDIR}/missing.$origin_id"
574 inspected_levels_compatible='node'
577 nlines=`wc -l < ${TMPDIR}/missing.$origin_id`
579 while [ $iline -le $nlines ]
581 origin_dependency=`sed -n ${iline}p "${TMPDIR}/missing.$origin_id"`
583 grep -m 1 -E '^'`str_escape_regexp "$origin_dependency"`'$' \
584 "${DBDIR}/ports.inspected.list" > /dev/null 2>&1 && \
586 database_build_inspect_dependencies "$origin_dependency" "$origin"
588 rm -f "${TMPDIR}/missing.$origin_id"
589 dist_subdir_rpl=`database_query_get_makevar_val "$origin" DIST_SUBDIR | str_escape_replaceval_filter` || :
590 [ -n "$dist_subdir_rpl" ] && dist_subdir_rpl="$dist_subdir_rpl\/"
591 database_build_make "$origin" fetch-urlall-list \
592 | sed -E "s/.*\/([^\/]+)$/$dist_subdir_rpl\1/" \
593 | sort -u >> ${DBDIR}/distfiles.inspected
595 if [ "x$origin_orig" != "x$origin" ]
599 for inspected_level_tmp in $inspected_levels_compatible
601 fileedit_add_a_line_if_new "$origin" "${DBDIR}/ports.inspected.${inspected_level_tmp}.list"
603 fileedit_add_a_line_if_new "$origin" "${DBDIR}/ports.inspected.list"
604 fileedit_add_a_line_if_new "$origin" "${DBDIR}/inspected_ports.update"
605 fileedit_rm_a_line "$origin" "${DBDIR}/stage.loop_list/ports_to_inspect.remain"
608 for inspected_level_tmp in $inspected_levels_compatible
610 fileedit_add_a_line_if_new "$origin_orig" "${DBDIR}/ports.inspected.${inspected_level_tmp}.list"
612 fileedit_add_a_line_if_new "$origin_orig" "${DBDIR}/ports.inspected.list"
613 fileedit_add_a_line_if_new "$origin_orig" "${DBDIR}/inspected_ports.update"
614 fileedit_rm_a_line "$origin_orig" "${DBDIR}/stage.loop_list/ports_to_inspect.remain"
615 message_echo "${DEPTH_INDEX} ===> ok"
617 DEPTH_INDEX=${DEPTH_INDEX_orig}
620 # ============= Build and get a list of the complete recursive dependencies of a port =============
621 database_build_get_complete_recursive_dependency ()
623 local table origin dbpath dstfile
626 dbpath=${DBDIR}/requires/$origin
627 [ -e "$dbpath/$table.direct" ] || return 0
628 dstfile=$dbpath/$table.full
629 if [ ! -e "$dbpath/$table" -a ! -e "$dstfile" ]
631 while read origin_requirement
633 echo "$origin_requirement"
634 database_build_get_complete_recursive_dependency "$table" "$origin_requirement"
635 done < $dbpath/$table.direct | sort -u > $dstfile.tmp
636 mv "$dstfile.tmp" "$dstfile"
641 # ============= Inspect the necessity of requirements of a necessary port even in case of skipping unchanged ports =============
642 # Here the "necessity" means that a port must be kept installed, newly installed or reinstalled for run- or build-time operations.
643 # In other words, "unnecessary" ports are what are not yet installed and not required by any "necessary" ports neither in run- or build-time.
644 database_build_inspect_necessity_for_only_new_upgrade ()
646 local origin level dbpath tmpfile
649 dbpath=${DBDIR}/requires/$origin
650 [ -e "$dbpath/necessary_port.${level}" ] && return
651 tmpfile=${TMPDIR}/database_build_inspect_necessity_for_only_new_upgrade:`echo "$origin" | tr / :`
652 if database_query_does_a_port_need_update "$origin"
654 sort -u "$dbpath/requirements.build.direct" "$dbpath/requirements.run.${level}" || :
656 cat "$dbpath/requirements.run.${level}" || :
657 fi 2> /dev/null > $tmpfile
658 if [ `wc -l < $tmpfile` -gt 0 ]
660 while read origin_requirement
662 database_build_inspect_necessity_for_only_new_upgrade "$origin_requirement" "$level"
666 touch "$dbpath/necessary_port.${level}"
669 # ============= Build complement relations to new dependents for targets recursively =============
670 database_build_complement_to_new_dependents_for_targets ()
672 local origin dbdir reqdir level
674 dbdir=${DBDIR}/targets/$origin
675 reqdir=${DBDIR}/requires/$origin
676 [ -d "$dbdir" ] || return 0
677 echo "$origin" >> ${DBDIR}/stage.loop_list/parse_target_attr_info
678 if [ -e "$dbdir/target_itself" ] && database_query_does_a_port_need_update "$origin"
680 for level in direct full
682 cat "$reqdir/requirements.all.${level}" 2> /dev/null | while read origin_requirement
684 fileedit_add_a_line_if_new "$origin" \
685 "${DBDIR}/targets/$origin_requirement/complement_for_new_dependents.${level}"
688 cat "$reqdir/requirements.all.direct" "$reqdir/requirements.all.full" 2> /dev/null \
689 | sort -u | while read origin_requirement
691 database_build_complement_to_new_dependents_for_targets "$origin_requirement"
696 # ============= Build target attribute files recursively =============
697 database_build_target_attributes ()
699 local origin dbdir reqdir _is_target _is_requires_requirements _is_initial_requirements _is_requires_dependents _is_initial_dependents _is_requires_requirements_complement _is_relevant tag level database table
701 dbdir=${DBDIR}/targets/$origin
702 reqdir=${DBDIR}/requires/$origin
703 [ -d "$dbdir" ] || return 0
704 [ -e "$dbdir/COMPLETE_ATTRS" ] && return
706 [ -e "$dbdir/target_itself" ] && _is_target=y
707 for tag in all run build none
709 for level in direct full
711 _is_relevant=${_is_target}
712 _is_requires_requirements=
713 _is_initial_requirements=
714 _is_requires_dependents=
715 _is_initial_dependents=
716 _is_requires_requirements_complement=
717 for database in requires initial
719 for table in requirements dependents
721 if [ -e "$dbdir/target_${database}_${table}.${tag}.${level}" ]
723 eval _is_${database}_${table}=y
728 if [ -z "${_is_requires_requirements}" -a -e "$dbdir/complement_for_new_dependents.${level}" ]
730 _is_requires_requirements_complement=y
733 [ -n "${_is_relevant}" ] && cat > $dbdir/attrs.${tag}.${level} << eof
734 _is_target=${_is_target}
735 _is_requires_requirements=${_is_requires_requirements}
736 _is_initial_requirements=${_is_initial_requirements}
737 _is_requires_dependents=${_is_requires_dependents}
738 _is_initial_dependents=${_is_initial_dependents}
739 _is_requires_requirements_complement=${_is_requires_requirements_complement}
743 touch "$dbdir/COMPLETE_ATTRS"
744 # local origin dbdir reqdir _is_all _is_target _is_requires_requirements _is_initial_requirements _is_requires_dependents _is_initial_dependents _is_requires_requirements_complement _is_relevant tag level database table
747 # _is_requires_requirements=
748 # _is_initial_requirements=
749 # _is_requires_dependents=
750 # _is_initial_dependents=
752 # origin_esc=`str_escape_regexp "$origin"`
753 # target_${database}_${table}.${tag}.${level}
754 # if [ `cat "${DBDIR}/stage.loop_list/target_requirements.specified" 2> /dev/null | wc -l` -gt 0 ]
756 # if [ -e "$nodedir_req/installed_version" ]
758 # deptag=`options_get_dependency_type`
763 # if grep -m 1 -E "^$origin_esc$" \
764 # "${DBDIR}/stage.loop_list/target_requirements.specified" > /dev/null 2>&1
767 # elif [ -e "$nodedir_req/dependents.$deptag.pattern" ] && \
768 # grep -m 1 -E -f "$nodedir_req/dependents.$deptag.pattern" \
769 # "${DBDIR}/stage.loop_list/target_requirements.specified" > /dev/null 2>&1
771 # _is_requires_requirements=y
772 # elif [ -e "$nodedir_ini/dependents.$deptag.pattern" ] && \
773 # grep -m 1 -E -f "$nodedir_ini/dependents.$deptag.pattern" \
774 # "${DBDIR}/stage.loop_list/target_requirements.specified" > /dev/null 2>&1
776 # _is_initial_requirements=y
779 # if [ `cat "${DBDIR}/stage.loop_list/target_dependents.specified" 2> /dev/null | wc -l` -gt 0 ]
781 # deptag=`options_get_dependency_type`
783 # if [ -n "${_is_target}" ] \
784 # || grep -m 1 -E "^$origin_esc$" "${DBDIR}/stage.loop_list/target_dependents.specified" \
788 # elif [ -e "$nodedir_req/requirements.$deptag.pattern" ] && \
789 # grep -m 1 -E -f "$nodedir_req/requirements.$deptag.pattern" \
790 # "${DBDIR}/stage.loop_list/target_dependents.specified" > /dev/null 2>&1
792 # _is_requires_dependents=y
793 # elif [ -e "$nodedir_ini/requirements.$deptag.pattern" ] && \
794 # grep -m 1 -E -f "$nodedir_ini/requirements.$deptag.pattern" \
795 # "${DBDIR}/stage.loop_list/target_dependents.specified" > /dev/null 2>&1
797 # _is_initial_dependents=y
803 # ============= Order the ports considering dependencies =============
804 database_build_order_ports_considering_dependencies ()
806 touch "${DBDIR}/reinst_order.list.tmp"
807 cat > ${TMPDIR}/order_dependencies.awk << eof
822 sub (/\/requirements.all\.full$/, "", target);
823 sub (/^\.\//, "", target);
824 srcikey[it] = target;
825 srckeyi[target] = it;
831 srcimax[it-1] = srcsize[it-1] = i;
845 for (it = 0; it < ntargets; it++)
847 if (!(it in srcikey)) continue;
848 if (srcsize[it] > 0) continue;
850 target = srcikey[it];
851 # print "[" icycle "]-- " target;
853 order[norder++] = target;
854 order_str = order_str lf_order_str;
855 order_str = sprintf ("%s%s", order_str, target);
857 for (jt = 0; jt < ntargets; jt++)
859 for (j = 0; j < srcimax[jt]; j++)
861 if ((jt,j) in src && src[jt,j] == target)
870 if (is_operated == 0) break;
873 reinst_order_list = sprintf ("%s%s", ENVIRON["DBDIR"], "/reinst_order.list.tmp");
874 print order_str > reinst_order_list;
876 for (it = 0; it < ntargets; it++)
878 if (srcsize[it] == 0) continue;
881 for (i = 0; i < srcimax[it]; i++)
885 reqs = reqs sp_reqs src[it,i];
889 unsatisfied = sprintf ("%s%s [%d] (%s)\n", unsatisfied, srcikey[it], srcsize[it], reqs);
891 if (unsatisfied != "")
893 unsatisfied_list = sprintf ("%s%s", ENVIRON["DBDIR"], "/unsatisfied.list");
894 print unsatisfied > unsatisfied_list;
899 (cd "${DBDIR}/requires" && \
900 find . -depth 3 -name requirements.all.full -exec echo {} \; -exec cat {} \; -exec echo \;) | \
901 env "DBDIR=${DBDIR}" awk -f "${TMPDIR}"/order_dependencies.awk || return
902 grep -v '^$' "${DBDIR}/reinst_order.list.tmp" > "${DBDIR}/reinst_order.list" || :
905 # ============= [Sub-function] Common operations for resetting configurations for a port =============
906 _database_build_reset_a_port_confdb ()
908 local origin origin_replace db
910 [ -d "${DBDIR}/initial/$origin" -o -d "${DBDIR}/replace/$origin" \
911 -o -d "${DBDIR}/requires/$origin" -o -d "${DBDIR}/targets/$origin" ] || return 0
912 touch "${DBDIR}/inspected_ports_only_partially"
915 cat "${DBDIR}/replace/$origin/origin" 2> /dev/null || :
916 for dbtag in initial requires
918 for tabel in requirements dependents
920 cat "${DBDIR}/$dbtag/$origin/$tabel.all.full" 2> /dev/null || :
921 rm -f "${DBDIR}/$dbtag/$origin/$tabel.run.full" \
922 "${DBDIR}/$dbtag/$origin/$tabel.build.full" 2> /dev/null
925 } | sort -u >> ${DBDIR}/inspected_ports.update
926 for level in full direct node
928 fileedit_rm_a_line "$origin" "${DBDIR}/ports.inspected.${level}.list"
930 fileedit_rm_a_line "$origin" "${DBDIR}/obsolete_ports"
931 fileedit_rm_a_line "$origin" "${DBDIR}/ports.inspected.list"
932 cat "${DBDIR}/replace/$origin/origin" 2> /dev/null || :
933 # if [ ! -d "${PORTSDIR}/$origin" ] || \
934 # echo "$origin" | grep -m 1 -E -f "${DBDIR}/conf/REPLACE.grep_from_pattern" > /dev/null
936 # rm -rf "${DBDIR}/requires/$origin"
938 # rm -f "${DBDIR}/requires/$origin/complete_as_node"
942 # ============= Remove configurations for a port permanently =============
943 database_build_forget ()
945 local origin origin_replace db
947 origin_replace=`_database_build_reset_a_port_confdb "$origin"`
948 # [ -d "${DBDIR}/initial/$origin" -o -d "${DBDIR}/replace/$origin" \
949 # -o -d "${DBDIR}/requires/$origin" -o -d "${DBDIR}/targets/$origin" ] || return 0
950 # touch "${DBDIR}/inspected_ports_only_partially"
953 # cat "${DBDIR}/replace/$origin/origin" || :
954 # for dbtag in initial requires
956 # for tabel in requirements dependents
958 # cat "${DBDIR}/$dbtag/$origin/$tabel.all.full" || :
959 # rm -f "${DBDIR}/$dbtag/$origin/$tabel.run.full" \
960 # "${DBDIR}/$dbtag/$origin/$tabel.build.full"
963 # } 2> /dev/null | sort -u >> ${DBDIR}/inspected_ports.update
964 # for level in full direct node
966 # fileedit_rm_a_line "$origin" "${DBDIR}/ports.inspected.${level}.list"
968 # fileedit_rm_a_line "$origin" "${DBDIR}/obsolete_ports"
969 # fileedit_rm_a_line "$origin" "${DBDIR}/ports.inspected.list"
970 # fileedit_add_a_line_if_new "$origin" "${DBDIR}/stage.loop_list/ports_to_inspect.remain"
971 # fileedit_add_a_line_if_new "$origin" "${DBDIR}/to_be_reconf"
972 # origin_replace=`cat "${DBDIR}/replace/$origin/origin" 2> /dev/null` || :
973 # if [ ! -d "${PORTSDIR}/$origin" ] || \
974 # echo "$origin" | grep -m 1 -E -f "${DBDIR}/conf/REPLACE.grep_from_pattern" > /dev/null
976 # rm -rf "${DBDIR}/requires/$origin"
978 # rm -f "${DBDIR}/requires/$origin/complete_as_node"
980 # for db in replace targets obsolete
982 # rm -rf "${DBDIR}/$db/$origin"
984 fileedit_rm_a_line "$origin" "${DBDIR}/targets_specified_so_far"
985 [ -z "$origin_replace" ] || database_build_forget "$origin_replace"
986 for db in requires replace targets obsolete
988 rm -rf "${DBDIR}/$db/$origin"
992 # ============= Patch to the temporary database so as to re-inspect and reinstall ports whose configurations were changed =============
993 database_build_patch_reconf ()
995 local origin origin_replace
996 # local origin origin_replace db
998 origin_replace=`_database_build_reset_a_port_confdb "$origin"`
999 # [ -d "${DBDIR}/initial/$origin" -o -d "${DBDIR}/replace/$origin" \
1000 # -o -d "${DBDIR}/requires/$origin" -o -d "${DBDIR}/targets/$origin" ] || return 0
1001 # touch "${DBDIR}/inspected_ports_only_partially"
1004 # cat "${DBDIR}/replace/$origin/origin" || :
1005 # for dbtag in initial requires
1007 # for tabel in requirements dependents
1009 # cat "${DBDIR}/$dbtag/$origin/$tabel.all.full" || :
1010 # rm -f "${DBDIR}/$dbtag/$origin/$tabel.run.full" \
1011 # "${DBDIR}/$dbtag/$origin/$tabel.build.full"
1014 # } 2> /dev/null >> ${DBDIR}/inspected_ports.update
1015 # for level in full direct node
1017 # fileedit_rm_a_line "$origin" "${DBDIR}/ports.inspected.${level}.list"
1019 # fileedit_rm_a_line "$origin" "${DBDIR}/obsolete_ports"
1020 # fileedit_rm_a_line "$origin" "${DBDIR}/ports.inspected.list"
1021 [ -d "${DBDIR}/initial/$origin" -o -d "${DBDIR}/requires/$origin" ] && \
1022 fileedit_add_a_line_if_new "$origin" "${DBDIR}/stage.loop_list/ports_to_inspect"
1023 fileedit_add_a_line_if_new "$origin" "${DBDIR}/to_be_reconf"
1024 # origin_replace=`cat "${DBDIR}/replace/$origin/origin" 2> /dev/null` || :
1025 # if [ ! -d "${PORTSDIR}/$origin" ] || \
1026 # echo "$origin" | grep -m 1 -E -f "${DBDIR}/conf/REPLACE.grep_from_pattern" > /dev/null
1028 # rm -rf "${DBDIR}/requires/$origin"
1030 # rm -f "${DBDIR}/requires/$origin/complete_as_node"
1032 # for db in replace targets obsolete
1034 # rm -rf "${DBDIR}/$db/$origin"
1036 [ -z "$origin_replace" ] || database_build_patch_reconf "$origin_replace"
1037 for db in requires replace targets obsolete
1039 rm -rf "${DBDIR}/$db/$origin"
1043 # ============= Post`processes after finishing to inspect dependencies =============
1044 database_build_post_inspect_dependencies ()
1046 touch "${DBDIR}/obsolete_ports" "${DBDIR}/inspected_ports.update"
1047 find "${DBDIR}/requires" -depth 2 -type d \
1048 | sed -E 's|.*/([^/]+/[^/]+)$|\1|' > ${DBDIR}/inspected_ports
1049 find "${DBDIR}/initial" -depth 2 -type d \
1050 | sed -E 's|.*/([^/]+/[^/]+)$|\1|' > ${DBDIR}/inspected_ports.initial
1051 sort -u "${DBDIR}/inspected_ports" "${DBDIR}/inspected_ports.initial" > ${DBDIR}/inspected_ports.all
1052 str_escape_regexp_filter < ${DBDIR}/inspected_ports \
1053 | sed 's/^/^/; s/$/$/' > ${DBDIR}/inspected_ports.grep_pattern
1054 str_escape_regexp_filter < ${DBDIR}/inspected_ports.initial \
1055 | sed 's/^/^/; s/$/$/' > ${DBDIR}/inspected_ports.initial.grep_pattern
1056 str_escape_regexp_filter < ${DBDIR}/inspected_ports.all \
1057 | sed 's/^/^/; s/$/$/' > ${DBDIR}/inspected_ports.all.grep_pattern
1058 cat "${DBDIR}/conf/HOLD_PORTS.grep_pattern" "${DBDIR}/need.grep_pattern" \
1059 2> /dev/null > ${TMPDIR}/INSPECT_ALL_DEPENDENCIES:obsolete_ports.exclude.grep_pattern || :
1060 grep -v -E -f "${TMPDIR}/INSPECT_ALL_DEPENDENCIES:obsolete_ports.exclude.grep_pattern" \
1061 "${DBDIR}/obsolete_ports" > ${DBDIR}/obsolete_ports.can_be_deleted || :
1062 cp /dev/null "${DBDIR}/REPLACE.complete_sed_pattern.tmp"
1063 cp /dev/null "${DBDIR}/REVERSE_REPLACE.complete_sed_pattern.tmp"
1064 find "${DBDIR}/replace" -depth 3 -type f -name origin | while read nodepath
1066 origin_orig=`expr "$nodepath" : '.*/\([^/][^/]*/[^/][^/]*\)/origin$'`
1067 origin=`cat "$nodepath"`
1068 origin_orig_regexp=`str_escape_regexp "$origin_orig"`
1069 origin_orig_esc=`str_escape_replaceval "$origin_orig"`
1070 origin_regexp=`str_escape_regexp "$origin"`
1071 origin_esc=`str_escape_replaceval "$origin"`
1072 echo "s/^$origin_orig_regexp$/$origin_esc/" >> ${DBDIR}/REPLACE.complete_sed_pattern.tmp
1073 echo "s/^$origin_regexp$/$origin_orig_esc/" >> ${DBDIR}/REVERSE_REPLACE.complete_sed_pattern.tmp
1075 mv "${DBDIR}/REPLACE.complete_sed_pattern.tmp" "${DBDIR}/REPLACE.complete_sed_pattern"
1076 mv "${DBDIR}/REVERSE_REPLACE.complete_sed_pattern.tmp" "${DBDIR}/REVERSE_REPLACE.complete_sed_pattern"
1077 if [ `cat "${DBDIR}/inspected_ports.update" 2> /dev/null | wc -l` -gt 0 ]
1079 grep -E -f "${DBDIR}/inspected_ports.all.grep_pattern" "${DBDIR}/inspected_ports.update" \
1080 > ${DBDIR}/inspected_ports.update.tmp || :
1081 mv "${DBDIR}/inspected_ports.update.tmp" "${DBDIR}/inspected_ports.update"
1082 if [ $opt_only_target_scope = yes ]
1084 touch "${DBDIR}/inspected_ports_only_partially"
1086 rm -f "${DBDIR}/inspected_ports_only_partially"
1088 if program_chk_stage_loop_complete CONVERT_REQUIREMENTS_LIST
1090 mv "${DBDIR}/inspected_ports.update" "${DBDIR}/stage.loop_list/convert_dependency_lists"
1092 cat "${DBDIR}/inspected_ports.update" "${DBDIR}/stage.loop_list/convert_dependency_lists" \
1093 2> /dev/null | sort -u > ${DBDIR}/stage.loop_list/convert_dependency_lists.tmp
1094 mv "${DBDIR}/stage.loop_list/convert_dependency_lists.tmp" "${DBDIR}/stage.loop_list/convert_dependency_lists"
1095 rm -f "${DBDIR}/inspected_ports.update"
1098 program_chk_stage_loop_complete CONVERT_REQUIREMENTS_LIST && rm -f "${DBDIR}/stage.loop_list/convert_dependency_lists"
1100 cp /dev/null "${DBDIR}/update_dependencies"
1103 # # ============= Remove configurations for a port with its requirements permanently unless initially installed =============
1104 # database_build_rm_new_port_conf ()
1106 # local origin src_scope dst_dependents dst_requirements origin_orig
1110 # dst_requirements=$4
1111 # if [ -e "${DBDIR}/REVERSE_REPLACE.complete_sed_pattern" ]
1113 # origin_orig=`echo "$origin" | sed -E -f "${DBDIR}/REVERSE_REPLACE.complete_sed_pattern"`
1115 # origin_orig=$origin
1117 # if [ -n "$dst_requirements" ]
1119 # cat "${DBDIR}/requires/$origin/requirements.all.full" 2> /dev/null >> $dst_requirements || :
1121 # if [ -n "$dst_dependents" ]
1123 # cat "${DBDIR}/requires/$origin/dependents.all.full" 2> /dev/null >> $dst_dependents || :
1125 # if [ -e "${DBDIR}/initial/$origin/installed_version" -o -e "${DBDIR}/initial/$origin_orig/installed_version" ]
1127 # message_echo "$origin (reset)"
1128 # database_build_patch_reconf "$origin"
1130 # message_echo "$origin (removed)"
1131 # database_build_forget "$origin"