Design - adept-dm/adept GitHub Wiki

  • Git is used manage repositories
  • Repository contains the metadata
  • Modules modules are stored in "variants" which represents a set of ids, attributes, artifact references and requirements/dependencies. A "variant" is the Adept equivalent of a version, but you might have multiple variants per version (for example with different dependencies).
  • Build tools, such as SBT, Gradle (not currently supported), Ant (not currently supported) uses Adept to create their classpath based on a set of modules.

Resolution algorithm

The resolution scheme in Adept is very simple (in fact it is only 180 LOC). The input for resolution is a set of ids (e.g. com.typesafe.akka/akka-actor, org.scala-lang/scala-library) and constraints (e.g. "binary-version" = 2.10), called 'requirements'.

When Adept starts resolution it will try to load the variants matching the requirements. If there is exactly one variant matching the id, Adept will continue resolution by loading the requirements of the resolved variant. The output can be one of 3 states: resolved, under-constrained (too few constraints) or over-constrained (too many constraints). If under-constrained, Adept's resolution engine can try to find one path among the available variants that resolves the graph.

Storage scheme

All metadata in Adept is stored in Git.

For a given commit in Git, there might be multiple variants (in the case where there might be multiple binary-versions for example).

A variant can "require" other variants. In this case, the repository name and commit of all transitive required variants are stored as well.

A variant can also link to artifacts. An artifact is essentially the hash and the locations (plural) of a file.

Configurations

Configurations makes it possible to separate different views of the same artifacts, such as what is required to compile ("compile") or to execute a library ("runtime"). Adept supports the same notion of configuration as Ivy, and by extension scopes in Maven.

Although configurations are a concept in the metadata, Adept's resolution knows nothing about configurations,. Instead configurations are mapped to requirements of variants. The "runtime" variant of com.typesafe.akka/akka-actor are stored internally as com.typesafe.akka/akka-actor/config/runtime. If "runtime" extends "compile", com.typesafe.akka/akka-actor/config/runtime simply requires com.typesafe.akka/akka-actor/config/compile, in addition to a base requirement: com.typesafe.akka/akka-actor which avoids issues where it would be possible for different variants to require different variants com.typesafe.akka/akka-actor.

Conflict resolution

Adept does not do any conflict resolution when resolving, and it is not possible that multiple variants have overlapping constraints (for example: one variant requires version A and another variant requires version B of the same id). The reason for this is that we want to know if a variant requires a variant which is not compatible with another, but we want resolution to be able to consider all variants as valid solution(s).

Therefore, each repository commit represents a valid state. This means that semantically versioned module might have versions: {1.0.6, 1.1.2, 2.0.1}, another (later commit) might have {1.0.6, 1.1.3, 2.0.2}.

When loading repositories Adept always takes the latest commit for a given id, if there are more than one. This makes it possible for library authors to their own definitions of what is best. For users this makes Adept chose the best version, without sacrificing the strictness in resolution.

It also makes it possible to safely retire a variant or update a wrongly published variant.

Metadata changes

Adept will support metadata changes. Since commits represents the "bestness" of modules, metadata changes are stored in branches. It will be possible for Adept to compare different branches (if these branches are indeed comparable). The way this will be done is to store a file that maps commits from one branch to another.

File layout

  • repos/
    • repo-name
      • variants/
        • variant id/*.json
      • artifacts/
        • variant id/*.json
      • repo-metadata/
        • variant id/*.json