dsh 0.2.0-rc.2: in-container update (experimental channel), path-agnostic compose, upstream patches adapted to 0.1.x/0.2.x
This commit is contained in:
commit
e6dcef9bf5
302 files changed
+75178
No files matched your search
@@ -0,0 +1,92 @@
|
||||
import { exactKeys, parseJsonDocument, TrustError } from './validation.mjs'
|
||||
|
||||
const SEMVER = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/
|
||||
|
||||
function parseSemver(value, label) {
|
||||
if (typeof value !== 'string') throw new TrustError(`${label} must be a semantic version`)
|
||||
const match = SEMVER.exec(value)
|
||||
if (match === null) throw new TrustError(`${label} must be a semantic version`)
|
||||
const prerelease = match[4] === undefined ? [] : match[4].split('.')
|
||||
for (const identifier of prerelease) {
|
||||
if (/^\d+$/.test(identifier) && identifier.length > 1 && identifier.startsWith('0')) {
|
||||
throw new TrustError(`${label} has an invalid numeric prerelease identifier`)
|
||||
}
|
||||
}
|
||||
return {
|
||||
core: match.slice(1, 4),
|
||||
prerelease,
|
||||
}
|
||||
}
|
||||
|
||||
function compareNumeric(left, right) {
|
||||
if (left.length !== right.length) return left.length < right.length ? -1 : 1
|
||||
if (left === right) return 0
|
||||
return left < right ? -1 : 1
|
||||
}
|
||||
|
||||
function compareIdentifier(left, right) {
|
||||
const leftNumeric = /^\d+$/.test(left)
|
||||
const rightNumeric = /^\d+$/.test(right)
|
||||
if (leftNumeric && rightNumeric) return compareNumeric(left, right)
|
||||
if (leftNumeric !== rightNumeric) return leftNumeric ? -1 : 1
|
||||
if (left === right) return 0
|
||||
return left < right ? -1 : 1
|
||||
}
|
||||
|
||||
export function compareSemanticVersions(leftValue, rightValue, leftLabel = 'left version', rightLabel = 'right version') {
|
||||
const left = parseSemver(leftValue, leftLabel)
|
||||
const right = parseSemver(rightValue, rightLabel)
|
||||
for (let index = 0; index < left.core.length; index += 1) {
|
||||
const compared = compareNumeric(left.core[index], right.core[index])
|
||||
if (compared !== 0) return compared
|
||||
}
|
||||
if (left.prerelease.length === 0 || right.prerelease.length === 0) {
|
||||
return left.prerelease.length === right.prerelease.length ? 0 : left.prerelease.length === 0 ? 1 : -1
|
||||
}
|
||||
const length = Math.max(left.prerelease.length, right.prerelease.length)
|
||||
for (let index = 0; index < length; index += 1) {
|
||||
if (left.prerelease[index] === undefined) return -1
|
||||
if (right.prerelease[index] === undefined) return 1
|
||||
const compared = compareIdentifier(left.prerelease[index], right.prerelease[index])
|
||||
if (compared !== 0) return Math.sign(compared)
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
export function compareDshVersions(leftValue, rightValue) {
|
||||
return compareSemanticVersions(leftValue, rightValue, 'left DSH version', 'right DSH version')
|
||||
}
|
||||
|
||||
export function parseSupportedTarget(bytes) {
|
||||
const object = parseJsonDocument(bytes, 'supported target')
|
||||
exactKeys(object, ['environment', 'latestSupportedDsh', 'schema'], 'supported target')
|
||||
if (object.schema !== 1) throw new TrustError('supported target schema must be 1')
|
||||
parseSemver(object.latestSupportedDsh, 'latestSupportedDsh')
|
||||
if (typeof object.environment !== 'string' || !/^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/.test(object.environment)) {
|
||||
throw new TrustError('supported target environment is invalid')
|
||||
}
|
||||
return Object.freeze({
|
||||
schema: 1,
|
||||
latestSupportedDsh: object.latestSupportedDsh,
|
||||
environment: object.environment,
|
||||
})
|
||||
}
|
||||
|
||||
export function validateSupportedTarget(targetBytes, environmentDefinitionBytes) {
|
||||
const target = parseSupportedTarget(targetBytes)
|
||||
const definition = parseJsonDocument(environmentDefinitionBytes, 'environment definition')
|
||||
if (definition.version !== target.environment) {
|
||||
throw new TrustError(`supported Environment ${JSON.stringify(target.environment)} does not match definition ${JSON.stringify(definition.version)}`)
|
||||
}
|
||||
return target
|
||||
}
|
||||
|
||||
export function advanceSupportedDsh(target, upstreamVersion) {
|
||||
const comparison = compareDshVersions(upstreamVersion, target.latestSupportedDsh)
|
||||
if (comparison < 0) throw new TrustError('upstream DSH version would roll back Latest Supported')
|
||||
if (comparison === 0) return Object.freeze({ changed: false, target })
|
||||
return Object.freeze({
|
||||
changed: true,
|
||||
target: Object.freeze({ ...target, latestSupportedDsh: upstreamVersion }),
|
||||
})
|
||||
}
|
||||
Reference in new issue
Block a user