@opendevise/antora-release-line-extension
Version:
An Antora extension that identifies and adds URL routing for SemVer release lines.
66 lines (60 loc) • 3.03 kB
JavaScript
const SemVerRx = /^\d+\.\d+\.\d+$/
module.exports.register = function () {
this.once('componentsRegistered', ({ contentCatalog }) => {
const latestPerReleaseLineByComponent = new Map()
for (const { name, versions } of contentCatalog.getComponentsSortedBy('name')) {
const latestPerReleaseLine = new Map()
for (const componentVersion of versions.slice().reverse()) {
const { version, prerelease } = componentVersion
if (!SemVerRx.test(version)) continue
const { major, minor } = extractMajorMinor(version)
if (!latestPerReleaseLine.has(major) || !prerelease || latestPerReleaseLine.get(major).prerelease) {
latestPerReleaseLine.set(major, componentVersion)
}
if (!latestPerReleaseLine.has(minor) || !prerelease || latestPerReleaseLine.get(minor).prerelease) {
latestPerReleaseLine.set(minor, componentVersion)
}
}
for (const [releaseLine, componentVersion] of new Map(latestPerReleaseLine)) {
const level = ~releaseLine.indexOf('.') ? 'minor' : 'major'
if (level === 'minor') componentVersion.versionSegment = releaseLine
latestPerReleaseLine.set(releaseLine, { level, version: componentVersion.version })
}
latestPerReleaseLineByComponent.set(name, new Map([...latestPerReleaseLine].sort(releaseLineCompareDesc)))
}
this.updateVariables({ latestPerReleaseLineByComponent })
})
this.once('contentClassified', ({ contentCatalog, latestPerReleaseLineByComponent }) => {
for (const [name, latestPerReleaseLine] of latestPerReleaseLineByComponent) {
if (!latestPerReleaseLine.size) continue
const { version: latestVersion } = contentCatalog.getComponent(name).latest
for (const [abbrVersion, { level, version: actualVersion }] of latestPerReleaseLine) {
let fromVersionSegment, toVersionSegment
if (level === 'major') {
fromVersionSegment = abbrVersion
toVersionSegment = contentCatalog.getComponentVersion(name, actualVersion).activeVersionSegment
} /* level === 'minor' */ else {
fromVersionSegment = actualVersion
if (actualVersion === latestVersion) {
toVersionSegment = contentCatalog.getComponentVersion(name, actualVersion).activeVersionSegment
if (toVersionSegment === actualVersion) continue // sanity check
} else {
toVersionSegment = abbrVersion
}
}
contentCatalog.addSplatAlias(
{ versionSegment: fromVersionSegment },
{ component: name, version: actualVersion, versionSegment: toVersionSegment }
)
}
}
})
}
function extractMajorMinor (version) {
const majorMinorSegments = version.split('.').slice(0, 2)
return { major: majorMinorSegments[0], minor: majorMinorSegments.join('.') }
}
function releaseLineCompareDesc ([a1, a2], [b1, b2]) {
return -(a2.level === 'major' ? a1 + '.a' : a1).localeCompare(b2.level === 'major' ? b1 + '.a' : b1)
}