Open kylewlacy opened 3 months ago
I designed the Brioche Registry to organize package versions in a way that's very similar to Docker: basically, the project is identified by a hash of its contents. Then, we associate the package name plus a tag to a given hash. One project can have multiple tags, each tag can change over time, and we offer a special latest
tag that by convention refers to the latest version of a project.
(Currently, Brioche itself will always resolve a dependency using the latest
tag, this was done as part of the MVP implementation. But, a version tag is also published based on the value of project.version
too)
Here's how I'm currently thinking about handling this feature:
export const projects = {}
object to support setting a otherVersions
key, listing all other "active" versions of a project. version
would still be used as the "latest" version (open to bikeshedding for the names here)versions
(plus latest
)import postgres from "postgres@16.0.0"
), we use the version number to find the right project in the registryBrioche.projectVersion
constant. Really, this could just be a JS getter function that uses (4) to determine the version numberAnd here's what it would look like:
import * as std from "std";
export const project = {
name: "postgresql",
version: "16.0.0",
versions: [
"15.0.0",
"14.0.0",
],
};
export const sources = {
"16.0.0": std.download({ /* ... */ }),
"15.0.0": std.download({ /* ... */ }),
"14.0.0": std.download({ /* ... */ }),
} as const;
export default function() {
const projectVersion = Brioche.projectVersion;
// => Returns "16.0.0", "15.0.0", or "14.0.0" depending on which version was imported
const source = sources[projectVersion];
// ... build Postgres from source ...
}
This I think would be an MVP version of the feature. This could further be extended to handle things like version aliases, like stable
/ beta
/ nightly
in Rust
Projects like Postgres support multiple simultaneous major versions at a time. Users also are likely to want to be able to install a specific major version, e.g. installing Postgres 15.x specifically because that's the version the underlying database targets. Major version upgrades for Postgres are disruptive, and we can't assume all users will be able to upgrade easily, and we should also be able to offer the latest security patches released for previous versions that still get support updates.
Many package managers solve this by having separate packages for each major version, e.g.
postgres14
andpostgres15
(Nixpkgs, Ubuntu apt, etc). Others have a single package name with a specific version number, e.g.postgres@14
andpostgres@15
(Homebrew, Docker, etc).Separate packages for each version are straightforward and simple, but lead to duplicated code across versions, plus it doesn't scale if we want lots of packages to support multiple simultaneous versions.