ActorSimulation.TemplateVersions (GenServerVirtualTime v0.6.1)

Copy Markdown View Source

The third-party versions that the code generators pin in the projects they emit.

A generated project is a real project: it has a conanfile.txt, a go.mod, a Cargo.toml, a pom.xml and a CI workflow of its own. Each of those pins versions, and those pins drift. Keeping the literals scattered across six generator modules made drift invisible; this module makes it a single table that can be read, reviewed, and upgraded.

Generators read versions through get/1, for example:

ActorSimulation.TemplateVersions.get(:caf)

Checking for drift

mix templates.upgrade --check

Upgrading

mix templates.upgrade

sources/0 records where each version comes from, so mix templates.upgrade can ask upstream for the latest release. Versions marked :manual have no meaningful upstream (a language level, a minimum CMake, a floating release channel) and are reported but never rewritten automatically.

Generated projects

The generated project templates and the projects checked into examples/ and generated/ come from the same generators, so after upgrading run mix templates.upgrade --examples to regenerate the checked-in ones.

Summary

Functions

Every pin in presentation order, as {key, version} pairs.

A human-readable description of source, used as the trailing comment in the rendered version table.

The version pinned under key.

The major component of key's version, or nil when the pin is not a version at all (a release channel, or a Go pseudo-version).

Where each pin comes from, in the order the table should be presented.

Every pinned version as a map.

Functions

all()

@spec all() :: [{atom(), String.t()}]

Every pin in presentation order, as {key, version} pairs.

describe(arg)

@spec describe(term()) :: String.t()

A human-readable description of source, used as the trailing comment in the rendered version table.

get(key)

@spec get(atom()) :: String.t()

The version pinned under key.

Raises KeyError for a key that is not in the table.

Examples

iex> ActorSimulation.TemplateVersions.get(:checkout_action) |> String.starts_with?("v")
true

major(key)

@spec major(atom()) :: String.t() | nil

The major component of key's version, or nil when the pin is not a version at all (a release channel, or a Go pseudo-version).

Templates that must name a major (a CMake package major, a JS library major) use this instead of repeating the digit, so the major cannot drift away from the pinned version.

Examples

iex> ActorSimulation.TemplateVersions.major(:caf)
"1"

iex> ActorSimulation.TemplateVersions.major(:ponyc_channel)
nil

sources()

@spec sources() :: [{atom(), term()}]

Where each pin comes from, in the order the table should be presented.

A source is {kind, target, transform}:

  • {:conan_center, package, transform} — ConanCenter recipes
  • {:crates_io, crate, transform} — crates.io
  • {:go_module, module, transform} — the Go module proxy
  • {:maven_central, "group:artifact", transform} — Maven Central metadata
  • {:github_release, "owner/repo", transform} — the latest GitHub release
  • {:github_tags, "owner/repo", transform} — the highest semver tag, for repositories whose newest release is not the library we pin (Mermaid)
  • {:manual, reason, :none} — deliberately not tracked against an upstream

transform says how much of the upstream version we take:

  • :version — the whole version ("6.2.0")
  • :latest_within_major — the newest release on the current major, so a script never pushes a generated project across a breaking major
  • :major — only the major ("11"), for pins that float within it
  • :major_tag — "v7", how GitHub Actions are pinned
  • :raw — the upstream value untouched ("v0.0.0-2022...")

versions()

@spec versions() :: %{required(atom()) => String.t()}

Every pinned version as a map.

Examples

iex> ActorSimulation.TemplateVersions.get(:caf) |> is_binary()
true