Add the necessary code to uninstall packages (re-install still pending).
Both scripted access (packageDelete) and UI access have been tested successfully with a variation of different situations including: + Uninstall a package which no other installed package depends + Uninstall multiple packages which no other installed packages depend + Uninstall multiple packages which depend on each other + Similar to above but when ordered removal requires tracing dependencies + Purposefully do things like uninstall a package that is not installed + Try to uninstall a package which other installed packages still depend + Try to uninstall multiple packages which other installed packages depend + And many more.
This commit is contained in:
parent
12a9a52070
commit
542dd84bad
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=252775
@ -255,6 +255,9 @@ msg_ok="OK"
|
||||
msg_options="Options"
|
||||
msg_options_editor="Options Editor"
|
||||
msg_other="other"
|
||||
msg_pkg_delete_failed="Warning: pkg_delete of %s failed.\n Run with debugging for details."
|
||||
msg_package_is_needed_by_other_installed_packages="Warning: Package %s is needed by\n %d other installed package%s."
|
||||
msg_package_not_installed_cannot_delete="Warning: package %s not installed\n No package can be deleted."
|
||||
msg_package_read_successfully_waiting_for_pkg_add="Package %s read successfully - waiting for pkg_add(1)"
|
||||
msg_package_temp="Package Temp"
|
||||
msg_package_was_added_successfully="Package %s was added successfully"
|
||||
@ -376,6 +379,7 @@ msg_unable_to_make_directory_mountpoint="Unable to make %s directory mountpoint
|
||||
msg_unable_to_open="Unable to open %s"
|
||||
msg_uninstall="Uninstall"
|
||||
msg_uninstall_desc="Mark this package for deletion"
|
||||
msg_uninstalling_package_waiting_for_pkg_delete="Uninstalling %s package - waiting for pkg_delete(1)"
|
||||
msg_unknown="unknown"
|
||||
msg_unknown_user="Unknown user: %s"
|
||||
msg_url_was_not_found="%s was not found, maybe directory or release-version are wrong?"
|
||||
|
@ -656,7 +656,7 @@ f_package_review()
|
||||
debug= f_getvar _mark_$varpkg mark
|
||||
[ "$mark" = "U" ] || continue
|
||||
f_dprintf "%s: Uninstalling %s package" $fname "$package"
|
||||
# XXX Uninstall package
|
||||
f_package_delete "$package" || continue
|
||||
f_package_deselect "$package"
|
||||
done
|
||||
|
||||
@ -1057,6 +1057,135 @@ f_package_extract()
|
||||
return $SUCCESS
|
||||
}
|
||||
|
||||
# f_package_delete $name
|
||||
#
|
||||
# Delete package by full $name (lacks archive suffix; e.g., `.tbz').
|
||||
#
|
||||
f_package_delete()
|
||||
{
|
||||
local name="$1"
|
||||
local fname=f_package_delete
|
||||
|
||||
if ! { [ "$name" ] || { f_getvar $VAR_PACKAGE name && [ "$name" ]; }; }
|
||||
then
|
||||
f_dprintf "packageDelete: %s" \
|
||||
"$msg_no_package_name_passed_in_package_variable"
|
||||
return $FAILURE
|
||||
fi
|
||||
|
||||
f_dprintf "%s: name=[%s]" $fname "$name"
|
||||
|
||||
[ "$name" ] || return $FAILURE
|
||||
|
||||
{ # Verify and initialize device media if-defined
|
||||
f_media_verify &&
|
||||
f_device_init media &&
|
||||
f_index_initialize packages/INDEX
|
||||
} || return $FAILURE
|
||||
|
||||
# Now we have (indirectly via f_index_read()):
|
||||
# CATEGORY_MENU_LIST _categories_{varpkg} _rundeps_{varpkg}
|
||||
# PACKAGE_CATEGORIES _npkgs
|
||||
|
||||
local varpkg
|
||||
f_str2varname "$name" varpkg
|
||||
|
||||
# Just as-in the user-interface (opposed to scripted-use), only allow
|
||||
# packages with at least one category to be recognized.
|
||||
#
|
||||
local pkgcat=
|
||||
if ! f_getvar _categories_$varpkg pkgcat || [ ! "$pkgcat" ]; then
|
||||
# $pkg may be a partial name, search the index (this is slow)
|
||||
f_index_search PACKAGE_INDEX "$name" name
|
||||
if [ ! "$name" ]; then
|
||||
f_show_msg \
|
||||
"$msg_sorry_package_was_not_found_in_the_index" \
|
||||
"$name"
|
||||
return $FAILURE
|
||||
fi
|
||||
f_str2varname "$name" varpkg
|
||||
fi
|
||||
|
||||
# If invoked through the scripted interface, we likely have not yet
|
||||
# detected the installed packages -- something we should do only once.
|
||||
#
|
||||
if [ ! "$PACKAGES_DETECTED" ]; then
|
||||
f_dprintf "%s: Detecting installed packages" $fname
|
||||
f_package_detect_installed
|
||||
export PACKAGES_DETECTED=1 # exported for awk(1) ENVIRON[]
|
||||
fi
|
||||
# Now we have: _mark_{varpkg}=X for all installed packages
|
||||
|
||||
#
|
||||
# Return failure if the package is not already installed.
|
||||
#
|
||||
local pkgmark=
|
||||
f_getvar _mark_$varpkg pkgmark
|
||||
if ! [ "$pkgmark" -a ! "${pkgmark#[XUR]}" ]; then
|
||||
f_show_msg "$msg_package_not_installed_cannot_delete" "$name"
|
||||
return $FAILURE
|
||||
fi
|
||||
|
||||
#
|
||||
# Check for dependencies
|
||||
#
|
||||
local pkgsel depc=0 udeps=
|
||||
for pkgsel in $SELECTED_PACKAGES; do
|
||||
local mark=
|
||||
f_str2varname $pkgsel varpkg
|
||||
debug= f_getvar _mark_$varpkg mark
|
||||
[ "$mark" -a ! "${mark#[XUR]}" ] || continue
|
||||
local dep rundeps=
|
||||
debug= f_getvar _rundeps_$varpkg rundeps
|
||||
for dep in $rundeps; do
|
||||
if [ "$dep" = "$name" ]; then
|
||||
# Maybe this package is marked for deletion too
|
||||
if [ "$mark" = "U" ]; then
|
||||
udeps="$udeps $pkgsel"
|
||||
else
|
||||
depc=$(( $depc + 1 ))
|
||||
fi
|
||||
break
|
||||
fi
|
||||
done
|
||||
done
|
||||
if [ $depc -gt 0 ]; then
|
||||
local grammatical_s=
|
||||
[ $depc -gt 1 ] && grammatical_s=s
|
||||
f_show_msg \
|
||||
"$msg_package_is_needed_by_other_installed_packages" \
|
||||
"$name" "$depc" "$grammatical_s"
|
||||
return $FAILURE
|
||||
fi
|
||||
|
||||
#
|
||||
# Chase dependencies that are marked for uninstallation
|
||||
#
|
||||
for pkgsel in $udeps; do
|
||||
f_dprintf "%s: Uninstalling dependecy %s (marked for delete)" \
|
||||
$fname "$pkgsel"
|
||||
f_package_delete "$pkgsel"
|
||||
done
|
||||
|
||||
#
|
||||
# OK to perform the delete (no other packages depend on it)...
|
||||
#
|
||||
f_show_info "$msg_uninstalling_package_waiting_for_pkg_delete" "$name"
|
||||
if f_debugging; then
|
||||
pkg_delete -v "$name"
|
||||
else
|
||||
f_quietly pkg_delete "$name"
|
||||
fi
|
||||
if [ $? -ne $SUCCESS ]; then
|
||||
f_show_msg "$msg_pkg_delete_failed" "$name"
|
||||
return $FAILURE
|
||||
else
|
||||
f_dprintf "%s: pkg_delete(1) of %s successful" $fname "$name"
|
||||
f_str2varname "$name" varpkg
|
||||
setvar _mark_$varpkg ""
|
||||
fi
|
||||
}
|
||||
|
||||
############################################################ MAIN
|
||||
|
||||
f_dprintf "%s: Successfully loaded." packages/packages.subr
|
||||
|
@ -195,6 +195,7 @@ f_resword_new configPCNFSD f_config_pcnfsd
|
||||
# packages/packages.subr
|
||||
f_resword_new configPackages f_package_config
|
||||
f_resword_new packageAdd f_package_add
|
||||
f_resword_new packageDelete f_package_delete
|
||||
|
||||
# variable.subr
|
||||
f_resword_new installVarDefaults f_variable_set_defaults
|
||||
|
Loading…
Reference in New Issue
Block a user