diff --git a/doc/ref/gappkg.xml b/doc/ref/gappkg.xml
index 0eaa2f5bfd..01631f5994 100644
--- a/doc/ref/gappkg.xml
+++ b/doc/ref/gappkg.xml
@@ -367,10 +367,23 @@ The following components of the record are optional.
denoting the other packages which shall be loaded together with the
current package if they are available,
+ TestPackages
+ -
+ a list of pairs [ pkgname, pkgversion ] of strings,
+ denoting packages that are needed only to test the package, but not to
+ load the package,
+
+ NeededSystemPackages
+ -
+ a record whose contents describe external dependencies of the package
+ in a machine-readable form (see
for
+ more information),
+
ExternalConditions
-
a list of strings or of pairs [ text, URL ] of strings,
- denoting conditions on external programs,
+ denoting conditions on external programs in a human-readable form
+ (see
for more information),
@@ -1169,6 +1182,19 @@ In this situation, loading A forces an attempt to load also B,
but A is loaded even if B is not available.
+If B is not essential for A but is used in the package tests,
+(for example because B is a library of groups used to provide
+testcases) then the name and the (least) version number of B should
+be added to the TestPackages component of the Dependencies
+component of the PackageInfo.g file of A. Note that ⪆
+itself does not use this information at all. In particular, no attempts
+are made to actually load B, this should be done explicitly as
+part of the package tests. The benefit of specifying this component is
+for automated test runners (e.g. as part of the ⪆ package distribution)
+which can use this information to ensure all packages needed to run
+your package's tests are installed and ready.
+
+
All package dependencies must be documented explicitly in the
PackageInfo.g file. It is important to properly
identify package dependencies and make the right decision
@@ -1224,6 +1250,60 @@ or what are other ways to disable its loading -->
+
+
+External Dependencies (System packages needed by a ⪆ Package)
+
+external dependency
+system package
+dependencies
+It is possible for a ⪆ package to require external software. If this
+software is not bundled together with the package, then this dependency
+should be documented. To do so, one may add either a string describing the
+dependency, or a list [ description, URL ], to the
+ExternalConditions component of the Dependencies component of
+the PackageInfo.g file of the ⪆ package.
+
+
+
+Note that the data in ExternalConditions is purely informational
+and meant to be human-readable, not machine-readable. ⪆ itself does
+not use it, but for packages distributed with ⪆, the ⪆ website
+displays it in its package list.
+
+
+If this dependency is available through a package manager such as apt
+or brew, this should also be documented. This can be done by adding
+the system package to the relevant component (such as Ubuntu or
+Homebrew) of the NeededSystemPackages component of the
+PackageInfo.g file of the ⪆ package. Each system package is added
+by means of a list whose first component is the name needed by the package
+manager. The other elements of this list are reserved for future usage.
+
+
+
+Note that this mechanism is primarily intended for consumption by the
+⪆ package distribution and by other testing tooling. It is deliberately
+kept very simple. For example, at this point there is no mechanism to
+prescribe a distribution version (basically, "Ubuntu" means whatever
+`ubuntu-latest` is referring to in GitHub actions), nor to specify a minimal
+version of a system package. Despite these strong limitations, this data may
+still be useful for people packaging ⪆ and its packages for a distribution,
+as it at least gives a hint which system packages may be needed.
+
+
+
+
Extensions Provided by a Package
diff --git a/lib/package.gi b/lib/package.gi
index 22eafe0815..fbd23eda01 100644
--- a/lib/package.gi
+++ b/lib/package.gi
@@ -2433,6 +2433,16 @@ InstallGlobalFunction( ValidatePackageInfo, function( info )
l -> IsList( l ) and Length( l ) = 2
and ForAll( l, IsString ) ),
"a list of pairs `[ , ]' of strings" );
+ TestOption( record.Dependencies, "TestPackages",
+ comp -> IsList( comp ) and ForAll( comp,
+ l -> IsList( l ) and Length( l ) = 2
+ and ForAll( l, IsString ) ),
+ "a list of pairs `[ , ]' of strings" );
+ TestOption( record.Dependencies, "NeededSystemPackages",
+ comp -> IsRecord( comp ) and ForAll( RecNames( comp ),
+ l -> IsList( comp.( l ) ) and ForAll( comp.( l ),
+ x -> IsList( x ) and IsString( First( x ) ) ) ),
+ "a record whose values are lists of lists `[ , ... ]`" );
TestOption( record.Dependencies, "ExternalConditions",
comp -> IsList( comp ) and ForAll( comp,
l -> IsString( l ) or ( IsList( l ) and Length( l ) = 2