svn commit: r252775 - in head/usr.sbin/bsdconfig: include share share/packages

Devin Teske dteske at FreeBSD.org
Fri Jul 5 06:52:08 UTC 2013


Author: dteske
Date: Fri Jul  5 06:52:07 2013
New Revision: 252775
URL: http://svnweb.freebsd.org/changeset/base/252775

Log:
  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.

Modified:
  head/usr.sbin/bsdconfig/include/messages.subr
  head/usr.sbin/bsdconfig/share/packages/packages.subr
  head/usr.sbin/bsdconfig/share/script.subr

Modified: head/usr.sbin/bsdconfig/include/messages.subr
==============================================================================
--- head/usr.sbin/bsdconfig/include/messages.subr	Fri Jul  5 06:46:11 2013	(r252774)
+++ head/usr.sbin/bsdconfig/include/messages.subr	Fri Jul  5 06:52:07 2013	(r252775)
@@ -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=
 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?"

Modified: head/usr.sbin/bsdconfig/share/packages/packages.subr
==============================================================================
--- head/usr.sbin/bsdconfig/share/packages/packages.subr	Fri Jul  5 06:46:11 2013	(r252774)
+++ head/usr.sbin/bsdconfig/share/packages/packages.subr	Fri Jul  5 06:52:07 2013	(r252775)
@@ -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

Modified: head/usr.sbin/bsdconfig/share/script.subr
==============================================================================
--- head/usr.sbin/bsdconfig/share/script.subr	Fri Jul  5 06:46:11 2013	(r252774)
+++ head/usr.sbin/bsdconfig/share/script.subr	Fri Jul  5 06:52:07 2013	(r252775)
@@ -195,6 +195,7 @@ f_resword_new configPCNFSD	f_config_pcnf
 # 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


More information about the svn-src-all mailing list