Declarative prescriptions for resolver

The implementation of the resolver allows to declaratively specify pipeline units that should be included in the resolver pipeline during the resolution process without actually implementing any code. The document below describes core mechanics behind creating such “prescriptions” for the resolver.

Note

Check thoth-station/prescriptions repository that provides prescriptions for open-source Python packages.

See also this pull request for a reference on how to implement a specific pipeline unit type that extends resolver functionality. A high level overview can be found in the following YouTube video.

One can see prescriptions as enhanced constraints but on the server side. This way constraints can be generalized and applied also for multiple projects for which server-side resolution can provide guidance.

Note

The declarative prescription interface allows to quickly provide pipeline units that assist the resolution process but have limited expressive capabilities. For more sophisticated pipeline units one can still use the programmable interface.

Examples to quickly write a new prescription

Here are few prescription examples to inspire for a quick creation of new prescriptions:

Prescriptions structure

Prescriptions are written in a form of YAML files that are maintained in a Git repository. An example of such a directory structure can be found at thoth-station/prescriptions.

A repository with prescriptions must state a metadata file keeping generic information for prescriptions. This file is named _prescription_metadata.yaml and metadata stated in this file are inherited to all units declared in sub-directories living besides the metadata file.

The content of the metadata file is (an example):

prescription:
  name: <name>
  release: <release>

The value stated in prescription.name acts as a namespace for prescriptions. If you use multiple Git repositories with prescriptions, you do not need to worry about any naming collisions unless you make sure these prescriptions live in a separate namespace (have different values of prescription.name).

The identifier stated in prescription.release states release information about prescriptions.

Note

Check the resolution log to see what prescriptions in which versions are used during the resolution process.

Each sub-directory keeps information about prescriptions. It is a convention to put package specific prescriptions into sub-directories which match package names. Any generic or package agnostic prescriptions can be placed into sub-directories prefixed with and underscore (e.g. _generic). The name of the YAML files are then determined based on the unit semantics written there.

Note

If you are a package maintainer or you would like to follow updates for a specific set of prescriptions, you can add yourself to CODEOWNERS file and follow updates only for a specific sub-directory.

Unit schema

Note

See schema.py file in adviser’s implementation for a more detailed schema overview.

Units are stated in units listing in the corresponding YAML file respecting unit’s base type:

units:
  boots: []
  pseudonyms: []
  sieves: []
  steps: []
  strides: []
  wraps: []
metadata:
  <key>: <value>

Each unit, regardless of its type, has the following schema:

name: '<unit_name>'
type: '<unit_type>'
metadata:
  <key>: <value>
should_include:
  <should_include_section>
match:
  <match_section>
run:
  <run_section>

The semantics behind entries:

name

Name of the unit that uniquely identifies the unit of the specific type within the prescription namespace in which unit is declared.

All the units created based on prescription live in their own namespace that is specified by the name of the prescription. This makes sure prescriptions do not clash even if multiple prescriptions are supplied.

type

Each prescription pipeline unit can be of a base type boot, pseudonym, sieve, step, stride and wrap or any derived type from the base types. The derived types provide certain additional functionality in opposite to the base types. See corresponding prescription pipeline unit documentation for available types.

metadata

This field keeps metadata associated with the given prescription in a form of key: value pairs - key is of type string and value is any JSON serializable object. These metadata are not used during the resolution process and can be used by tools that integrate with prescriptions. This applies for prescription unit metadata as well as for metadata stored on YAML file level.

should_include

See the following documentation for more info.

match

This section is specific to a pipeline unit type used.

run

This section is specific to a pipeline unit type used.