Subject: RFC: new variable SUGGESTS, Part II
To: None <tech-pkg@netbsd.org>
From: Jan Schaumann <jschauma@netbsd.org>
List: tech-pkg
Date: 09/01/2002 21:36:34
--/04w6evG8XlLl3ft
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi all,

Some time before the pkgsrc-1.6-freeze, I suggested the implementation
of a new variable called SUGGESTS (see
http://mail-index.netbsd.org/tech-pkg/2002/07/21/0007.html).

Now that the freeze is over, I'd like to bring this up again, as I still
think this ia a good idea.  The discussion at that time did divert into
areas that SUGGESTS would not be able to solve.  Various instances where
other, similar problems arise still exist.  However, this implementation
is not intended to solve those problems, but merely to provide a
possibility for a package to point out what other software might be
useful.

As such, I still believe that it would not be useful to turn such
suggestions into dependencies.

Anyway, attached find a revised implementation, with additional support
in pkg_info, pkg_create and pkg_add.

Let me know what you think and where to improve this.

-Jan

-- 
chown -R us.enemy your_base

--/04w6evG8XlLl3ft
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="Packages.txt.diff"

Index: Packages.txt
===================================================================
RCS file: /cvsroot/pkgsrc/Packages.txt,v
retrieving revision 1.261
diff -b -u -r1.261 Packages.txt
--- Packages.txt	2002/08/26 05:17:39	1.261
+++ Packages.txt	2002/09/02 01:17:53
@@ -1397,6 +1397,10 @@
       done in pkgsrc/x11/kde, this is likely to remove whole KDE. Works by
       adding a "-R" to the pkg_delete command line.
 
+    - DEINSTALLSUGGESTS:
+      Additionally remove all packages suggested by the given package.
+      Works similarly to DEINSTALLDEPENDS.
+
  * update:
    This target causes the current package to be updated to the latest
    version.  The package and all depending packages first get de-installed,
@@ -1529,6 +1533,10 @@
    This target shows which installed packages match the current package's
    DEPENDS. Useful if out of date DEPENDS are causing build problems.
 
+ * show-installed-suggests:
+   This target shows which installed packages match the current package's
+   SUGGESTS.
+
  * check-shlibs:
    After a package is installed, check all it's binaries and (on ELF 
    platforms) shared libraries if they find the shared libs they need.
@@ -2060,8 +2068,34 @@
 and a different version string. "Xaw3d-1.5" e.g. will automatically conflict
 with the older version "Xaw3d-1.3".
 
+
+ 10.14 Suggesting other packages
+ ===============================
+
+Your package, even though it may not strictly DEPEND on another package, may
+suggest other packages that are useful with this package.  This allows the
+package maintainer to point the user to, for example, benchmark tests for the
+package in question or allow the user to select from a range of options that
+simply make sense to install alongside this package. The format is almost
+exactly as the format of DEPENDS.
+
+For example, pkgsrc/wm/blackbox contains a WindowManager which does not
+include keybindings.  The vast majority of the users will want to install a
+keygrabber such as pkgsrc/wm/bbkeys, yet it is not a strict dependency for
+blackbox.  Thus, pkgsrc/wm/blackbox SUGGESTS the bbkeys package:
+
+    SUGGESTS=  bbkeys>=0.8.4:../../wm/bbkeys
+
+The way suggestions are implemented allows the user to choose between ignoring
+suggestions alltogether, installing them or be prompted for each package to
+choose whether or not it should be installed.  This behaviour is regulated
+through the TAKE_SUGGESTS variable defined in /etc/mk.conf.  TAKE_SUGGESTS
+defaults to the value "NO", causing all suggestions to silently be ignored.
+Other possible values are "YES" and "ASK" with their logical consequences.
+(If BATCH is defined, suggestions are automatically ignored.)
+
 
- 10.14 Software which has a WWW Home Page
+ 10.15 Software which has a WWW Home Page
  ========================================
 
 The NetBSD packages system now supports a variable called HOMEPAGE.
@@ -2071,7 +2105,7 @@
 variable.
 
 
- 10.15 How to handle modified distfiles with the 'old' name
+ 10.16 How to handle modified distfiles with the 'old' name
  ==========================================================
 
 Sometimes authors of a software package make some modifications after the
@@ -2086,7 +2120,7 @@
 crept in.
 
 
- 10.16 What does "Don't know how to make /usr/share/tmac/tmac.andoc" mean?
+ 10.17 What does "Don't know how to make /usr/share/tmac/tmac.andoc" mean?
  =========================================================================
 
 When compiling the pkgsrc/pkgtools/pkg_install package, you get the error
@@ -2098,7 +2132,7 @@
 NOMAN=YES either in the environment or in /etc/mk.conf.
 
 
- 10.17 How to handle incrementing versions when fixing an existing package
+ 10.18 How to handle incrementing versions when fixing an existing package
  =========================================================================
 
 When making fixes to an existing package it can be useful to change
@@ -2119,7 +2153,7 @@
 DISTNAME=	foo-17.43
 
 
- 10.18 "Could not find bsd.own.mk" - what's wrong?
+ 10.19 "Could not find bsd.own.mk" - what's wrong?
  =================================================
 
 You didn't install the compiler set, comp.tgz, when you installed your
@@ -2131,7 +2165,7 @@
 the release you have installed (determine via "uname -r").
 
 
- 10.19 Restricted packages
+ 10.20 Restricted packages
  =========================
 
 Some licenses restrict how software may be re-distributed.  In order to
@@ -2168,7 +2202,7 @@
 unconditionally prevent users from generating binary packages!
 
 
- 10.20 Packages using (n)curses
+ 10.21 Packages using (n)curses
  ==============================
 
 Some packages need curses functionality that wasn't present in NetBSD's own
@@ -2183,7 +2217,7 @@
 define USE_NCURSES in the package's Makefile.
 
 
- 10.21 Automated security check
+ 10.22 Automated security check
  ==============================
 
 Please be aware that there can often be bugs in third-party software,
@@ -2239,7 +2273,7 @@
 /pub/NetBSD/packages/distfiles/vulnerabilities on ftp.netbsd.org. 
 
 
- 10.22 What's the proper way to create an account from a package?
+ 10.23 What's the proper way to create an account from a package?
  ================================================================
 
 There are two make variables used to control the creation of package-specific
@@ -2272,7 +2306,7 @@
 prior to package installation.
 
 
- 10.23 How to handle compiler bugs
+ 10.24 How to handle compiler bugs
  =================================
 
 Some source files trigger bugs in the compiler, based on combinations
@@ -2286,7 +2320,7 @@
 examples.
 
 
- 10.24 Packages providing info files
+ 10.25 Packages providing info files
  ===================================
 
 Some packages install info files or use the makeinfo or install-info
@@ -2334,7 +2368,7 @@
     mk/texinfo.mk).
 
 
- 10.25 Packages whose distfiles aren't available for plain downloading
+ 10.26 Packages whose distfiles aren't available for plain downloading
  =====================================================================
 
 If you need to download from a dynamic URL you can set DYNAMIC_MASTER_SITES
@@ -2352,7 +2386,7 @@
 www/ap-aolserver, www/openacs. Try to be consistent with them.
 
 
- 10.26 Using pkgsrc on non-NetBSD (Linux, Solaris, Darwin, MacOS X)
+ 10.27 Using pkgsrc on non-NetBSD (Linux, Solaris, Darwin, MacOS X)
  ==================================================================
 
 In order to use pkgsrc on a non-NetBSD operating system, you must first
@@ -2360,7 +2394,7 @@
 http://www.zoularis.org/ for information on boostrapping.
 
 
- 10.27 Configuration files handling and placement
+ 10.28 Configuration files handling and placement
  ================================================
 
 The global variable PKG_SYSCONFBASE (and some others) can be set by the

--/04w6evG8XlLl3ft
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="pkg_install.suggests.diff"

Index: add/perform.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/pkg_install/add/perform.c,v
retrieving revision 1.73
diff -b -u -r1.73 perform.c
--- add/perform.c	2002/08/29 21:46:33	1.73
+++ add/perform.c	2002/09/02 01:11:03
@@ -571,6 +571,8 @@
 			move_file(".", SIZE_PKG_FNAME, LogDir);
 		if (fexists(SIZE_ALL_FNAME))
 			move_file(".", SIZE_ALL_FNAME, LogDir);
+		if (fexists(SUGGESTS_FNAME))
+			move_file(".", SUGGESTS_FNAME, LogDir);
 		(void) snprintf(contents, sizeof(contents), "%s/%s", LogDir, CONTENTS_FNAME);
 		cfile = fopen(contents, "w");
 		if (!cfile) {
@@ -647,6 +649,11 @@
 			warnx("cannot open %s as display file", buf);
 	}
 
+	if (!isemptyfile(SUGGESTS_FNAME)) {
+		printf("This package suggests the following other packages:\n");
+		printf("%s", fileGetContents(SUGGESTS_FNAME));
+	}
+
 	goto success;
 
 bomb:
Index: admin/main.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/pkg_install/admin/main.c,v
retrieving revision 1.29
diff -b -u -r1.29 main.c
--- admin/main.c	2002/08/04 20:50:55	1.29
+++ admin/main.c	2002/09/02 01:11:04
@@ -138,6 +138,7 @@
 		case PLIST_OPTION:
 		case PLIST_PKGCFL:
 		case PLIST_BLDDEP:
+		case PLIST_SUGG:
 			break;
 		}
 	}
@@ -249,6 +250,7 @@
 			case PLIST_OPTION:
 			case PLIST_PKGCFL:
 			case PLIST_BLDDEP:
+			case PLIST_SUGG:
 				break;
 			}
 		}
Index: create/create.h
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/pkg_install/create/create.h,v
retrieving revision 1.16
diff -b -u -r1.16 create.h
--- create/create.h	2001/05/21 09:17:30	1.16
+++ create/create.h	2002/09/02 01:11:04
@@ -27,6 +27,7 @@
 
 extern char *Prefix;
 extern char *Comment;
+extern char *Suggests;
 extern char *Desc;
 extern char *Display;
 extern char *Install;
Index: create/main.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/pkg_install/create/main.c,v
retrieving revision 1.21
diff -b -u -r1.21 main.c
--- create/main.c	2002/06/09 14:14:50	1.21
+++ create/main.c	2002/09/02 01:11:05
@@ -24,10 +24,11 @@
 #include "lib.h"
 #include "create.h"
 
-static const char Options[] = "ORhlVvFf:p:P:C:c:d:i:k:L:r:t:X:D:m:s:S:b:B:UI:";
+static const char Options[] = "ORhlVvFf:p:P:C:c:d:i:k:L:r:t:X:D:m:s:S:b:B:UI:j:";
 
 char   *Prefix = NULL;
 char   *Comment = NULL;
+char   *Suggests = NULL;
 char   *Desc = NULL;
 char   *Display = NULL;
 char   *Install = NULL;
@@ -61,7 +62,7 @@
 	    "                  [-i iscript] [-k dscript] [-r rscript] [-t template]",
 	    "                  [-X excludefile] [-D displayfile] [-m mtreefile]",
 	    "                  [-b build-version-file] [-B build-info-file]",
-	    "                  [-I realprefix]",
+	    "                  [-I realprefix] [-j suggests-file]",
 	    "                  -c comment -d description -f packlist pkg-name");
 	exit(1);
 }
@@ -173,6 +174,10 @@
 
 		case 'B':
 			BuildInfo = optarg;
+			break;
+
+		case 'j':
+			Suggests = optarg;
 			break;
 
 		case 'V':
Index: create/perform.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/pkg_install/create/perform.c,v
retrieving revision 1.33
diff -b -u -r1.33 perform.c
--- create/perform.c	2002/07/19 19:04:36	1.33
+++ create/perform.c	2002/09/02 01:11:05
@@ -135,6 +135,9 @@
 	if (SizeAll) {
 		(void) fprintf(totar, "%s\n", SIZE_ALL_FNAME);
 	}
+	if (Suggests) {
+		(void) fprintf(totar, "%s\n", SUGGESTS_FNAME);
+	}
 
 	for (p = plist->head; p; p = p->next) {
 		if (p->type == PLIST_FILE) {
@@ -284,6 +287,14 @@
 			printf(".\n");
 	}
 
+	/* Note suggestions, if any */
+	if (Suggests) {
+		if (Verbose && !PlistOnly) {
+			printf("Noting suggestions:\n");
+			printf("%s", fileGetContents(Suggests));
+		}
+	}
+
 	/* Slurp in the packing list */
 	read_plist(&plist, pkg_in);
 
@@ -378,6 +389,12 @@
 		copy_file(Home, SizeAll, SIZE_ALL_FNAME);
 		add_plist(&plist, PLIST_IGNORE, NULL);
 		add_plist(&plist, PLIST_FILE, SIZE_ALL_FNAME);
+	}
+	if (Suggests) {
+		copy_file(Home, Suggests, SUGGESTS_FNAME);
+		add_plist(&plist, PLIST_IGNORE, NULL);
+		add_plist(&plist, PLIST_FILE, SUGGESTS_FNAME);
+		add_plist(&plist, PLIST_SUGG, SUGGESTS_FNAME);
 	}
 
 	/* Finally, write out the packing list */
Index: create/pkg_create.1
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/pkg_install/create/pkg_create.1,v
retrieving revision 1.32
diff -b -u -r1.32 pkg_create.1
--- create/pkg_create.1	2002/03/05 13:01:21	1.32
+++ create/pkg_create.1	2002/09/02 01:11:07
@@ -85,6 +85,9 @@
 .Op Fl t Ar template
 .Ek
 .Bk -words
+.Op Fl j Ar suggests-file
+.Ek
+.Bk -words
 .Fl c Ar comment
 .Ek
 .Bk -words
@@ -252,7 +255,7 @@
 Store the given file for later querying with the
 .Xr pkg_info 1
 .Ar -s
-flag. The file is expected to contain the the size (in bytes) of all files of
+flag. The file is expected to contain the size (in bytes) of all files of
 this package added up and stored as a ASCII string, terminated by a newline.
 .It Fl t Ar template
 Use
@@ -268,6 +271,12 @@
 for
 .Xr mktemp 3
 to fill in with a unique ID.
+.It Fl s Ar suggests-file
+Store the given file for later querying with the
+.Xr pkg_info 1
+.Ar -j
+flag. The file is expected to contain the names of the packages suggested
+by this package, if any.
 .It Fl U
 Do not update the package file database with any file information.
 .It Fl V
@@ -467,6 +476,10 @@
 .Cm @pkgdep
 directive may contain wildcards or relational
 package version information).
+.It Cm @suggests Ar pkgname
+Suggest
+.Ar pkgname
+as a useful addition to this package.
 .It Cm @pkgcfl Ar pkgcflname
 Declare a conflict with the
 .Ar pkgcflname
Index: delete/main.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/pkg_install/delete/main.c,v
retrieving revision 1.20
diff -b -u -r1.20 main.c
--- delete/main.c	2002/07/20 08:40:19	1.20
+++ delete/main.c	2002/09/02 01:11:07
@@ -35,12 +35,13 @@
 #include "lib.h"
 #include "delete.h"
 
-static char Options[] = "hVvDdnfFp:OrR";
+static char Options[] = "hVvDdnfFp:OrRj";
 
 char   *Prefix = NULL;
 char   *ProgramPath = NULL;
 Boolean NoDeInstall = FALSE;
 Boolean CleanDirs = FALSE;
+Boolean Delete_suggests = FALSE;
 Boolean File2Pkg = FALSE;
 Boolean Recurse_up = FALSE;
 Boolean Recurse_down = FALSE;
@@ -50,7 +51,7 @@
 static void
 usage(void)
 {
-	fprintf(stderr, "usage: pkg_delete [-vVDdnFfOrR] [-p prefix] pkg-name ...\n");
+	fprintf(stderr, "usage: pkg_delete [-vVDdnFfOrRj] [-p prefix] pkg-name ...\n");
 	exit(1);
 }
 
@@ -74,6 +75,10 @@
 
 		case 'F':
 			File2Pkg = TRUE;
+			break;
+
+		case 'j':
+			Delete_suggests = TRUE;
 			break;
 
 		case 'p':
Index: info/info.h
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/pkg_install/info/info.h,v
retrieving revision 1.13
diff -b -u -r1.13 info.h
--- info/info.h	2002/06/09 13:23:45	1.13
+++ info/info.h	2002/09/02 01:11:07
@@ -50,6 +50,7 @@
 #define SHOW_DEPENDS		0x04000
 #define SHOW_PKG_SIZE		0x08000
 #define SHOW_ALL_SIZE		0x10000
+#define SHOW_SUGGESTS		0x20000
 
 extern int Flags;
 extern Boolean AllInstalled;
Index: info/main.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/pkg_install/info/main.c,v
retrieving revision 1.31
diff -b -u -r1.31 main.c
--- info/main.c	2002/08/04 19:43:08	1.31
+++ info/main.c	2002/09/02 01:11:07
@@ -38,7 +38,7 @@
 #include "lib.h"
 #include "info.h"
 
-static const char Options[] = "aBbcDde:fFhIikLl:mnpqRrsSvV";
+static const char Options[] = "aBbcDde:fFhIijkLl:mnpqRrsSvV";
 
 int     Flags = 0;
 Boolean AllInstalled = FALSE;
@@ -55,7 +55,7 @@
 usage(void)
 {
 	fprintf(stderr, "%s\n%s\n%s\n",
-	    "usage: pkg_info [-BbcDdFfIikLmnpqRrSsVvh] [-e package] [-l prefix]",
+	    "usage: pkg_info [-BbcDdFfIijkLmnpqRrSsVvh] [-e package] [-l prefix]",
 	    "                pkg-name [pkg-name ...]",
 	    "       pkg_info -a [flags]");
 	exit(1);
@@ -113,6 +113,10 @@
 			Flags |= SHOW_INSTALL;
 			break;
 
+		case 'j':
+			Flags |= SHOW_SUGGESTS;
+			break;
+
 		case 'k':
 			Flags |= SHOW_DEINSTALL;
 			break;
@@ -162,7 +166,8 @@
 			/* Reasonable definition of 'everything' */
 			Flags = SHOW_COMMENT | SHOW_DESC | SHOW_PLIST | SHOW_INSTALL |
 			    SHOW_DEINSTALL | SHOW_REQUIRE | SHOW_DISPLAY | SHOW_MTREE |
-			    SHOW_REQBY | SHOW_DEPENDS | SHOW_PKG_SIZE | SHOW_ALL_SIZE;
+			    SHOW_REQBY | SHOW_DEPENDS | SHOW_PKG_SIZE | SHOW_ALL_SIZE |
+			    SHOW_SUGGESTS;
 			break;
 
 		case 'V':
@@ -195,7 +200,7 @@
 
 	/* Set some reasonable defaults */
 	if (!Flags)
-		Flags = SHOW_COMMENT | SHOW_DESC | SHOW_REQBY | SHOW_DEPENDS;
+		Flags = SHOW_COMMENT | SHOW_DESC | SHOW_REQBY | SHOW_DEPENDS | SHOW_SUGGESTS;
 
 	/* -Fe /filename -> change CheckPkg to real packagename */
 	if (CheckPkg && File2Pkg) {
Index: info/perform.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/pkg_install/info/perform.c,v
retrieving revision 1.40
diff -b -u -r1.40 perform.c
--- info/perform.c	2002/07/19 19:04:37	1.40
+++ info/perform.c	2002/09/02 01:11:08
@@ -224,9 +224,13 @@
 		if ((Flags & SHOW_ALL_SIZE) && fexists(SIZE_ALL_FNAME)) {
 			show_file("Size in bytes including required pkgs: ", SIZE_ALL_FNAME);
 		}
+		if ((Flags & SHOW_SUGGESTS) && fexists(SUGGESTS_FNAME)) {
+			show_file("Suggests:\n", SUGGESTS_FNAME);
+		}
 		if (!Quiet) {
 			puts(InfoPrefix);
 		}
+
 		free_plist(&plist);
 	}
 bail:
Index: info/show.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/pkg_install/info/show.c,v
retrieving revision 1.25
diff -b -u -r1.25 show.c
--- info/show.c	2002/07/20 04:59:47	1.25
+++ info/show.c	2002/09/02 01:11:09
@@ -95,6 +95,7 @@
 	{PLIST_OPTION, "@option %s", "\tPackage has option: %s"},
 	{PLIST_PKGCFL, "@pkgcfl %s", "\tPackage conflicts with: %s"},
 	{PLIST_BLDDEP, "@blddep %s", "\tPackage depends exactly on: %s"},
+	{PLIST_SUGG, "@suggests %s", "\tPackage suggests: %s"},
 	{-1, NULL, NULL}
 };
 
@@ -201,6 +202,7 @@
 			case PLIST_OPTION:
 			case PLIST_PKGCFL:
 			case PLIST_BLDDEP:
+			case PLIST_SUGG:
 				printf(Quiet ? showv[p->type].sh_quiet : showv[p->type].sh_verbose, p->name);
 				break;
 			default:
Index: lib/lib.h
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/pkg_install/lib/lib.h,v
retrieving revision 1.43
diff -b -u -r1.43 lib.h
--- lib/lib.h	2002/07/19 19:04:40	1.43
+++ lib/lib.h	2002/09/02 01:11:09
@@ -100,6 +100,7 @@
 #define BUILD_INFO_FNAME	"+BUILD_INFO"
 #define SIZE_PKG_FNAME		"+SIZE_PKG"
 #define SIZE_ALL_FNAME		"+SIZE_ALL"
+#define SUGGESTS_FNAME		"+SUGGESTS"
 
 #define CMD_CHAR		'@'	/* prefix for extended PLIST cmd */
 
@@ -137,7 +138,8 @@
 	PLIST_IGNORE_INST,	/* 15 */
 	PLIST_OPTION,		/* 16 */
 	PLIST_PKGCFL,		/* 17 */
-	PLIST_BLDDEP		/* 18 */
+	PLIST_BLDDEP,		/* 18 */
+	PLIST_SUGG		/* 19 */
 }       pl_ent_t;
 
 /* Types */
Index: lib/plist.c
===================================================================
RCS file: /cvsroot/basesrc/usr.sbin/pkg_install/lib/plist.c,v
retrieving revision 1.35
diff -b -u -r1.35 plist.c
--- lib/plist.c	2002/07/20 08:36:19	1.35
+++ lib/plist.c	2002/09/02 01:11:10
@@ -63,6 +63,7 @@
 	{"dirrm", PLIST_DIR_RM, 1, 0},
 	{"option", PLIST_OPTION, 1, 0},
 	{"blddep", PLIST_BLDDEP, 1, 0},
+	{"suggests", PLIST_SUGG, 1, 0},
 	{NULL, FAIL, 0, 0}
 };
 

--/04w6evG8XlLl3ft
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="suggests.diff"

Index: bsd.pkg.mk
===================================================================
RCS file: /cvsroot/pkgsrc/mk/bsd.pkg.mk,v
retrieving revision 1.1041
diff -b -u -r1.1041 bsd.pkg.mk
--- bsd.pkg.mk	2002/09/01 16:15:32	1.1041
+++ bsd.pkg.mk	2002/09/02 01:03:25
@@ -65,6 +65,9 @@
 
 INTERACTIVE_STAGE?=	none
 
+TAKE_SUGGESTS?= NO
+DEINSTALLSUGGESTS?= NO
+
 .if defined(USE_JAVA)
 BUILD_DEFS+=		PKG_JVM JAVA_HOME
 .  if !defined(PKG_JVM)
@@ -743,6 +746,9 @@
 .  ifndef NO_MTREE
 PKG_ARGS_COMMON+=	-m ${MTREE_FILE}
 .  endif
+.  ifdef SUGGESTS
+PKG_ARGS_COMMON+=	-j ${PKG_DBDIR}/${PKGNAME}/+SUGGESTS
+.  endif
 
 PKG_ARGS_INSTALL=	-p ${PREFIX} ${PKG_ARGS_COMMON}
 PKG_ARGS_BINPKG=	-p ${PREFIX:S/^${DESTDIR}//} -L ${PREFIX} ${PKG_ARGS_COMMON}
@@ -1239,6 +1245,90 @@
 .  endif
 .endif
 
+
+################################################################
+# Suggestions                                                  #
+################################################################
+.if !target(check-suggests)
+check-suggests:
+.	if ${TAKE_SUGGESTS} == "YES" || ${TAKE_SUGGESTS} == "yes"
+		${_PKG_SILENT}${_PKG_DEBUG} 				\
+		for sugg in ${SUGGESTS:Q:S/\ / /g} ; do			\
+			pkg=$${sugg%%:*}; 				\
+			dir=$${sugg#*:}; 				\
+			found=`${PKG_INFO} -e $$pkg || ${TRUE}`;	\
+			if [ "X$$found" != "X" ]; then   		\
+				${ECHO} "Suggested package $$pkg found: $$found"; \
+			else 						\
+				${ECHO_MSG} "=> Installing suggested package $$pkg ..."; \
+				cd $$dir; 				\
+				${MAKE} ${MAKEFLAGS} reinstall; 	\
+			fi; 						\
+		done;
+.	elif ${TAKE_SUGGESTS} == "ASK"  && !defined(BATCH)
+		${_PKG_SILENT}${_PKG_DEBUG} 				\
+		for sugg in ${SUGGESTS:Q:S/\ / /g} ; do			\
+			pkg=$${sugg%%:*}; 				\
+			dir=$${sugg#*:}; 				\
+			found=`${PKG_INFO} -e $$pkg || ${TRUE}`; 	\
+			if [ "X$$found" != "X" ]; then   		\
+				${ECHO} "Suggested package $$pkg found: $$found"; \
+			else 						\
+				read -p "Install suggested package $$pkg? [y/n] " ANS; \
+				if [ "X$$ANS" = "Xy" ]; then 		\
+					${ECHO_MSG} "=> Installing suggested package $$pkg ..."; \
+					cd $$dir; 			\
+					${MAKE} ${MAKEFLAGS} reinstall;	\
+				fi; 					\
+			fi;						\
+		done;
+.	endif # TAKE_SUGGESTS == "YES"
+.endif # !target(check-suggests)
+
+# show suggestions
+.if !target(show-suggests-dirs)
+show-suggests-dirs:
+	${_PKG_SILENT}${_PKG_DEBUG}					\
+	dlist="";							\
+	thisdir=`pwd`;							\
+	for reldir in "" ${SUGGESTS:C/^[^:]*://:C/:.*$//} ;		\
+	do								\
+		if [ "X$$reldir" = "X" ]; then continue; fi;		\
+		cd $$thisdir/$$reldir;					\
+		WD=`pwd`;						\
+		d=`dirname $$WD`;					\
+		absdir=`basename $$d`/`basename $$WD`;			\
+		dlist="$$dlist $$absdir";				\
+	done;								\
+	cd $$thisdir;							\
+	${ECHO} "$$dlist"
+.endif
+
+.if !target(show-installed-suggests)
+show-installed-suggests:
+.  if defined(SUGGESTS)
+	${_PKG_SILENT}${_PKG_DEBUG}					\
+	for i in ${SUGGESTS:C/:.*$//:Q:S/\ / /g} ; do			\
+		echo "$$i =>" `${PKG_INFO} -e $$i` ;			\
+	done
+.  endif
+.endif
+
+.if !target(clean-suggests)
+clean-suggests:
+.  if defined(SUGGESTS)
+	${_PKG_SILENT}${_PKG_DEBUG}					\
+	for i in `${MAKE} ${MAKEFLAGS} CLEAN_SUGGESTS_LIST_TOP=YES 	\
+			clean-suggests-list | 				\
+			${SED} -e 's;\.\./[^ ]*; ;g' | 			\
+			${TR} -s "[:space:]" "\n" | ${SORT} -u` ;	\
+	do								\
+		cd ${.CURDIR}/../../$$i &&				\
+		${MAKE} ${MAKEFLAGS} CLEANSUGGESTS=NO clean;		\
+	done
+.  endif
+.endif
+
 ################################################################
 # The following are used to create easy dummy targets for
 # disabling some bit of default target behavior you don't want.
@@ -2269,6 +2359,7 @@
 .if defined(PKG_DEVELOPER) && (${CHECK_SHLIBS} == "YES")
 	@${MAKE} ${MAKEFLAGS} check-shlibs
 .endif
+	@${MAKE} ${MAKEFLAGS} check-suggests
 
 
 
@@ -2830,10 +2921,23 @@
 	fi
 .    endfor
 .  endif # DEINSTALLDEPENDS
+.  if ${DEINSTALLSUGGESTS} != "NO"
+       @${SHCOMMENT} Also remove SUGGESTS:
+.    for pkg in ${SUGGESTS:C/:.*$//}
+       ${_PKG_SILENT}${_PKG_DEBUG}                                     \
+       found="`${PKG_INFO} -e \"${pkg}\" || ${TRUE}`";                 \
+       if [ "$$found" != "" ]; then                                    \
+               ${ECHO} Running ${PKG_DELETE} $$found;                  \
+               ${PKG_DELETE} ${real-su-deinstall-flags} $$found || ${TRUE}; \
+       fi
+.    endfor
+.  endif # DEINSTALLSUGGESTS
+
 	@${RM} -f ${INSTALL_COOKIE} ${PACKAGE_COOKIE}
 .endif						# target(deinstall)
 
 
+
 ################################################################
 # Some more targets supplied for users' convenience
 ################################################################
@@ -3110,6 +3214,33 @@
 .  endif
 .endif
 
+.if !target(clean-suggests-list)
+clean-suggests-list:
+.  if defined(SUGGESTS)
+	@for dir in `${ECHO} ${SUGGESTS:C/^[^:]*://:C/:.*//} |		\
+		       ${TR} '\040' '\012' `; do			\
+	       case "$$CLEAN_SUGGESTS_LIST_SEEN" in			\
+	       *" "$$dir" "*)  ;;					\
+	       *)							\
+		       CLEAN_SUGGESTS_LIST_SEEN=" $$dir cd ${.CURDIR} ; cd $$dir && ${MAKE} ${MAKEFLAGS} CLEAN_SUGGESTS_LIST_SEEN="$$CLEAN_SUGGESTS_LIST_SEEN" CLEAN_SUGGESTS_LIST_TOP=NO clean-suggests-list`";\
+		       ;;						\
+	       esac							\
+       done ;								\
+       if [ "${CLEAN_SUGGESTS_LIST_TOP}" != "YES" ]; then		\
+	       ${ECHO} " ${PKGPATH} $$CLEAN_SUGGESTS_LIST_SEEN";	\
+       else								\
+	       ${ECHO} " $$CLEAN_SUGGESTS_LIST_SEEN";			\
+       fi
+.  else
+       @if [ "${CLEAN_SUGGESTS_LIST_TOP}" != "YES" ]; then		\
+	       ${ECHO} " ${PKGPATH} $$CLEAN_SUGGESTS_LIST_SEEN";	\
+       else								\
+	       ${ECHO} " $$CLEAN_SUGGESTS_LIST_SEEN";			\
+	fi
+.  endif
+.endif
+
+
 .if !target(pre-distclean)
 pre-distclean:
 	@${DO_NADA}
@@ -4080,6 +4211,9 @@
 				${MV} ${PKG_DBDIR}/$$realdep/reqby.$$$$ ${PKG_DBDIR}/$$realdep/+REQUIRED_BY; \
 				${ECHO} "${PKGNAME} requires installed package $$realdep"; \
 			fi;						\
+		done;							\
+		for sugg in ${SUGGESTS:C/:.*$//:Q:S/\ / /g}; do	\
+			${ECHO} $$sugg >>  ${PKG_DBDIR}/${PKGNAME}/+SUGGESTS;	\
 		done;							\
 	fi
 	${_PKG_SILENT}${_PKG_DEBUG}					\

--/04w6evG8XlLl3ft--