10 FAQ
This section answers anticipated frequently asked questions about the package manager.
10.1 Are package installations versioned with respect to the Racket version?
Most Racket installations are configured to that installing a package installs it for a specific user and a specific version of Racket. That is, the package scope is user- and version-specific. More precisely, it is user-specific and installation-name-specific, where an installation name is typically a Racket version.
You can change the default package scope (for a particular Racket installation) with raco pkg config -i --set default-scope installation, in which case package operations apply for all users of a Racket installation. You can also use the -i or --installation flag with a specific raco pkg command, instead of changing the default scope for all uses of raco pkg. Note that an installation-wide package is not exactly version-specific, because the version of an installation can change if it corresponds to a source-code checkout that is periodically updated and rebuilt.
If you change the default package scope, you can use the -u or --user flag with a specific raco pkg command to perform the command with user-specific package scope.
10.2 Where and how are packages installed?
User-specific and Racket-version-specific packages are in (find-user-pkgs-dir), and installation-wide packages are in (find-pkgs-dir). They are linked as collections (for single-collection packages) or collection roots (for multi-collection packages) with raco link.
10.3 How are user-specific and installation-wide package scopes related for conflict checking?
User-specific packages are checked against installation-wide packages for package-name conflicts and provided-module conflicts. Installation-wide packages are checked against user-specific packages only for provided-module conflicts.
Beware that a conflict-free, installation-wide change by one user can create conflicts for a different user.
10.4 Do I need to change a package’s version when I update a package with error fixes, etc.?
If you have new code for a package, then it should have a new checksum. When package updates are searched for, the checksum of the installed package is compared with the checksum of the source, if they are different, then the source is re-installed. This allows code changes to be distributed. You do not need to declare an update a version number, except to allow other package implementors to indicate a dependency on particular features (where a bug fix might be considered a feature, but it is not usually necessary to consider it that way).
10.5 How can I specify which version of a package I depend on if its interface has changed and I need an old version?
In such a situation, the author of the package has released a backwards incompatible edition of a package. The package manager provides no help to deal with this situation (other than, of course, not installing the “update”). Therefore, package authors should not make backwards incompatible changes to packages. Instead, they should release a new package with a new name. For example, package libgtk might become libgtk2. These packages should be designed to not conflict with each other, as well.
10.6 How can I fix my installation to a specific set of package implementations or checksums?
Packages are updated only when you run a tool such as raco pkg update, so packages are never updated implicitly. Furthermore, you can snapshot a set of package archives and install from those archives, instead of relying on package name resolution through a package catalog.
If you want to control the resolution of package names (including specific checksums) but not necessary keep a copy of all package code (assuming that old checksums remain available, such as through GitHub), you can create a snapshot of the package name to package source mapping by using raco pkg catalog-copy. For example,
raco pkg catalog-copy --from-config /home/joe/snapshot.sqlite
creates a snapshot "/home/joe/snapshot.sqlite" of the current package name resolution, and then
raco pkg config --set catalogs file:///home/joe/snapshot.sqlite
directs all package-name resolution to the snapshot. You can configure resolution for specific package names by editing the snapshot.
You can go even further with
raco pkg catalog-archive --from-config /home/joe/snapshot/
which not only takes a snapshot of the catalog, but also takes a snapshot of all package sources (so that you do not depend on the original sources).
10.7 How can I install a package without its documentation?
If package is available in the form of a built package, then you can use raco pkg install --binary-lib to strip source, tests, and documentation from a package before installing it.
Built packages are typically provided by a snapshot or release site (where a Racket distribution downloaded from the site is configured to consult the site for packages), at least for packages associated with the distribution. Beware that https://pkgs.racket-lang.org/ generally refers to source packages, not built packages. In the near future, built variants of the https://pkgs.racket-lang.org/ packages will be provided at https://pkg-build.racket-lang.org/catalog/.
Some packages have been split at the source level into separate library, test, and documentation packages. For example, net-lib provides modules such as net/cookie without documentation, while net-doc provides documentation and net-test provides tests. The net package depends on net-lib and net-doc, and it implies net-lib, so you can install net in a minimal Racket distribution to get the libraries with documentation (and lots of additional packages to support documentation), or install net-lib to get just the libraries.
If you develop a package that is especially widely used or is especially useful in a constrained installation environment, then splitting your package into -lib, -doc, and -test components may be worthwhile. Most likely, you should keep the packages together in a single source-code repository and use metedata such as implies and update-implies (see Package Metadata) so that the packages are updated in sync.
10.8 Why is the package manager so different than PLaneT?
There are two fundamental differences between PLaneT and this package manager.
The first is that PLaneT uses “internal linking” whereas the current package manager uses “external linking.” For example, an individual module requires a PLaneT package directly in a require statement:
whereas using the package manager, the module would simply require the module of interest:
(require data/matrix)
and would rely on the external system having the tic-tac-toe package installed.
This change is good because it makes the origin of modules more
flexible—
This change is bad because it makes the meaning of your program dependent on the state of the system.
The second major difference is that PLaneT is committed to guaranteeing that packages that never conflict with one another, so that any number of major and minor versions of the same package can be installed and used simultaneously. The package manager does not share this commitment, so package authors and users must be mindful of potential conflicts and plan around them.
This change is good because it is simpler and lowers the burden of maintenance (provided most packages don’t conflict.)
The change is bad because users must plan around potential conflicts.
In general, the goal of the package manager is to be a lower-level system, more like the package systems used by operating systems. The goals of PLaneT are not bad, but we believe they are needed infrequently and a system like PLaneT could be more easily built atop the package manager than the reverse.
In particular, our plans to mitigate the downsides of these changes are documented in Short Term.