Skip to content

Commit

Permalink
Centralise versioning configuration (#176)
Browse files Browse the repository at this point in the history
The goal here is to centralise the logic around versions, creating a
list of all the details about each version (e.g. full version number,
whether it's a pre-release or unmaintained etc.), that downstream
processing can reference directly rather than recompute. This, for
instance, eliminates the duplicated logic around which versions are
maintained.

The goal here is to make changes like #174 (and maybe #159) easier. This
PR doesn't/shouldn't change observable behaviour.

This also removes the explicit `disableVersioning` flag, since that
seems to require changing the contents of the `versions` map. Instead
the existing use of `onlyIncludeVersions` seems to do what's intended:
make dev builds faster. An `npm start` build takes about 10s both with
the old `disableVersioning` setting, or just relying on
`onlyIncludeVersions`.

This includes some cut-and-paste rearrangement too that makes the diff
harder to understand. The commits are individually reviewable.
  • Loading branch information
huonw authored Mar 12, 2024
1 parent 0bcc0a0 commit 04263c1
Showing 1 changed file with 117 additions and 56 deletions.
173 changes: 117 additions & 56 deletions docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,53 +11,40 @@ import { themes as prismThemes } from "prism-react-renderer";
const organizationName = "pantsbuild";
const projectName = "pantsbuild.org";

function getCurrentVersion() {
const lastReleasedVersion = versions[0];
const version = parseInt(lastReleasedVersion.replace("2.", ""), 10);
return `2.${version + 1}`;
}
const numberOfSupportedStableVersions = 2;

// Controls for how much to build:
// - (No env vars set) -> Just uses the docs from `/docs/` (Docusaurus calls this "current version"), and no blog.
// - PANTSBUILD_ORG_INCLUDE_VERSIONS=<version>,<version> -> Use current version and versions specified
// - PANTSBUILD_ORG_INCLUDE_BLOG=1 -> Include the blog.
// Note that `NODE_ENV === 'production' builds _everything_.
const isDev = process.env.NODE_ENV === "development";
const disableVersioning =
isDev && process.env.PANTSBUILD_ORG_INCLUDE_VERSIONS === undefined;

// Versions
const onlyIncludeVersions = isDev
? process.env.PANTSBUILD_ORG_INCLUDE_VERSIONS
? ["current"].concat(
(process.env.PANTSBUILD_ORG_INCLUDE_VERSIONS || "").split(",")
)
: ["current"]
: undefined;
const currentVersion = getCurrentVersion();
const includeBlog = process.env.PANTSBUILD_ORG_INCLUDE_BLOG === "1" || !isDev;

const formatCopyright = () => {
const makeLink = (href, text) => `<a href="${href}">${text}</a>`;

const repoUrl = `https://github.com/${organizationName}/${projectName}`;
const repoLink = makeLink(repoUrl, "Website source");
function getCurrentVersion() {
const lastReleasedVersion = versions[0];
const version = parseInt(lastReleasedVersion.replace("2.", ""), 10);
return `2.${version + 1}`;
}

// Only set by CI, so fallback to just `local` for local dev
const docsCommit = process.env.GITHUB_SHA;
const commitLink = docsCommit
? makeLink(`${repoUrl}/commit/${docsCommit}`, docsCommit.slice(0, 6))
: "local";
const currentVersion = getCurrentVersion();

return `Copyright © Pants project contributors. ${repoLink} @ ${commitLink}.`;
};
const isCurrentVersion = (shortVersion) => shortVersion === currentVersion;

const isPrerelease = (version) => {
const reference_dir = path.join(
"versioned_docs",
`version-${version}`,
"reference"
);
const getFullVersion = (shortVersion) => {
const parentDir = isCurrentVersion(shortVersion)
? "docs"
: path.join("versioned_docs", `version-${shortVersion}`);
const helpAll = JSON.parse(
fs.readFileSync(path.join(reference_dir, "help-all.json"), "utf8")
fs.readFileSync(path.join(parentDir, "reference", "help-all.json"), "utf8")
);

const pantsVersion = helpAll["scope_to_help_info"][""]["advanced"].find(
Expand All @@ -68,12 +55,106 @@ const isPrerelease = (version) => {
(value) => value["rank"] == "HARDCODED"
);

return hardcoded["value"];
};

const isPrereleaseVersion = (fullVersion) => {
// Check if it's one of xx.xx.0.dev0, xx.xx.0a0, xx.xx.0b0, xx.xx.0rc0, etc.
// We don't treat patch versions pre-releases as pre-releases, since it looks weird.
// Optimally we shouldn't sync those either way, but some have ended up here by accident.
const rex = /^(\d+\.\d+\.0)(\.dev|a|b|rc)\d+$/;

return rex.test(hardcoded["value"]);
return rex.test(fullVersion);
};

const getVersionDetails = () => {
const versionDetails = [];

let seenStableVersions = 0;

// Construct the configuration for each version. NB. iterating from newest to oldest is important,
// to be able to label too-old stable versions as unsupported.
for (const shortVersion of [currentVersion, ...versions]) {
const fullVersion = getFullVersion(shortVersion);

// NB. "maintained" versions includes pre-releases
const isMaintained = seenStableVersions < numberOfSupportedStableVersions;
const isPrerelease = isPrereleaseVersion(fullVersion);
const isCurrent = isCurrentVersion(shortVersion);

// compute the appropriate configuration this version
let config;
if (isCurrent) {
// current version => dev
config = {
label: `${shortVersion} (dev)`,
};
} else if (isPrerelease) {
// prerelease => prerelease
config = {
label: `${shortVersion} (prerelease)`,
banner: "unreleased",
noIndex: false,
};
} else if (isMaintained) {
// a new-enough stable version => so still supported
config = {
label: shortVersion,
banner: "none",
noIndex: false,
};
} else {
// stable, but too old => deprecated
config = {
label: `${shortVersion} (deprecated)`,
banner: "unmaintained",
noIndex: true,
};
}

versionDetails.push({
shortVersion,
fullVersion,
isMaintained,
isPrerelease,
isCurrent,
config: {
...config,
path: shortVersion,
},
});

if (!isPrerelease) {
seenStableVersions += 1;
}
}

return versionDetails;
};

const versionDetails = getVersionDetails();

const mostRecentStableVersion = versionDetails.find(
({ isPrerelease }) => !isPrerelease
);

// Blog
const includeBlog = process.env.PANTSBUILD_ORG_INCLUDE_BLOG === "1" || !isDev;

// Other information
const formatCopyright = () => {
const makeLink = (href, text) => `<a href="${href}">${text}</a>`;

const repoUrl = `https://github.com/${organizationName}/${projectName}`;
const repoLink = makeLink(repoUrl, "Website source");

// Only set by CI, so fallback to just `local` for local dev
const docsCommit = process.env.GITHUB_SHA;
const commitLink = docsCommit
? makeLink(`${repoUrl}/commit/${docsCommit}`, docsCommit.slice(0, 6))
: "local";

return `Copyright © Pants project contributors. ${repoLink} @ ${commitLink}.`;
};

const config = {
Expand Down Expand Up @@ -331,36 +412,16 @@ const config = {
{
sidebarPath: require.resolve("./sidebars.js"),
routeBasePath: "/",
disableVersioning,
onlyIncludeVersions,
lastVersion: onlyIncludeVersions
? undefined
: versions.find((v) => !isPrerelease(v)),
versions: {
current: {
label: `${currentVersion} (dev)`,
path: currentVersion,
},
...(disableVersioning
? {}
: versions.reduce((acc, version, index) => {
acc[version] = {
label: isPrerelease(version)
? `${version} (prerelease)`
: index < 2 + (isPrerelease(versions[0]) ? 1 : 0)
? version
: `${version} (deprecated)`,
banner: isPrerelease(version)
? "unreleased"
: index < 2 + (isPrerelease(versions[0]) ? 1 : 0)
? "none"
: "unmaintained",
noIndex: index >= 2 + (isPrerelease(versions[0]) ? 1 : 0),
path: version,
};
return acc;
}, {})),
},
: mostRecentStableVersion.shortVersion,
versions: Object.fromEntries(
versionDetails.map(({ isCurrent, shortVersion, config }) => [
isCurrent ? "current" : shortVersion,
config,
])
),
remarkPlugins: [captionedCode, tabBlocks],
editUrl: ({ docPath }) => {
if (docPath.startsWith("reference/")) {
Expand Down

0 comments on commit 04263c1

Please sign in to comment.