130 lines
4.8 KiB
JavaScript
130 lines
4.8 KiB
JavaScript
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
import path from "node:path";
|
|
import { fileURLToPath } from "node:url";
|
|
|
|
export function buildUnityReleaseRequest({
|
|
capabilityManifest,
|
|
packageManifest,
|
|
capabilityManifestPath = "",
|
|
packageManifestPath = "",
|
|
repository = "GameCult/EveUnity",
|
|
} = {}) {
|
|
if (!capabilityManifest || typeof capabilityManifest !== "object") {
|
|
throw new Error("capabilityManifest is required");
|
|
}
|
|
if (!packageManifest || typeof packageManifest !== "object") {
|
|
throw new Error("packageManifest is required");
|
|
}
|
|
|
|
const releaseContract = capabilityManifest.lifecycle?.release?.releaseContract;
|
|
if (!releaseContract) {
|
|
throw new Error("capability manifest is missing lifecycle.release.releaseContract");
|
|
}
|
|
|
|
if (packageManifest.name !== releaseContract.packageName) {
|
|
throw new Error(`package name mismatch: expected ${releaseContract.packageName} got ${packageManifest.name || "missing"}`);
|
|
}
|
|
if (!packageManifest.version || !/^\d+\.\d+\.\d+(?:[-+][0-9A-Za-z.-]+)?$/.test(packageManifest.version)) {
|
|
throw new Error(`package version is not a SemVer-compatible release version: ${packageManifest.version || "missing"}`);
|
|
}
|
|
const requiredPackageDependencies = Array.isArray(releaseContract.requiredPackageDependencies)
|
|
? releaseContract.requiredPackageDependencies
|
|
: [{ packageName: "org.gamecult.eve.surface", version: "0.1.0", packageManager: "upm", ownerRepo: "Eve" }];
|
|
const packageDependencies = packageManifest.dependencies || {};
|
|
for (const dependency of requiredPackageDependencies) {
|
|
if (!dependency?.packageName) {
|
|
throw new Error("release contract requiredPackageDependencies entries must name packageName");
|
|
}
|
|
const actualVersion = packageDependencies[dependency.packageName];
|
|
if (!actualVersion) {
|
|
throw new Error(`${releaseContract.packageName} must depend on ${dependency.packageName}`);
|
|
}
|
|
if (dependency.version && actualVersion !== dependency.version) {
|
|
throw new Error(`${releaseContract.packageName} dependency ${dependency.packageName} expected ${dependency.version} got ${actualVersion}`);
|
|
}
|
|
}
|
|
|
|
const tagName = replaceVersion(releaseContract.tagPattern, packageManifest.version);
|
|
const artifactPath = replaceVersion(
|
|
releaseContract.artifactPattern || `artifacts/eveunity-uitoolkit-release/{version}/${releaseContract.packageName}-{version}.tgz`,
|
|
packageManifest.version,
|
|
);
|
|
|
|
return {
|
|
schema: releaseContract.requestSchema || "gamecult.eve.runtime_release_request.v1",
|
|
ownerRepo: releaseContract.ownerRepo,
|
|
repository,
|
|
packageName: releaseContract.packageName,
|
|
displayName: packageManifest.displayName || "",
|
|
version: packageManifest.version,
|
|
unity: packageManifest.unity || "",
|
|
packageRoot: releaseContract.packageRoot,
|
|
versionSource: releaseContract.versionSource,
|
|
tagName,
|
|
artifactKind: releaseContract.artifactKind,
|
|
artifactPath,
|
|
publishProof: releaseContract.publishProof,
|
|
sourceCapabilityManifestPath: capabilityManifestPath,
|
|
sourcePackageManifestPath: packageManifestPath,
|
|
dependencies: packageManifest.dependencies || {},
|
|
requiredPackageDependencies,
|
|
};
|
|
}
|
|
|
|
export function loadJsonFile(filePath) {
|
|
return JSON.parse(readFileSync(filePath, "utf8"));
|
|
}
|
|
|
|
export function writeReleaseRequest(request, outputPath) {
|
|
mkdirSync(path.dirname(outputPath), { recursive: true });
|
|
writeFileSync(outputPath, `${JSON.stringify(request, null, 2)}\n`, "utf8");
|
|
}
|
|
|
|
function replaceVersion(pattern, version) {
|
|
if (!pattern || !pattern.includes("{version}")) {
|
|
throw new Error(`release pattern must include {version}: ${pattern || "missing"}`);
|
|
}
|
|
return pattern.replaceAll("{version}", version);
|
|
}
|
|
|
|
function parseArgs(argv) {
|
|
const args = {};
|
|
for (let index = 0; index < argv.length; index += 1) {
|
|
const value = argv[index];
|
|
if (!value.startsWith("--")) continue;
|
|
const key = value.slice(2);
|
|
const next = argv[index + 1];
|
|
if (!next || next.startsWith("--")) {
|
|
args[key] = true;
|
|
} else {
|
|
args[key] = next;
|
|
index += 1;
|
|
}
|
|
}
|
|
return args;
|
|
}
|
|
|
|
function runCli() {
|
|
const args = parseArgs(process.argv.slice(2));
|
|
for (const required of ["capability", "package", "output"]) {
|
|
if (!args[required]) {
|
|
throw new Error(`missing required --${required}`);
|
|
}
|
|
}
|
|
|
|
const request = buildUnityReleaseRequest({
|
|
capabilityManifest: loadJsonFile(args.capability),
|
|
packageManifest: loadJsonFile(args.package),
|
|
capabilityManifestPath: args.capability,
|
|
packageManifestPath: args.package,
|
|
repository: args.repository || "GameCult/EveUnity",
|
|
});
|
|
writeReleaseRequest(request, args.output);
|
|
process.stdout.write(`${args.output}\n`);
|
|
}
|
|
|
|
const invokedPath = process.argv[1] ? path.resolve(process.argv[1]) : "";
|
|
const modulePath = fileURLToPath(import.meta.url);
|
|
if (invokedPath === modulePath) {
|
|
runCli();
|
|
}
|