mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
fix issues with legacy packages (#2841)
* fix issues with legacy packages * include non-prerelease versions within compat range * lock sdk to corresponding os prerelease * bump sdk version * fixes from PR review
This commit is contained in:
@@ -1,4 +1,9 @@
|
||||
import { ExtendedVersion, types as T, utils } from "@start9labs/start-sdk"
|
||||
import {
|
||||
ExtendedVersion,
|
||||
types as T,
|
||||
utils,
|
||||
VersionRange,
|
||||
} from "@start9labs/start-sdk"
|
||||
import * as fs from "fs/promises"
|
||||
|
||||
import { polyfillEffects } from "./polyfillEffects"
|
||||
@@ -345,7 +350,8 @@ export class SystemForEmbassy implements System {
|
||||
const previousVersion = await effects.getDataVersion()
|
||||
if (previousVersion) {
|
||||
if (
|
||||
(await this.migration(effects, previousVersion, timeoutMs)).configured
|
||||
(await this.migration(effects, { from: previousVersion }, timeoutMs))
|
||||
.configured
|
||||
) {
|
||||
await effects.action.clearRequests({ only: ["needs-config"] })
|
||||
}
|
||||
@@ -542,7 +548,10 @@ export class SystemForEmbassy implements System {
|
||||
nextVersion: Optional<string>,
|
||||
timeoutMs: number | null,
|
||||
): Promise<void> {
|
||||
// TODO Do a migration down if the version exists
|
||||
await this.currentRunning?.clean({ timeout: timeoutMs ?? undefined })
|
||||
if (nextVersion) {
|
||||
await this.migration(effects, { to: nextVersion }, timeoutMs)
|
||||
}
|
||||
await effects.setMainStatus({ status: "stopped" })
|
||||
}
|
||||
|
||||
@@ -746,46 +755,37 @@ export class SystemForEmbassy implements System {
|
||||
|
||||
async migration(
|
||||
effects: Effects,
|
||||
fromVersion: string,
|
||||
version: { from: string } | { to: string },
|
||||
timeoutMs: number | null,
|
||||
): Promise<{ configured: boolean }> {
|
||||
const fromEmver = ExtendedVersion.parseEmver(fromVersion)
|
||||
const currentEmver = ExtendedVersion.parseEmver(this.manifest.version)
|
||||
if (!this.manifest.migrations) return { configured: true }
|
||||
const fromMigration = Object.entries(this.manifest.migrations.from)
|
||||
.map(
|
||||
([version, procedure]) =>
|
||||
[ExtendedVersion.parseEmver(version), procedure] as const,
|
||||
)
|
||||
.find(
|
||||
([versionEmver, procedure]) =>
|
||||
versionEmver.greaterThan(fromEmver) &&
|
||||
versionEmver.lessThanOrEqual(currentEmver),
|
||||
)
|
||||
const toMigration = Object.entries(this.manifest.migrations.to)
|
||||
.map(
|
||||
([version, procedure]) =>
|
||||
[ExtendedVersion.parseEmver(version), procedure] as const,
|
||||
)
|
||||
.find(
|
||||
([versionEmver, procedure]) =>
|
||||
versionEmver.greaterThan(fromEmver) &&
|
||||
versionEmver.lessThanOrEqual(currentEmver),
|
||||
)
|
||||
|
||||
// prettier-ignore
|
||||
const migration = (
|
||||
fromEmver.greaterThan(currentEmver) ? [toMigration, fromMigration] :
|
||||
[fromMigration, toMigration]).filter(Boolean)[0]
|
||||
let migration
|
||||
let args: [string, ...string[]]
|
||||
if ("from" in version) {
|
||||
args = [version.from, "from"]
|
||||
const fromExver = ExtendedVersion.parse(version.from)
|
||||
if (!this.manifest.migrations) return { configured: true }
|
||||
migration = Object.entries(this.manifest.migrations.from)
|
||||
.map(
|
||||
([version, procedure]) =>
|
||||
[VersionRange.parseEmver(version), procedure] as const,
|
||||
)
|
||||
.find(([versionEmver, _]) => versionEmver.satisfiedBy(fromExver))
|
||||
} else {
|
||||
args = [version.to, "to"]
|
||||
const toExver = ExtendedVersion.parse(version.to)
|
||||
if (!this.manifest.migrations) return { configured: true }
|
||||
migration = Object.entries(this.manifest.migrations.to)
|
||||
.map(
|
||||
([version, procedure]) =>
|
||||
[VersionRange.parseEmver(version), procedure] as const,
|
||||
)
|
||||
.find(([versionEmver, _]) => versionEmver.satisfiedBy(toExver))
|
||||
}
|
||||
|
||||
if (migration) {
|
||||
const [version, procedure] = migration
|
||||
const [_, procedure] = migration
|
||||
if (procedure.type === "docker") {
|
||||
const commands = [
|
||||
procedure.entrypoint,
|
||||
...procedure.args,
|
||||
JSON.stringify(fromVersion),
|
||||
]
|
||||
const commands = [procedure.entrypoint, ...procedure.args]
|
||||
const container = await DockerProcedureContainer.of(
|
||||
effects,
|
||||
this.manifest.id,
|
||||
@@ -794,7 +794,11 @@ export class SystemForEmbassy implements System {
|
||||
`Migration - ${commands.join(" ")}`,
|
||||
)
|
||||
return JSON.parse(
|
||||
(await container.execFail(commands, timeoutMs)).stdout.toString(),
|
||||
(
|
||||
await container.execFail(commands, timeoutMs, {
|
||||
input: JSON.stringify(args[0]),
|
||||
})
|
||||
).stdout.toString(),
|
||||
)
|
||||
} else if (procedure.type === "script") {
|
||||
const moduleCode = await this.moduleCode
|
||||
@@ -803,7 +807,7 @@ export class SystemForEmbassy implements System {
|
||||
throw new Error("Expecting that the method migration exists")
|
||||
return (await method(
|
||||
polyfillEffects(effects, this.manifest),
|
||||
fromVersion as string,
|
||||
...args,
|
||||
).then((x) => {
|
||||
if ("result" in x) return x.result
|
||||
if ("error" in x) throw new Error("Error getting config: " + x.error)
|
||||
@@ -1177,9 +1181,14 @@ function extractServiceInterfaceId(manifest: Manifest, specInterface: string) {
|
||||
return serviceInterfaceId
|
||||
}
|
||||
async function convertToNewConfig(value: OldGetConfigRes) {
|
||||
const valueSpec: OldConfigSpec = matchOldConfigSpec.unsafeCast(value.spec)
|
||||
const spec = transformConfigSpec(valueSpec)
|
||||
if (!value.config) return { spec, config: null }
|
||||
const config = transformOldConfigToNew(valueSpec, value.config)
|
||||
return { spec, config }
|
||||
try {
|
||||
const valueSpec: OldConfigSpec = matchOldConfigSpec.unsafeCast(value.spec)
|
||||
const spec = transformConfigSpec(valueSpec)
|
||||
if (!value.config) return { spec, config: null }
|
||||
const config = transformOldConfigToNew(valueSpec, value.config) ?? null
|
||||
return { spec, config }
|
||||
} catch (e) {
|
||||
console.error(e)
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
@@ -444,8 +444,8 @@ function parseDfOutput(output: string): { used: number; total: number } {
|
||||
.map((x) => x.split(/\s+/))
|
||||
const index = lines.splice(0, 1)[0].map((x) => x.toLowerCase())
|
||||
const usedIndex = index.indexOf("used")
|
||||
const availableIndex = index.indexOf("available")
|
||||
const sizeIndex = index.indexOf("size")
|
||||
const used = lines.map((x) => Number.parseInt(x[usedIndex]))[0] || 0
|
||||
const total = lines.map((x) => Number.parseInt(x[availableIndex]))[0] || 0
|
||||
const total = lines.map((x) => Number.parseInt(x[sizeIndex]))[0] || 0
|
||||
return { used, total }
|
||||
}
|
||||
|
||||
@@ -166,6 +166,8 @@ export function transformOldConfigToNew(
|
||||
|
||||
delete config[key][val.tag.id]
|
||||
|
||||
if (!val.variants[selection]) return obj
|
||||
|
||||
newVal = {
|
||||
selection,
|
||||
value: transformOldConfigToNew(
|
||||
|
||||
683
core/Cargo.lock
generated
683
core/Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
@@ -514,11 +514,17 @@ pub async fn cli_install(
|
||||
#[command(rename_all = "kebab-case")]
|
||||
pub struct UninstallParams {
|
||||
id: PackageId,
|
||||
#[arg(long, help = "Do not delete the service data")]
|
||||
#[serde(default)]
|
||||
soft: bool,
|
||||
#[arg(long, help = "Ignore errors in service uninit script")]
|
||||
#[serde(default)]
|
||||
force: bool,
|
||||
}
|
||||
|
||||
pub async fn uninstall(
|
||||
ctx: RpcContext,
|
||||
UninstallParams { id }: UninstallParams,
|
||||
UninstallParams { id, soft, force }: UninstallParams,
|
||||
) -> Result<PackageId, Error> {
|
||||
ctx.db
|
||||
.mutate(|db| {
|
||||
@@ -540,7 +546,7 @@ pub async fn uninstall(
|
||||
let return_id = id.clone();
|
||||
|
||||
tokio::spawn(async move {
|
||||
if let Err(e) = ctx.services.uninstall(&ctx, &id).await {
|
||||
if let Err(e) = ctx.services.uninstall(&ctx, &id, soft, force).await {
|
||||
tracing::error!("Error uninstalling service {id}: {e}");
|
||||
tracing::debug!("{e:?}");
|
||||
}
|
||||
|
||||
@@ -117,8 +117,11 @@ impl ServiceRef {
|
||||
pub async fn uninstall(
|
||||
self,
|
||||
target_version: Option<models::VersionString>,
|
||||
soft: bool,
|
||||
force: bool,
|
||||
) -> Result<(), Error> {
|
||||
self.seed
|
||||
let uninit_res = self
|
||||
.seed
|
||||
.persistent_container
|
||||
.execute::<NoOutput>(
|
||||
Guid::new(),
|
||||
@@ -126,7 +129,12 @@ impl ServiceRef {
|
||||
to_value(&target_version)?,
|
||||
None,
|
||||
) // TODO timeout
|
||||
.await?;
|
||||
.await;
|
||||
if force {
|
||||
uninit_res.log_err();
|
||||
} else {
|
||||
uninit_res?;
|
||||
}
|
||||
let id = self.seed.persistent_container.s9pk.as_manifest().id.clone();
|
||||
let ctx = self.seed.ctx.clone();
|
||||
self.shutdown().await?;
|
||||
@@ -166,24 +174,26 @@ impl ServiceRef {
|
||||
.await?
|
||||
{
|
||||
let state = pde.state_info.expect_removing()?;
|
||||
for volume_id in &state.manifest.volumes {
|
||||
let path = data_dir(DATA_DIR, &state.manifest.id, volume_id);
|
||||
if tokio::fs::metadata(&path).await.is_ok() {
|
||||
tokio::fs::remove_dir_all(&path).await?;
|
||||
if !soft {
|
||||
for volume_id in &state.manifest.volumes {
|
||||
let path = data_dir(DATA_DIR, &state.manifest.id, volume_id);
|
||||
if tokio::fs::metadata(&path).await.is_ok() {
|
||||
tokio::fs::remove_dir_all(&path).await?;
|
||||
}
|
||||
}
|
||||
let logs_dir = Path::new(PACKAGE_DATA)
|
||||
.join("logs")
|
||||
.join(&state.manifest.id);
|
||||
if tokio::fs::metadata(&logs_dir).await.is_ok() {
|
||||
tokio::fs::remove_dir_all(&logs_dir).await?;
|
||||
}
|
||||
let archive_path = Path::new(PACKAGE_DATA)
|
||||
.join("archive")
|
||||
.join("installed")
|
||||
.join(&state.manifest.id);
|
||||
if tokio::fs::metadata(&archive_path).await.is_ok() {
|
||||
tokio::fs::remove_file(&archive_path).await?;
|
||||
}
|
||||
}
|
||||
let logs_dir = Path::new(PACKAGE_DATA)
|
||||
.join("logs")
|
||||
.join(&state.manifest.id);
|
||||
if tokio::fs::metadata(&logs_dir).await.is_ok() {
|
||||
tokio::fs::remove_dir_all(&logs_dir).await?;
|
||||
}
|
||||
let archive_path = Path::new(PACKAGE_DATA)
|
||||
.join("archive")
|
||||
.join("installed")
|
||||
.join(&state.manifest.id);
|
||||
if tokio::fs::metadata(&archive_path).await.is_ok() {
|
||||
tokio::fs::remove_file(&archive_path).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -397,7 +407,7 @@ impl Service {
|
||||
tracing::debug!("{e:?}")
|
||||
})
|
||||
{
|
||||
match service.uninstall(None).await {
|
||||
match service.uninstall(None, false, false).await {
|
||||
Err(e) => {
|
||||
tracing::error!("Error uninstalling service: {e}");
|
||||
tracing::debug!("{e:?}")
|
||||
|
||||
@@ -286,7 +286,7 @@ impl ServiceMap {
|
||||
.version
|
||||
.clone();
|
||||
service
|
||||
.uninstall(Some(s9pk.as_manifest().version.clone()))
|
||||
.uninstall(Some(s9pk.as_manifest().version.clone()), false, false)
|
||||
.await?;
|
||||
progress.complete();
|
||||
Some(version)
|
||||
@@ -321,12 +321,18 @@ impl ServiceMap {
|
||||
|
||||
/// This is ran during the cleanup, so when we are uninstalling the service
|
||||
#[instrument(skip_all)]
|
||||
pub async fn uninstall(&self, ctx: &RpcContext, id: &PackageId) -> Result<(), Error> {
|
||||
pub async fn uninstall(
|
||||
&self,
|
||||
ctx: &RpcContext,
|
||||
id: &PackageId,
|
||||
soft: bool,
|
||||
force: bool,
|
||||
) -> Result<(), Error> {
|
||||
let mut guard = self.get_mut(id).await;
|
||||
if let Some(service) = guard.take() {
|
||||
ServiceRefReloadGuard::new(ctx.clone(), id.clone(), "Uninstall")
|
||||
.handle_last(async move {
|
||||
let res = service.uninstall(None).await;
|
||||
let res = service.uninstall(None, soft, force).await;
|
||||
drop(guard);
|
||||
res
|
||||
})
|
||||
|
||||
@@ -45,7 +45,25 @@ ExtendedVersion
|
||||
return { flavor: flavor || null, upstream, downstream }
|
||||
}
|
||||
|
||||
EmVer
|
||||
EmverVersionRange
|
||||
= first:EmverVersionRangeAtom rest:(_ ((Or / And) _)? EmverVersionRangeAtom)*
|
||||
|
||||
EmverVersionRangeAtom
|
||||
= EmverParens
|
||||
/ EmverAnchor
|
||||
/ EmverNot
|
||||
/ Any
|
||||
/ None
|
||||
|
||||
EmverParens
|
||||
= "(" _ expr:EmverVersionRange _ ")" { return { type: "Parens", expr } }
|
||||
|
||||
EmverAnchor
|
||||
= operator:CmpOp? _ version:Emver { return { type: "Anchor", operator, version } }
|
||||
|
||||
EmverNot = "!" _ value:EmverVersionRangeAtom { return { type: "Not", value: value }}
|
||||
|
||||
Emver
|
||||
= major:Digit "." minor:Digit "." patch:Digit revision:( "." revision:Digit { return revision } )? {
|
||||
return {
|
||||
flavor: null,
|
||||
|
||||
@@ -296,7 +296,7 @@ function peg$parse(input, options) {
|
||||
var peg$source = options.grammarSource;
|
||||
|
||||
// @ts-ignore
|
||||
var peg$startRuleFunctions = { VersionRange: peg$parseVersionRange, Or: peg$parseOr, And: peg$parseAnd, VersionRangeAtom: peg$parseVersionRangeAtom, Parens: peg$parseParens, Anchor: peg$parseAnchor, VersionSpec: peg$parseVersionSpec, Not: peg$parseNot, Any: peg$parseAny, None: peg$parseNone, CmpOp: peg$parseCmpOp, ExtendedVersion: peg$parseExtendedVersion, EmVer: peg$parseEmVer, Flavor: peg$parseFlavor, Lowercase: peg$parseLowercase, String: peg$parseString, Version: peg$parseVersion, PreRelease: peg$parsePreRelease, PreReleaseSegment: peg$parsePreReleaseSegment, VersionNumber: peg$parseVersionNumber, Digit: peg$parseDigit, _: peg$parse_ };
|
||||
var peg$startRuleFunctions = { VersionRange: peg$parseVersionRange, Or: peg$parseOr, And: peg$parseAnd, VersionRangeAtom: peg$parseVersionRangeAtom, Parens: peg$parseParens, Anchor: peg$parseAnchor, VersionSpec: peg$parseVersionSpec, Not: peg$parseNot, Any: peg$parseAny, None: peg$parseNone, CmpOp: peg$parseCmpOp, ExtendedVersion: peg$parseExtendedVersion, EmverVersionRange: peg$parseEmverVersionRange, EmverVersionRangeAtom: peg$parseEmverVersionRangeAtom, EmverParens: peg$parseEmverParens, EmverAnchor: peg$parseEmverAnchor, EmverNot: peg$parseEmverNot, Emver: peg$parseEmver, Flavor: peg$parseFlavor, Lowercase: peg$parseLowercase, String: peg$parseString, Version: peg$parseVersion, PreRelease: peg$parsePreRelease, PreReleaseSegment: peg$parsePreReleaseSegment, VersionNumber: peg$parseVersionNumber, Digit: peg$parseDigit, _: peg$parse_ };
|
||||
// @ts-ignore
|
||||
var peg$startRuleFunction = peg$parseVersionRange;
|
||||
|
||||
@@ -397,10 +397,19 @@ function peg$parse(input, options) {
|
||||
return { flavor: flavor || null, upstream, downstream }
|
||||
};// @ts-ignore
|
||||
|
||||
var peg$f15 = function(major, minor, patch, revision) {// @ts-ignore
|
||||
var peg$f15 = function(expr) {// @ts-ignore
|
||||
return { type: "Parens", expr } };// @ts-ignore
|
||||
|
||||
var peg$f16 = function(operator, version) {// @ts-ignore
|
||||
return { type: "Anchor", operator, version } };// @ts-ignore
|
||||
|
||||
var peg$f17 = function(value) {// @ts-ignore
|
||||
return { type: "Not", value: value }};// @ts-ignore
|
||||
|
||||
var peg$f18 = function(major, minor, patch, revision) {// @ts-ignore
|
||||
return revision };// @ts-ignore
|
||||
|
||||
var peg$f16 = function(major, minor, patch, revision) {
|
||||
var peg$f19 = function(major, minor, patch, revision) {
|
||||
// @ts-ignore
|
||||
return {
|
||||
// @ts-ignore
|
||||
@@ -422,16 +431,16 @@ function peg$parse(input, options) {
|
||||
}
|
||||
};// @ts-ignore
|
||||
|
||||
var peg$f17 = function(flavor) {// @ts-ignore
|
||||
var peg$f20 = function(flavor) {// @ts-ignore
|
||||
return flavor };// @ts-ignore
|
||||
|
||||
var peg$f18 = function() {// @ts-ignore
|
||||
var peg$f21 = function() {// @ts-ignore
|
||||
return text() };// @ts-ignore
|
||||
|
||||
var peg$f19 = function() {// @ts-ignore
|
||||
var peg$f22 = function() {// @ts-ignore
|
||||
return text(); };// @ts-ignore
|
||||
|
||||
var peg$f20 = function(number, prerelease) {
|
||||
var peg$f23 = function(number, prerelease) {
|
||||
// @ts-ignore
|
||||
return {
|
||||
// @ts-ignore
|
||||
@@ -441,22 +450,22 @@ function peg$parse(input, options) {
|
||||
};
|
||||
};// @ts-ignore
|
||||
|
||||
var peg$f21 = function(first, rest) {
|
||||
var peg$f24 = function(first, rest) {
|
||||
// @ts-ignore
|
||||
return [first].concat(rest.map(r => r[1]));
|
||||
};// @ts-ignore
|
||||
|
||||
var peg$f22 = function(segment) {
|
||||
var peg$f25 = function(segment) {
|
||||
// @ts-ignore
|
||||
return segment;
|
||||
};// @ts-ignore
|
||||
|
||||
var peg$f23 = function(first, rest) {
|
||||
var peg$f26 = function(first, rest) {
|
||||
// @ts-ignore
|
||||
return [first].concat(rest.map(r => r[1]));
|
||||
};// @ts-ignore
|
||||
|
||||
var peg$f24 = function() {// @ts-ignore
|
||||
var peg$f27 = function() {// @ts-ignore
|
||||
return parseInt(text(), 10); };
|
||||
// @ts-ignore
|
||||
var peg$currPos = 0;
|
||||
@@ -1536,7 +1545,336 @@ peg$parseExtendedVersion() {
|
||||
|
||||
// @ts-ignore
|
||||
function // @ts-ignore
|
||||
peg$parseEmVer() {
|
||||
peg$parseEmverVersionRange() {
|
||||
// @ts-ignore
|
||||
var s0, s1, s2, s3, s4, s5, s6, s7;
|
||||
|
||||
// @ts-ignore
|
||||
s0 = peg$currPos;
|
||||
// @ts-ignore
|
||||
s1 = peg$parseEmverVersionRangeAtom();
|
||||
// @ts-ignore
|
||||
if (s1 !== peg$FAILED) {
|
||||
// @ts-ignore
|
||||
s2 = [];
|
||||
// @ts-ignore
|
||||
s3 = peg$currPos;
|
||||
// @ts-ignore
|
||||
s4 = peg$parse_();
|
||||
// @ts-ignore
|
||||
s5 = peg$currPos;
|
||||
// @ts-ignore
|
||||
s6 = peg$parseOr();
|
||||
// @ts-ignore
|
||||
if (s6 === peg$FAILED) {
|
||||
// @ts-ignore
|
||||
s6 = peg$parseAnd();
|
||||
}
|
||||
// @ts-ignore
|
||||
if (s6 !== peg$FAILED) {
|
||||
// @ts-ignore
|
||||
s7 = peg$parse_();
|
||||
// @ts-ignore
|
||||
s6 = [s6, s7];
|
||||
// @ts-ignore
|
||||
s5 = s6;
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
peg$currPos = s5;
|
||||
// @ts-ignore
|
||||
s5 = peg$FAILED;
|
||||
}
|
||||
// @ts-ignore
|
||||
if (s5 === peg$FAILED) {
|
||||
// @ts-ignore
|
||||
s5 = null;
|
||||
}
|
||||
// @ts-ignore
|
||||
s6 = peg$parseEmverVersionRangeAtom();
|
||||
// @ts-ignore
|
||||
if (s6 !== peg$FAILED) {
|
||||
// @ts-ignore
|
||||
s4 = [s4, s5, s6];
|
||||
// @ts-ignore
|
||||
s3 = s4;
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
peg$currPos = s3;
|
||||
// @ts-ignore
|
||||
s3 = peg$FAILED;
|
||||
}
|
||||
// @ts-ignore
|
||||
while (s3 !== peg$FAILED) {
|
||||
// @ts-ignore
|
||||
s2.push(s3);
|
||||
// @ts-ignore
|
||||
s3 = peg$currPos;
|
||||
// @ts-ignore
|
||||
s4 = peg$parse_();
|
||||
// @ts-ignore
|
||||
s5 = peg$currPos;
|
||||
// @ts-ignore
|
||||
s6 = peg$parseOr();
|
||||
// @ts-ignore
|
||||
if (s6 === peg$FAILED) {
|
||||
// @ts-ignore
|
||||
s6 = peg$parseAnd();
|
||||
}
|
||||
// @ts-ignore
|
||||
if (s6 !== peg$FAILED) {
|
||||
// @ts-ignore
|
||||
s7 = peg$parse_();
|
||||
// @ts-ignore
|
||||
s6 = [s6, s7];
|
||||
// @ts-ignore
|
||||
s5 = s6;
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
peg$currPos = s5;
|
||||
// @ts-ignore
|
||||
s5 = peg$FAILED;
|
||||
}
|
||||
// @ts-ignore
|
||||
if (s5 === peg$FAILED) {
|
||||
// @ts-ignore
|
||||
s5 = null;
|
||||
}
|
||||
// @ts-ignore
|
||||
s6 = peg$parseEmverVersionRangeAtom();
|
||||
// @ts-ignore
|
||||
if (s6 !== peg$FAILED) {
|
||||
// @ts-ignore
|
||||
s4 = [s4, s5, s6];
|
||||
// @ts-ignore
|
||||
s3 = s4;
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
peg$currPos = s3;
|
||||
// @ts-ignore
|
||||
s3 = peg$FAILED;
|
||||
}
|
||||
}
|
||||
// @ts-ignore
|
||||
s1 = [s1, s2];
|
||||
// @ts-ignore
|
||||
s0 = s1;
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
peg$currPos = s0;
|
||||
// @ts-ignore
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
return s0;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
function // @ts-ignore
|
||||
peg$parseEmverVersionRangeAtom() {
|
||||
// @ts-ignore
|
||||
var s0;
|
||||
|
||||
// @ts-ignore
|
||||
s0 = peg$parseEmverParens();
|
||||
// @ts-ignore
|
||||
if (s0 === peg$FAILED) {
|
||||
// @ts-ignore
|
||||
s0 = peg$parseEmverAnchor();
|
||||
// @ts-ignore
|
||||
if (s0 === peg$FAILED) {
|
||||
// @ts-ignore
|
||||
s0 = peg$parseEmverNot();
|
||||
// @ts-ignore
|
||||
if (s0 === peg$FAILED) {
|
||||
// @ts-ignore
|
||||
s0 = peg$parseAny();
|
||||
// @ts-ignore
|
||||
if (s0 === peg$FAILED) {
|
||||
// @ts-ignore
|
||||
s0 = peg$parseNone();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
return s0;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
function // @ts-ignore
|
||||
peg$parseEmverParens() {
|
||||
// @ts-ignore
|
||||
var s0, s1, s2, s3, s4, s5;
|
||||
|
||||
// @ts-ignore
|
||||
s0 = peg$currPos;
|
||||
// @ts-ignore
|
||||
if (input.charCodeAt(peg$currPos) === 40) {
|
||||
// @ts-ignore
|
||||
s1 = peg$c2;
|
||||
// @ts-ignore
|
||||
peg$currPos++;
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
s1 = peg$FAILED;
|
||||
// @ts-ignore
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e2); }
|
||||
}
|
||||
// @ts-ignore
|
||||
if (s1 !== peg$FAILED) {
|
||||
// @ts-ignore
|
||||
s2 = peg$parse_();
|
||||
// @ts-ignore
|
||||
s3 = peg$parseEmverVersionRange();
|
||||
// @ts-ignore
|
||||
if (s3 !== peg$FAILED) {
|
||||
// @ts-ignore
|
||||
s4 = peg$parse_();
|
||||
// @ts-ignore
|
||||
if (input.charCodeAt(peg$currPos) === 41) {
|
||||
// @ts-ignore
|
||||
s5 = peg$c3;
|
||||
// @ts-ignore
|
||||
peg$currPos++;
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
s5 = peg$FAILED;
|
||||
// @ts-ignore
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e3); }
|
||||
}
|
||||
// @ts-ignore
|
||||
if (s5 !== peg$FAILED) {
|
||||
// @ts-ignore
|
||||
peg$savedPos = s0;
|
||||
// @ts-ignore
|
||||
s0 = peg$f15(s3);
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
peg$currPos = s0;
|
||||
// @ts-ignore
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
peg$currPos = s0;
|
||||
// @ts-ignore
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
peg$currPos = s0;
|
||||
// @ts-ignore
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
return s0;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
function // @ts-ignore
|
||||
peg$parseEmverAnchor() {
|
||||
// @ts-ignore
|
||||
var s0, s1, s2, s3;
|
||||
|
||||
// @ts-ignore
|
||||
s0 = peg$currPos;
|
||||
// @ts-ignore
|
||||
s1 = peg$parseCmpOp();
|
||||
// @ts-ignore
|
||||
if (s1 === peg$FAILED) {
|
||||
// @ts-ignore
|
||||
s1 = null;
|
||||
}
|
||||
// @ts-ignore
|
||||
s2 = peg$parse_();
|
||||
// @ts-ignore
|
||||
s3 = peg$parseEmver();
|
||||
// @ts-ignore
|
||||
if (s3 !== peg$FAILED) {
|
||||
// @ts-ignore
|
||||
peg$savedPos = s0;
|
||||
// @ts-ignore
|
||||
s0 = peg$f16(s1, s3);
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
peg$currPos = s0;
|
||||
// @ts-ignore
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
return s0;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
function // @ts-ignore
|
||||
peg$parseEmverNot() {
|
||||
// @ts-ignore
|
||||
var s0, s1, s2, s3;
|
||||
|
||||
// @ts-ignore
|
||||
s0 = peg$currPos;
|
||||
// @ts-ignore
|
||||
if (input.charCodeAt(peg$currPos) === 33) {
|
||||
// @ts-ignore
|
||||
s1 = peg$c5;
|
||||
// @ts-ignore
|
||||
peg$currPos++;
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
s1 = peg$FAILED;
|
||||
// @ts-ignore
|
||||
if (peg$silentFails === 0) { peg$fail(peg$e5); }
|
||||
}
|
||||
// @ts-ignore
|
||||
if (s1 !== peg$FAILED) {
|
||||
// @ts-ignore
|
||||
s2 = peg$parse_();
|
||||
// @ts-ignore
|
||||
s3 = peg$parseEmverVersionRangeAtom();
|
||||
// @ts-ignore
|
||||
if (s3 !== peg$FAILED) {
|
||||
// @ts-ignore
|
||||
peg$savedPos = s0;
|
||||
// @ts-ignore
|
||||
s0 = peg$f17(s3);
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
peg$currPos = s0;
|
||||
// @ts-ignore
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
peg$currPos = s0;
|
||||
// @ts-ignore
|
||||
s0 = peg$FAILED;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
return s0;
|
||||
}
|
||||
|
||||
// @ts-ignore
|
||||
function // @ts-ignore
|
||||
peg$parseEmver() {
|
||||
// @ts-ignore
|
||||
var s0, s1, s2, s3, s4, s5, s6, s7, s8;
|
||||
|
||||
@@ -1608,7 +1946,7 @@ peg$parseEmVer() {
|
||||
// @ts-ignore
|
||||
peg$savedPos = s6;
|
||||
// @ts-ignore
|
||||
s6 = peg$f15(s1, s3, s5, s8);
|
||||
s6 = peg$f18(s1, s3, s5, s8);
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
@@ -1631,7 +1969,7 @@ peg$parseEmVer() {
|
||||
// @ts-ignore
|
||||
peg$savedPos = s0;
|
||||
// @ts-ignore
|
||||
s0 = peg$f16(s1, s3, s5, s6);
|
||||
s0 = peg$f19(s1, s3, s5, s6);
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
@@ -1717,7 +2055,7 @@ peg$parseFlavor() {
|
||||
// @ts-ignore
|
||||
peg$savedPos = s0;
|
||||
// @ts-ignore
|
||||
s0 = peg$f17(s2);
|
||||
s0 = peg$f20(s2);
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
@@ -1797,7 +2135,7 @@ peg$parseLowercase() {
|
||||
// @ts-ignore
|
||||
peg$savedPos = s0;
|
||||
// @ts-ignore
|
||||
s1 = peg$f18();
|
||||
s1 = peg$f21();
|
||||
}
|
||||
// @ts-ignore
|
||||
s0 = s1;
|
||||
@@ -1859,7 +2197,7 @@ peg$parseString() {
|
||||
// @ts-ignore
|
||||
peg$savedPos = s0;
|
||||
// @ts-ignore
|
||||
s1 = peg$f19();
|
||||
s1 = peg$f22();
|
||||
}
|
||||
// @ts-ignore
|
||||
s0 = s1;
|
||||
@@ -1890,7 +2228,7 @@ peg$parseVersion() {
|
||||
// @ts-ignore
|
||||
peg$savedPos = s0;
|
||||
// @ts-ignore
|
||||
s0 = peg$f20(s1, s2);
|
||||
s0 = peg$f23(s1, s2);
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
@@ -2018,7 +2356,7 @@ peg$parsePreRelease() {
|
||||
// @ts-ignore
|
||||
peg$savedPos = s0;
|
||||
// @ts-ignore
|
||||
s0 = peg$f21(s2, s3);
|
||||
s0 = peg$f24(s2, s3);
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
@@ -2076,7 +2414,7 @@ peg$parsePreReleaseSegment() {
|
||||
// @ts-ignore
|
||||
peg$savedPos = s0;
|
||||
// @ts-ignore
|
||||
s0 = peg$f22(s2);
|
||||
s0 = peg$f25(s2);
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
@@ -2189,7 +2527,7 @@ peg$parseVersionNumber() {
|
||||
// @ts-ignore
|
||||
peg$savedPos = s0;
|
||||
// @ts-ignore
|
||||
s0 = peg$f23(s1, s2);
|
||||
s0 = peg$f26(s1, s2);
|
||||
// @ts-ignore
|
||||
} else {
|
||||
// @ts-ignore
|
||||
@@ -2255,7 +2593,7 @@ peg$parseDigit() {
|
||||
// @ts-ignore
|
||||
peg$savedPos = s0;
|
||||
// @ts-ignore
|
||||
s1 = peg$f24();
|
||||
s1 = peg$f27();
|
||||
}
|
||||
// @ts-ignore
|
||||
s0 = s1;
|
||||
@@ -2426,7 +2764,7 @@ peggyParser.SyntaxError.prototype.name = "PeggySyntaxError";
|
||||
|
||||
export interface ParseOptions {
|
||||
filename?: string;
|
||||
startRule?: "VersionRange" | "Or" | "And" | "VersionRangeAtom" | "Parens" | "Anchor" | "VersionSpec" | "Not" | "Any" | "None" | "CmpOp" | "ExtendedVersion" | "EmVer" | "Flavor" | "Lowercase" | "String" | "Version" | "PreRelease" | "PreReleaseSegment" | "VersionNumber" | "Digit" | "_";
|
||||
startRule?: "VersionRange" | "Or" | "And" | "VersionRangeAtom" | "Parens" | "Anchor" | "VersionSpec" | "Not" | "Any" | "None" | "CmpOp" | "ExtendedVersion" | "EmverVersionRange" | "EmverVersionRangeAtom" | "EmverParens" | "EmverAnchor" | "EmverNot" | "Emver" | "Flavor" | "Lowercase" | "String" | "Version" | "PreRelease" | "PreReleaseSegment" | "VersionNumber" | "Digit" | "_";
|
||||
tracer?: any;
|
||||
[key: string]: any;
|
||||
}
|
||||
@@ -2446,7 +2784,12 @@ export type ParseFunction = <Options extends ParseOptions>(
|
||||
StartRule extends "None" ? None :
|
||||
StartRule extends "CmpOp" ? CmpOp :
|
||||
StartRule extends "ExtendedVersion" ? ExtendedVersion :
|
||||
StartRule extends "EmVer" ? EmVer :
|
||||
StartRule extends "EmverVersionRange" ? EmverVersionRange :
|
||||
StartRule extends "EmverVersionRangeAtom" ? EmverVersionRangeAtom :
|
||||
StartRule extends "EmverParens" ? EmverParens :
|
||||
StartRule extends "EmverAnchor" ? EmverAnchor :
|
||||
StartRule extends "EmverNot" ? EmverNot :
|
||||
StartRule extends "Emver" ? Emver :
|
||||
StartRule extends "Flavor" ? Flavor :
|
||||
StartRule extends "Lowercase" ? Lowercase_1 :
|
||||
StartRule extends "String" ? String_1 :
|
||||
@@ -2491,7 +2834,24 @@ export type ExtendedVersion = {
|
||||
upstream: Version;
|
||||
downstream: Version;
|
||||
};
|
||||
export type EmVer = {
|
||||
export type EmverVersionRange = [
|
||||
EmverVersionRangeAtom,
|
||||
[_, [Or | And, _] | null, EmverVersionRangeAtom][]
|
||||
];
|
||||
export type EmverVersionRangeAtom =
|
||||
| EmverParens
|
||||
| EmverAnchor
|
||||
| EmverNot
|
||||
| Any
|
||||
| None;
|
||||
export type EmverParens = { type: "Parens"; expr: EmverVersionRange };
|
||||
export type EmverAnchor = {
|
||||
type: "Anchor";
|
||||
operator: CmpOp | null;
|
||||
version: Emver;
|
||||
};
|
||||
export type EmverNot = { type: "Not"; value: EmverVersionRangeAtom };
|
||||
export type Emver = {
|
||||
flavor: null;
|
||||
upstream: { number: [Digit, Digit, Digit]; prerelease: [] };
|
||||
downstream: { number: [0 | NonNullable<Digit | null>]; prerelease: [] };
|
||||
|
||||
@@ -123,6 +123,12 @@ export class VersionRange {
|
||||
)
|
||||
}
|
||||
|
||||
static parseEmver(range: string): VersionRange {
|
||||
return VersionRange.parseRange(
|
||||
P.parse(range, { startRule: "EmverVersionRange" }),
|
||||
)
|
||||
}
|
||||
|
||||
and(right: VersionRange) {
|
||||
return new VersionRange({ type: "And", left: this, right })
|
||||
}
|
||||
@@ -291,12 +297,19 @@ export class ExtendedVersion {
|
||||
}
|
||||
|
||||
static parseEmver(extendedVersion: string): ExtendedVersion {
|
||||
const parsed = P.parse(extendedVersion, { startRule: "EmVer" })
|
||||
return new ExtendedVersion(
|
||||
parsed.flavor,
|
||||
new Version(parsed.upstream.number, parsed.upstream.prerelease),
|
||||
new Version(parsed.downstream.number, parsed.downstream.prerelease),
|
||||
)
|
||||
try {
|
||||
const parsed = P.parse(extendedVersion, { startRule: "Emver" })
|
||||
return new ExtendedVersion(
|
||||
parsed.flavor,
|
||||
new Version(parsed.upstream.number, parsed.upstream.prerelease),
|
||||
new Version(parsed.downstream.number, parsed.downstream.prerelease),
|
||||
)
|
||||
} catch (e) {
|
||||
if (e instanceof Error) {
|
||||
e.message += ` (${extendedVersion})`
|
||||
}
|
||||
throw e
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -48,6 +48,11 @@ export type SDKManifest = {
|
||||
/** Long description to display on the marketplace details page for this service. Max length 500 chars. */
|
||||
readonly long: string
|
||||
}
|
||||
/**
|
||||
* override the StartOS version this package was made for
|
||||
* defaults to the version the SDK was built for
|
||||
*/
|
||||
osVersion?: string
|
||||
/**
|
||||
* @description A mapping of OS images needed to run the container processes. Each image ID is a unique key.
|
||||
* @example
|
||||
|
||||
@@ -73,7 +73,7 @@ import * as actions from "../../base/lib/actions"
|
||||
import { setupInit } from "./inits/setupInit"
|
||||
import * as fs from "node:fs/promises"
|
||||
|
||||
export const SDKVersion = testTypeVersion("0.3.6")
|
||||
export const OSVersion = testTypeVersion("0.3.6-alpha.15")
|
||||
|
||||
// prettier-ignore
|
||||
type AnyNeverCond<T extends any[], Then, Else> =
|
||||
|
||||
@@ -4,7 +4,7 @@ import {
|
||||
SDKManifest,
|
||||
SDKImageInputSpec,
|
||||
} from "../../../base/lib/types/ManifestTypes"
|
||||
import { SDKVersion } from "../StartSdk"
|
||||
import { OSVersion } from "../StartSdk"
|
||||
import { VersionGraph } from "../version/VersionGraph"
|
||||
import { execSync } from "child_process"
|
||||
|
||||
@@ -58,7 +58,7 @@ export function buildManifest<
|
||||
)
|
||||
return {
|
||||
...manifest,
|
||||
osVersion: SDKVersion,
|
||||
osVersion: manifest.osVersion ?? OSVersion,
|
||||
version: versions.current.options.version,
|
||||
releaseNotes: versions.current.options.releaseNotes,
|
||||
satisfies: versions.current.options.satisfies || [],
|
||||
|
||||
4
sdk/package/package-lock.json
generated
4
sdk/package/package-lock.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@start9labs/start-sdk",
|
||||
"version": "0.3.6-beta.13",
|
||||
"version": "0.3.6-beta.14",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@start9labs/start-sdk",
|
||||
"version": "0.3.6-beta.13",
|
||||
"version": "0.3.6-beta.14",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@iarna/toml": "^2.2.5",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@start9labs/start-sdk",
|
||||
"version": "0.3.6-beta.13",
|
||||
"version": "0.3.6-beta.14",
|
||||
"description": "Software development kit to facilitate packaging services for StartOS",
|
||||
"main": "./package/lib/index.js",
|
||||
"types": "./package/lib/index.d.ts",
|
||||
|
||||
Reference in New Issue
Block a user