mirror of
https://github.com/microsoft/vcpkg.git
synced 2024-11-27 19:19:01 +08:00
[RFC][docs] Add pattern matching docs (#27686)
* [docs] add pattern matching docs * Add more examples * Improve default-registry documentation
This commit is contained in:
parent
4c76cc0af7
commit
a22a711815
@ -16,6 +16,7 @@ use, please read [this documentation](../maintainers/registries.md).
|
||||
- [Registry Objects: `"baseline"`](#registry-objects-baseline)
|
||||
- [Registry Objects: `"repository"`](#registry-objects-repository)
|
||||
- [Registry Objects: `"path"`](#registry-objects-path)
|
||||
- [Registry Objects: `"packages"`](#registry-objects-packages)
|
||||
- [Configuration: `"default-registry"`](#configuration-default-registry)
|
||||
- [Configuration: `"registries"`](#configuration-registries)
|
||||
- [Configuration: `"overlay-ports"`](#configuration-overlay-ports)
|
||||
@ -74,21 +75,64 @@ This should be a string, of any repository format that git understands:
|
||||
This should be a path; it can be either absolute or relative; relative paths
|
||||
will be based at the directory the `vcpkg-configuration.json` lives in.
|
||||
|
||||
#### Registry Objects: `"packages"`
|
||||
|
||||
With exception of the default registry and artifacts registries. All registries
|
||||
must declare the packages they provide using the `"packages"` array.
|
||||
|
||||
Each entry in the array must be:
|
||||
* a package name, or
|
||||
* a package prefix.
|
||||
|
||||
Package names may contain only lowercase letters, digits, and `-`. Package names cannot start or end with `-`.
|
||||
|
||||
Package prefixes must follow these rules:
|
||||
* Use the wildcard character: `*`
|
||||
* `*` matches zero or more port name characters (lowercase letters, digits, and `-`).
|
||||
* Contain only one wildcard (`*`)
|
||||
* The wildcard (`*`) must be the last character in the pattern.
|
||||
* All characters before the wildcard `*` must be valid port name characters.
|
||||
|
||||
Examples of valid patterns:
|
||||
* `*`: Matches all port names
|
||||
* `b*`: Matches ports that start with the letter `b`
|
||||
* `boost-*`: Matches ports that start with the prefix `boost-`
|
||||
|
||||
Examples of invalid patterns:
|
||||
* `*a` (`*` must be the last character in the prefix)
|
||||
* `a**` (only one `*` is allowed)
|
||||
* `a+` (`+` is not a valid wildcard)
|
||||
* `a?` (`?` is not a valid wildcard)
|
||||
|
||||
See [package name resolution](#package-name-resolution) for more details.
|
||||
|
||||
### Configuration: `"default-registry"`
|
||||
|
||||
The `"default-registry"` field should be a registry object. It defines
|
||||
the registry that is used for all packages that are not claimed by any
|
||||
package registries. It may also be `null`, in which case no packages that
|
||||
are not claimed by package registries may be installed.
|
||||
The default registry is used as a fallback when resolving package names,
|
||||
if no other registry matches the package name, the default registry will be selected.
|
||||
Users can set the default registry to `null`, in which case, if no other registry matches
|
||||
a package name the install will fail.
|
||||
|
||||
The default registry is either a registry object without a `"packages"` array
|
||||
(since it will automatically match any non-resolved package names) or `null`.
|
||||
|
||||
If `vcpkg-configuration.json` does not declare a `"default-registry"`, vcpkg will
|
||||
automatically set the default registry to the `"builtin-registry"`.
|
||||
|
||||
The `"builtin-registry"` is the local instance of `https://github.com/Microsoft/vcpkg`.
|
||||
This is necessary so that a manifest with no explicit registry configuration can resolve
|
||||
port names in the official vcpkg catalog. The `"builtin-baseline"` property in `vcpkg.json`
|
||||
can be used to set the baseline for the `"builtin-registry"`.
|
||||
|
||||
### Configuration: `"registries"`
|
||||
|
||||
The `"registries"` field should be an array of registry objects, each of
|
||||
which additionally contain a `"packages"` field, which should be an array of
|
||||
package names. These define the package registries, which are used for
|
||||
the specific packages named by the `"packages"` field.
|
||||
The `"registries"` field is used to define additional port and/or artifact registries.
|
||||
|
||||
The `"packages"` fields of all the package registries must be disjoint.
|
||||
Port registries are also required to declare a list of packages they provide using the `"packages"` array.
|
||||
|
||||
Using additional port registries also requires that a baseline is provided for the default registry
|
||||
or that the default registry is set to null. If using the `"builtin-registry"` you can set the baseline
|
||||
using the `"builtin-baseline"` field in `vcpkg.json`.
|
||||
|
||||
### Configuration: `"overlay-ports"`
|
||||
|
||||
@ -140,20 +184,180 @@ overlay triplets from your custom directories. The following
|
||||
|
||||
## Package Name Resolution
|
||||
|
||||
The way package name resolution works in vcpkg is fairly distinct from many
|
||||
package managers. It is very carefully designed to _never_ implicitly choose
|
||||
the registry that a package is fetched from. Just from
|
||||
`vcpkg-configuration.json`, one can tell exactly from which registry a
|
||||
package definition will be fetched from.
|
||||
Package name resolution in vcpkg is designed to be predictable and easy to understand. Given a
|
||||
`vcpkg-configuration.json` file, it should be simple to tell which registry will provide any given port name.
|
||||
|
||||
The name resolution algorithm is as follows:
|
||||
When resolving a port name to a registry, we prioritize as follows:
|
||||
1. Exact match
|
||||
2. Pattern match
|
||||
* Longer prefixes have higher priority, e.g.: when resolving `boost`, `boost*` > `b*` > `*`
|
||||
3. Default registry
|
||||
4. If the default registry has been set to null, emit an error
|
||||
|
||||
- If the name matches an [overlay](#overlays-resolution), use that overlay; otherwise
|
||||
- If there is a package registry that claims the package name,
|
||||
use that registry; otherwise
|
||||
- If there is a default registry defined, use that registry; otherwise
|
||||
- If the default registry is set to `null`, error out; otherwise
|
||||
- use the built-in registry.
|
||||
Package names have higher priority than prefixes even if they both match the same amount of characters.
|
||||
For example, when resolving `boost`: `boost` > `boost*`.
|
||||
|
||||
If there is a tie in priority, vcpkg will use the first registry that declares the package name or prefix.
|
||||
_This makes the order in which registries are declared in the `"registries"` array important._
|
||||
|
||||
### Example #1: Package name resolution
|
||||
|
||||
`vcpkg-configuration.json`
|
||||
```json
|
||||
{
|
||||
"registries": [
|
||||
{
|
||||
"kind": "git",
|
||||
"repository": "https://github.com/northwindtraders/vcpkg-registry",
|
||||
"baseline": "dacf4de488094a384ca2c202b923ccc097956e0c",
|
||||
"packages": ["bei*"]
|
||||
},
|
||||
{
|
||||
"kind": "git",
|
||||
"repository": "https://github.com/vicroms/vcpkg-registry",
|
||||
"baseline": "dacf4de488094a384ca2c202b923ccc097956e0c",
|
||||
"packages": ["beicode", "bei*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
`vcpkg.json`
|
||||
```json
|
||||
{
|
||||
"dependencies": [
|
||||
"beicode",
|
||||
"beison",
|
||||
"fmt"
|
||||
],
|
||||
"builtin-baseline": "7e7c62d863b1bf599c1d104b76cd8b74475844d4"
|
||||
}
|
||||
```
|
||||
|
||||
Given this configuration, each package name resolves to:
|
||||
|
||||
* `beicode`: from registry `https://github.com/vicroms/vcpkg-registry` (exact match on `beicode`)
|
||||
* `beison`: from registry `https://github.com/northwindtraders/vcpkg-registry` (pattern match on `beison` and declared first in `"registries"` array)
|
||||
* `fmt`: from default registry (no matches)
|
||||
|
||||
Because multiple registries declare `bei*`, vcpkg will also emit the following warning:
|
||||
|
||||
```no-highlight
|
||||
Found the following problems in configuration (path/to/vcpkg-configuration.json):
|
||||
$ (a configuration object): warning: Package "bei*" is duplicated.
|
||||
First declared in:
|
||||
location: $.registries[0].packages[0]
|
||||
registry: https://github.com/northwindtraders/vcpkg-registry
|
||||
|
||||
The following redeclarations will be ignored:
|
||||
location: $.registries[1].packages[1]
|
||||
registry: https://github.com/vicroms/vcpkg-registry
|
||||
```
|
||||
|
||||
### Example #2: Overriding the default registry
|
||||
|
||||
There are two ways for a user to override the default registry.
|
||||
|
||||
One way is to use the `"default-registry"` object:
|
||||
```json
|
||||
{
|
||||
"default-registry": {
|
||||
"kind": "git",
|
||||
"repository": "https://github.com/Microsoft/vcpkg",
|
||||
"baseline": "e79c0d2b5d72eb3063cf32a1f7de1a9cf19930f3"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The other way is to set the `"default-registry"` object to null and
|
||||
use the `"*"` pattern in the first registry of the `"registries"` array.
|
||||
```json
|
||||
{
|
||||
"default-registry": null,
|
||||
"registries": [
|
||||
{
|
||||
"kind": "git",
|
||||
"repository": "https://github.com/Microsoft/vcpkg",
|
||||
"baseline": "e79c0d2b5d72eb3063cf32a1f7de1a9cf19930f3",
|
||||
"packages": ["*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
An advantage of the second form is that you can add more entries to the packages array, while the
|
||||
`"default-registry"` object doesn't allow you to define a packages array at all. This difference
|
||||
becomes important in cases where you need to ensure that a package comes from the default registry, like
|
||||
in the example below.
|
||||
|
||||
### Example #3: Ensuring correct name resolution
|
||||
|
||||
Let's consider a registry that provides the Qt Framework libraries.
|
||||
|
||||
`vcpkg-configuration.json`
|
||||
```json
|
||||
{
|
||||
"default-registry": {
|
||||
"kind": "git",
|
||||
"repository": "https://github.com/Microsoft/vcpkg",
|
||||
"baseline": "7e7c62d863b1bf599c1d104b76cd8b74475844d4"
|
||||
},
|
||||
"registries": [
|
||||
{
|
||||
"kind": "git",
|
||||
"repository": "https://github.com/custom-qt/custom-qt-registry",
|
||||
"baseline": "adfc4de488094a384ca2c202b923ccc097956e0c",
|
||||
"packages": ["qt*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
And the following project dependencies:
|
||||
|
||||
`vcpkg.json`
|
||||
```json
|
||||
{
|
||||
"dependencies": [
|
||||
"qt5",
|
||||
"qt-advanced-docking-system",
|
||||
"qtkeychain"
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
The `"qt*"` pattern matches all port names in `vcpkg.json`. But there is a problem!
|
||||
The ports `qt-advanced-docking-system` and `qtkeychain` are not part of the official Qt Framework libraries,
|
||||
and since vcpkg won't be able to find the ports in the custom registry the installation will fail.
|
||||
|
||||
The obvious solution is to make sure that these packages come from the default registry instead,
|
||||
we can accomplish that by changing the way we declare the default registry and adding `qt-advanced-docking-system`
|
||||
and `qtkeychain` to its `"packages"` array:
|
||||
|
||||
`vcpkg-configuration.json`
|
||||
```json
|
||||
{
|
||||
"default-registry": null,
|
||||
"registries": [
|
||||
{
|
||||
"kind": "git",
|
||||
"repository": "https://github.com/Microsoft/vcpkg",
|
||||
"baseline": "e79c0d2b5d72eb3063cf32a1f7de1a9cf19930f3",
|
||||
"packages": ["*", "qt-advanced-docking-system", "qtkeychain"]
|
||||
},
|
||||
{
|
||||
"kind": "git",
|
||||
"repository": "https://github.com/custom-qt/custom-qt-registry",
|
||||
"baseline": "adfc4de488094a384ca2c202b923ccc097956e0c",
|
||||
"packages": ["qt*"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
Because exact matches are preferred over pattern matches, this configuration will make
|
||||
`qt-advanced-docking-system` and `qtkeychain` resolve to the default registry.
|
||||
|
||||
### Overlays Resolution
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user