2 Package Concepts

▼ |  | Package Management in Racket

1 | Getting Started with Packages
2 | Package Concepts
3 | Using raco pkg
4 | Package Metadata
5 | Source, Binary, and Built Packages
6 | Developing Packages with Git
7 | Package APIs
8 | Package Catalog Protocol
9 | PLane T Compatibility
10 | FAQ
11 | Future Plans
12 | How Package Installation and Distribution Works

► | 2 | Package Concepts

2.1 | Single-collection and Multi-collection Packages
2.2 | Package Sources
2.3 | Package Catalogs
2.4 | Explicit vs. Auto-Installation
2.5 | Package Conflicts
2.6 | Package Updates
2.7 | Package Scopes

On this page:

2.1 Single-collection and Multi-collection Packages
2.2 Package Sources
2.3 Package Catalogs
2.4 Explicit vs. Auto-Installation
2.5 Package Conflicts
2.6 Package Updates
2.7 Package Scopes

Racket
top contents ← prev up next →

## 2 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—in which case a require might appear to be referencing a package, but it is actually referencing a collection provided by the package.

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 must be computed as the SHA-1 hash (see openssl/sha1) of the package’s archive when the package is distributed in archive form. A package can be installed in a way that it has no checksum, but then the package installation does not support updating.

- a version — a string of the form ‹maj›.‹min›, ‹maj›.‹min›.‹sub›, or ‹maj›.‹min›.‹sub›.‹rel›, The constraints on version numbers are consistent with version/utils and force version numbers to be in a canonical form. For example, a would-be version string "4.3.0" must be written instead as "4.3", "4.3.1.0" must be written instead as "4.3.1", and "4" must be written as "4.0". where ‹maj›, ‹min›, ‹sub›, and ‹rel› are all canonical decimal representations of natural numbers, ‹rel› is not 0, ‹sub› is not 0 unless ‹rel› is supplied, ‹min› has no more than two digits, and ‹sub› and ‹rel› have 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).

### 2.1 Single-collection and Multi-collection Packages🔗ℹ

A package can be a single-collection package or a multi-collection package:

- A single-collection package’s directory doubles as a collection directory. By default, the package name also doubles as the collection name, but if the package has an "info.rkt" file that defines collection to a string, then the string is used as the name of the package’s collection.

- A multi-collection package’s directory contains subdirectories, each of which is a collection that is provided by the package (where the directory name is used as the collection name). A multi-collection package must have an "info.rkt" file that defines collection as 'multi.

### 2.2 Package Sources🔗ℹ

A package source identifies a package representation. Each package source type has a different way of storing the checksum and providing the package content (usually with single-collection package and multi-collection package variants).

The package source types are:

- a local file path naming an archive (as a plain path or file:// URL) — The name of the package is the basename of the archive file. The checksum for archive "f.‹ext›" is the archive’s SHA-1 hash (see openssl/sha1), which is optionally recorded in the file "f.‹ext›.CHECKSUM" (but ultimately checked again the file’s actual hash). The valid archive formats are (currently) ".zip", ".tar", ".tgz", ".tar.gz", and ".plt". Other than a type query, which affects inference as described below, any query or fragments parts of a file:// URL are ignored.

  For example, "~/tic-tac-toe.zip" is an archive package source, and its checksum would be optionally recorded inside "~/tic-tac-toe.zip.CHECKSUM".

  An archive represents package content analogous to a directory, but if the archive’s content is contained within a single top-level directory, then the directory’s content (as opposed to the overall archive content) is used as the package content. The ".plt" format does not accommodate either an extra directory layer or a single-collection package representation.

  A package source is inferred to refer to an archive file only when it has a suffix matching a valid archive format and when it starts with file:// or does not start with alphabetic characters followed by ://. In the case that the package source starts with file://, it must be a URL without a type query or with a type query value of file. The inferred package name is the filename without its suffix.

  Changed in version 6.0.1.12: Changed treatment of an archive that contains all content within a top-level directory.
  Changed in version 6.1.1.5: Changed file:// parsing to accept a general URL, recognize a type query, and ignore any other query or fragment.

- a local directory (as a plain path or file:// URL) — The name of the package is the name of the directory. The checksum is not present. Other than a type query, which affects inference as described below, any query or fragments parts of a file:// URL are ignored.

  For example, "~/tic-tac-toe/" is a 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 either starts with file:// or does not start with alphabetic characters followed by ://. In the case that the package source starts with file://, it must be a URL without a type query or with a type query value of dir, link, or static-link. The inferred package name is the directory name.

  When the package source is a file:// URL with a type query value of link or static-link, then the package is installed as directory link, the same as if --link or --static-link is supplied to raco pkg install or raco pkg update.

  Changed in version 6.1.1.5: Changed file:// parsing to accept a general URL, recognize a type query, and ignore any other query or fragment.

- 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 optionally recorded 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.

  When a ".CHECKSUM" file for a remote archive is not available, then the archive is downloaded to compute its checksum. If the remote server provides an ETag header for the downloaded file and recognizes If-None-Match headers, then the ETag value can be used as a shortcut to determine that the file’s checksum has not changed. An ETag-to-checksum mapping is cached in (build-path (find-system-path 'cache-dir) "pkg-etag-checksum.rktd").

  Changed in version 8.16.0.4: Changed the checksum for a remote archive to download and use the archive content when a ".CHECKSUM" file is not available, instead of treating the package as having no checksum.

- 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 the purposes of detecting updates, and there is no constraint on how that checksum is computed.

  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 or a ".git" suffix. The inferred package name is the directory name.

  Changed in version 6.1.1.1: Added special-casing of the ".git" suffix.

- a remote URL naming a Git repository — The format for such URLs is:

  > ‹scheme›://‹host›/.../‹repo›[.git][/][?path=‹path›][#‹rev›]

  where ‹scheme› is git, http, https, git+http, or git+https, except when ‹scheme› is git and ‹host› is github.com (which is treated more specifically as a GitHub reference). The ‹path› can contain multiple /-separated elements to form a path within the repository, and it defaults to the empty path. The ‹rev› can be a branch, tag, or commit, and it defaults to using the default branch as reported by the server.

  > > > Due to properties of the Git protocol, the archive might be accessed more efficiently when ‹rev› refers to a branch or tag (even if it is written as a commit). In those cases, the content typically can be obtained without downloading irrelevant history.

  For example, "http://bitbucket.org/game/tic-tac-toe#main" is a Git package source.

  A checkout of the repository at ‹rev› provides the content of the package, and ‹scheme› determines the protocol that is used to clone the repository. The package’s checksum is the hash identifying ‹rev› if ‹rev› is a branch or tag, otherwise ‹rev› itself serves as the checksum.

  A package source is inferred to be a Git reference when it starts with git:// and the host is not github.com. A package source is also inferred to be a Git reference when it starts with http:// or https:// and the last non-empty path element ends in .git; a .git suffix is added if the source is otherwise specified to be a Git reference. Finally, a package source is inferred to be a Git reference when it starts with git+https:// or git+http://, in which case no .git suffix in the path is needed to designate the source as a Git reference (and no .git suffix is implicitly added). The inferred package name is the last element of ‹path› if it is non-empty, otherwise the inferred name is ‹repo›.

  Changed in version 6.1.1.1: Added Git repository support.
  Changed in version 8.0.0.13: Added git+https:// and git+http:// support.

- a remote URL naming a GitHub repository — The format for such URLs is the same as for a Git repository reference starting git://, but with github.com as the host:

  > git://github.com/‹user›/‹repo›[.git][/][?path=‹path›][#‹rev›]

  For example, "git://github.com/game/tic-tac-toe#main" is a GitHub package source.

  > > > A Github repository source that starts with git:// obtains the same content that would be accessed if github.com were not treated specially. The special treatment is preserved for historical reasons, especially in combination with PLT_USE_GITHUB_API.

  For backward compatibility, an older format is also supported:

  > github://github.com/‹user›/‹repo›/‹rev›[/‹path›]

  The zip-formatted archive for the repository (generated by GitHub for any commit) is used as a remote URL archive path. The checksum is the hash identifying ‹rev› if ‹rev› is a branch or tag, otherwise ‹rev› itself serves as the checksum.

  A package source is inferred to be a GitHub reference when it starts with git://github.com/ or github://; a package source that is otherwise specified as a GitHub reference is automatically prefixed with git://github.com/. The inferred package name is the last element of ‹path› if it is non-empty, otherwise the inferred name is ‹repo›.

  If the PLT_USE_GITHUB_API environment variable is set, GitHub packages are obtained using the GitHub API protocol instead of using the Git protocol.

  Changed in version 6.3: Changed handling of GitHub sources to use the Git protocol by default.

- a package name — A package catalog 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 -.

### 2.3 Package Catalogs🔗ℹ

A package catalog is a server or database that converts package names to other package sources. A package catalog is identified by a string representing a URL, where a http:// or https:// URL indicates a remote server, and a file:// URL indicates a local catalog in the form of an SQLite database or a directory tree.

PLT supports two package catalog servers that are enabled by default: https://pkgs.racket-lang.org for new packages and http://planet-compats.racket-lang.org for automatically generated packages for old PLaneT packages. Anyone may host a package catalog, and any file-serving HTTP host can act as a basic package catalog server. See Package Catalog Protocol for information on how package information is extracted from a catalog.

### 2.4 Explicit vs. Auto-Installation🔗ℹ

When a package is installed, the original source of its installation is recorded, as well as whether the installation was an automatic installation. An automatic installation is one that was installed because it was a dependency of some other package (as opposed to being installed explicitly by a user).

### 2.5 Package Conflicts🔗ℹ

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 base Racket implementation. 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", ".ss", or ".scrbl", with the exception of files named "info.rkt".

### 2.6 Package Updates🔗ℹ

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. A single-collection package can be a package update of a multi-collection package and vice versa.

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.

### 2.7 Package Scopes🔗ℹ

A package scope determines the effect of package installations, updates, etc., with respect to different users and Racket installations. The default package scope can be configured, but it is normally user, which makes actions specific to both the current user and the installation’s name/version (in the sense of get-installation-name). The installation scope means that package operations affect all users of the Racket installation.

A directory path can be used as a package scope, in which case package operations affect the set of packages installations in the directory. An installation can be configured to include the directory in its search path for installed packages (see Installation Configuration and Search Paths). When a directory path is used as a package scope, operations such as dependency checking will use all paths in the configured search path starting with the one that is designed as a package scope; if the designated path is not in the configured search path, then the directory by itself is used as the search path.

Conflict checking disallows installation of the same or conflicting package in different scopes, but if such a configuration is forced, collections are found first in packages with user package scope. Search then proceeds in a configured order, where installation package scope typically precedes other directory package scopes.

The default package scope is determined by first checking the configuration at 'user scope, and then checking for configuration in wider scopes like 'installation. If the default package scope is not configured in any scope, then it defaults to 'user.

top contents ← prev up next →