1 Package Concepts
A package is a set of modules in some number of collections. Modules installed using the Racket package manager are required like any other modules. For example, if the package tic-tac-toe contains the module "matrix.rkt" in a "data" collection, then after tic-tac-toe is installed,
(require data/matrix)
imports the module. The package name is not mentioned with
require, because packages are a way of managing library
collections, not a way of referencing them. It is common, however, for
a package to implement a collection whose name is the same as the
package name—
Each package has associated package metadata:
a package name —
a string made of the characters a through z, A through Z, 0 through 9, _, and -. a checksum —
a string that identifies different releases of a package. A package can be updated when its checksum changes, whether or not its version changes. The checksum can be computed as the SHA1 (see openssl/sha1) of the package’s source. a version —
a string of the form ‹maj›.‹min›, ‹maj›.‹min›.‹sub›, or ‹maj›.‹min›.‹sub›.‹rel›, where ‹maj›, ‹min›, ‹sub›, and ‹rel› are all canonical decimal representations of natural numbers, ‹min› has no more than two digits, and ‹sub› and ‹rel› has no more than three digits. A version is intended to reflect available features of a package, and should not be confused with different releases of a package as indicated by the checksum. a list of dependencies —
a list of packages to be installed simultaneously, optionally with a lower bound on each package’s version.
A package is typically represented by a directory with the same name as the package. The checksum is typically left implicit. The package directory can contain a file named "info.rkt" to declare other metadata (see Package Metadata).
A package source identifies a package representation. Each package source type has a different way of storing the checksum. The valid package source types are:
a local file path naming an archive – The name of the package is the basename of the archive file. The checksum for archive "f.‹ext›" is given by the file "f.‹ext›.CHECKSUM". For example, "~/tic-tac-toe.zip"’s checksum would be inside "~/tic-tac-toe.zip.CHECKSUM". The valid archive formats are (currently) ".zip", ".tar", ".tgz", ".tar.gz", and ".plt".
A package source is inferred to refer to a file only when it has a suffix matching a valid archive format and when it does not start with alphabetic characters followed by ://. The inferred package name is the filename without its suffix.
a local directory – The name of the package is the name of the directory. The checksum is not present. For example, "~/tic-tac-toe/" is directory package source.
A package source is inferred to refer to a directory only when it does not have a file-archive suffix, does not match the grammar of a package name, and does not start with alphabetic characters followed by ://. The inferred package name is the directory name.
a remote URL naming an archive – This type follows the same rules as a local file path, but the archive and checksum files are accessed via HTTP(S). For example, "http://game.com/tic-tac-toe.zip" is a remote URL package source whose checksum is found at "http://game.com/tic-tac-toe.zip.CHECKSUM".
A package source is inferred to be a URL only when it starts with http:// or https://, and it is inferred to be a file URL when the URL ends with a path element that could be inferred as a file archive. The inferred package name is from the URL’s file name in the same way as for a file package source.
a remote URL naming a directory – The remote directory must contain a file named "MANIFEST" that lists all the contingent files. These are downloaded into a local directory and then the rules for local directory paths are followed. However, if the remote directory contains a file named ".CHECKSUM", then it is used to determine the checksum. For example, "http://game.com/tic-tac-toe/" is a directory URL package source whose checksum is found at "http://game.com/tic-tac-toe/.CHECKSUM".
A package source is inferred to be a URL the same for a directory or file, and it is treated as a directory URL when it does not end with a path element that has an archive file suffix. The inferred package name is the directory name.
a remote URL naming a GitHub repository – The format for such URLs is:
github://github.com/‹user›/‹repository›/‹branch-or-tag›/‹optional-subpath›
For example, "github://github.com/game/tic-tac-toe/master/" is a GitHub package source.
The zip-formatted archive for the repository (generated by GitHub for every branch and tag) is used as a remote URL archive path, except the checksum is the hash identifying the branch (or tag).
A package source is inferred to be a GitHub reference when it starts with github://; a package source that is otherwise specified as a GitHub reference is automatically prefixed with "github://github.com/". The inferred package name is the last element of ‹optional-subpath› if it is non-empty, otherwise the inferred name is ‹repository›.
a package name – A package name resolver is consulted to determine the source and checksum for the package. For example, tic-tac-toe is a package name that can be used as a package source.
A package source is inferred to be a package name when it fits the grammar of package names, which means that it has only the characters a through z, A through Z, 0 through 9, _, and -.
A package name resolver (PNR) is a server that converts package names to other package sources. A PNR is identified by a string representing a URL. This URL is combined with pkg/‹package› path segments (where ‹package› is a package name) plus a version=‹version› query (where ‹version› is the Racket version number) to form a URL that should refer to a read-able hash table with the keys: 'source mapped to the package source string and 'checksum mapped to the checksum value. Typically, the package source value for 'source will be a remote URL.
PLT supports two package name resolvers that are enabled by default: https://pkg.racket-lang.org for new packages and https://planet-compat.racket-lang.org for automatically generated packages for old PLaneT packages. Anyone may host their own package name resolver. The source for the PLT-hosted resolvers is in the (collection-file-path "pkg-index" "meta") directory.
After a package is installed, the original source of its installation is recorded, as well as if it was an automatic installation. An automatic installation is one that was installed because it was a dependency of a non-automatic installation package.
Two packages are in conflict if they contain the same module. For example, if the package tic-tac-toe contains the module file "data/matrix.rkt" and the package factory-optimize contains the module file "data/matrix.rkt", then tic-tac-toe and factory-optimize are in conflict. A package may also be in conflict with Racket itself, if it contains a module file that is part of the core Racket distribution. For example, any package that contains "racket/list.rkt" is in conflict with Racket. For the purposes of conflicts, a module is a file that ends in ".rkt" or ".ss".
Package A is a package update of Package B if (1) B is installed, (2) A and B have the same name, and (3) A’s checksum is different than B’s. Note that a package version is not taken into account when determining a package update, although a change in a package’s version (in either direction) implies a change in the checksum because the checksum is computed from the package source and the meta-data that specifies the version is part of the source.
A package scope determines the effect of package installations, updates, etc., with respect to different users, Racket versions, and Racket installations. The default package scope can be configured, but it is normally user, which is user-specific and version-specific; that is, package installation makes the package visible only for the installing user and with the installing version of Racket. The installation scope means that package installation makes the package visible to all users of the specific Racket installation that is used to install the package. Finally, the shared scope means user-specific, but for all versions and installations of Racket.