This commit is contained in:
parent
70570faed6
commit
2b2bb20658
@ -5,9 +5,6 @@ import { readThisNpmPackageVersion } from "./tools/readThisNpmPackageVersion";
|
|||||||
import * as child_process from "child_process";
|
import * as child_process from "child_process";
|
||||||
import { assertNoPnpmDlx } from "./tools/assertNoPnpmDlx";
|
import { assertNoPnpmDlx } from "./tools/assertNoPnpmDlx";
|
||||||
import { getBuildContext } from "./shared/buildContext";
|
import { getBuildContext } from "./shared/buildContext";
|
||||||
import { SemVer } from "./tools/SemVer";
|
|
||||||
import { assert, is } from "tsafe/assert";
|
|
||||||
import chalk from "chalk";
|
|
||||||
|
|
||||||
type CliCommandOptions = {
|
type CliCommandOptions = {
|
||||||
projectDirPath: string | undefined;
|
projectDirPath: string | undefined;
|
||||||
@ -137,47 +134,11 @@ program
|
|||||||
handler: async ({ projectDirPath, keycloakVersion, port, realmJsonFilePath }) => {
|
handler: async ({ projectDirPath, keycloakVersion, port, realmJsonFilePath }) => {
|
||||||
const { command } = await import("./start-keycloak");
|
const { command } = await import("./start-keycloak");
|
||||||
|
|
||||||
validate_keycloak_version: {
|
|
||||||
if (keycloakVersion === undefined) {
|
|
||||||
break validate_keycloak_version;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isValidVersion = (() => {
|
|
||||||
if (typeof keycloakVersion === "number") {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
SemVer.parse(keycloakVersion);
|
|
||||||
} catch {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
})();
|
|
||||||
|
|
||||||
if (isValidVersion) {
|
|
||||||
break validate_keycloak_version;
|
|
||||||
}
|
|
||||||
|
|
||||||
console.log(
|
|
||||||
chalk.red(
|
|
||||||
[
|
|
||||||
`Invalid Keycloak version: ${keycloakVersion}`,
|
|
||||||
"It should be a valid semver version example: 26.0.4"
|
|
||||||
].join(" ")
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
process.exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(is<string | undefined>(keycloakVersion));
|
|
||||||
|
|
||||||
await command({
|
await command({
|
||||||
buildContext: getBuildContext({ projectDirPath }),
|
buildContext: getBuildContext({ projectDirPath }),
|
||||||
cliCommandOptions: {
|
cliCommandOptions: {
|
||||||
keycloakVersion,
|
keycloakVersion:
|
||||||
|
keycloakVersion === undefined ? undefined : `${keycloakVersion}`,
|
||||||
port,
|
port,
|
||||||
realmJsonFilePath
|
realmJsonFilePath
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ import { join as pathJoin, dirname as pathDirname } from "path";
|
|||||||
import * as fs from "fs/promises";
|
import * as fs from "fs/promises";
|
||||||
import { existsAsync } from "../tools/fs.existsAsync";
|
import { existsAsync } from "../tools/fs.existsAsync";
|
||||||
import { readThisNpmPackageVersion } from "../tools/readThisNpmPackageVersion";
|
import { readThisNpmPackageVersion } from "../tools/readThisNpmPackageVersion";
|
||||||
|
import type { ReturnType } from "tsafe";
|
||||||
|
|
||||||
export type BuildContextLike = {
|
export type BuildContextLike = {
|
||||||
fetchOptions: BuildContext["fetchOptions"];
|
fetchOptions: BuildContext["fetchOptions"];
|
||||||
@ -20,7 +21,10 @@ assert<BuildContext extends BuildContextLike ? true : false>;
|
|||||||
|
|
||||||
export async function getSupportedDockerImageTags(params: {
|
export async function getSupportedDockerImageTags(params: {
|
||||||
buildContext: BuildContextLike;
|
buildContext: BuildContextLike;
|
||||||
}) {
|
}): Promise<{
|
||||||
|
allSupportedTags: string[];
|
||||||
|
latestMajorTags: string[];
|
||||||
|
}> {
|
||||||
const { buildContext } = params;
|
const { buildContext } = params;
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -31,14 +35,14 @@ export async function getSupportedDockerImageTags(params: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const tags: string[] = [];
|
const tags_queryResponse: string[] = [];
|
||||||
|
|
||||||
await (async function callee(url: string) {
|
await (async function callee(url: string) {
|
||||||
const r = await fetch(url, buildContext.fetchOptions);
|
const r = await fetch(url, buildContext.fetchOptions);
|
||||||
|
|
||||||
await Promise.all([
|
await Promise.all([
|
||||||
(async () => {
|
(async () => {
|
||||||
tags.push(
|
tags_queryResponse.push(
|
||||||
...z
|
...z
|
||||||
.object({
|
.object({
|
||||||
tags: z.array(z.string())
|
tags: z.array(z.string())
|
||||||
@ -70,7 +74,9 @@ export async function getSupportedDockerImageTags(params: {
|
|||||||
]);
|
]);
|
||||||
})("https://quay.io/v2/keycloak/keycloak/tags/list");
|
})("https://quay.io/v2/keycloak/keycloak/tags/list");
|
||||||
|
|
||||||
const arr = tags
|
const supportedKeycloakMajorVersions = getSupportedKeycloakMajorVersions();
|
||||||
|
|
||||||
|
const allSupportedTags_withVersion = tags_queryResponse
|
||||||
.map(tag => ({
|
.map(tag => ({
|
||||||
tag,
|
tag,
|
||||||
version: (() => {
|
version: (() => {
|
||||||
@ -86,28 +92,35 @@ export async function getSupportedDockerImageTags(params: {
|
|||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (tag.split(".").length !== 3) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!supportedKeycloakMajorVersions.includes(version.major)) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
return version;
|
return version;
|
||||||
})()
|
})()
|
||||||
}))
|
}))
|
||||||
.map(({ tag, version }) => (version === undefined ? undefined : { tag, version }))
|
.map(({ tag, version }) => (version === undefined ? undefined : { tag, version }))
|
||||||
.filter(exclude(undefined));
|
.filter(exclude(undefined))
|
||||||
|
.sort(({ version: a }, { version: b }) => SemVer.compare(b, a));
|
||||||
|
|
||||||
const versionByMajor: Record<number, SemVer | undefined> = {};
|
const latestTagByMajor: Record<number, SemVer | undefined> = {};
|
||||||
|
|
||||||
for (const { version } of arr) {
|
for (const { version } of allSupportedTags_withVersion) {
|
||||||
const version_current = versionByMajor[version.major];
|
const version_current = latestTagByMajor[version.major];
|
||||||
|
|
||||||
if (
|
if (
|
||||||
version_current === undefined ||
|
version_current === undefined ||
|
||||||
SemVer.compare(version_current, version) === -1
|
SemVer.compare(version_current, version) === -1
|
||||||
) {
|
) {
|
||||||
versionByMajor[version.major] = version;
|
latestTagByMajor[version.major] = version;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const supportedKeycloakMajorVersions = getSupportedKeycloakMajorVersions();
|
const latestMajorTags = Object.entries(latestTagByMajor)
|
||||||
|
|
||||||
const result = Object.entries(versionByMajor)
|
|
||||||
.sort(([a], [b]) => parseInt(b) - parseInt(a))
|
.sort(([a], [b]) => parseInt(b) - parseInt(a))
|
||||||
.map(([, version]) => version)
|
.map(([, version]) => version)
|
||||||
.map(version => {
|
.map(version => {
|
||||||
@ -121,16 +134,40 @@ export async function getSupportedDockerImageTags(params: {
|
|||||||
})
|
})
|
||||||
.filter(exclude(undefined));
|
.filter(exclude(undefined));
|
||||||
|
|
||||||
|
const allSupportedTags = allSupportedTags_withVersion.map(({ tag }) => tag);
|
||||||
|
|
||||||
|
const result = {
|
||||||
|
latestMajorTags,
|
||||||
|
allSupportedTags
|
||||||
|
};
|
||||||
|
|
||||||
await setCachedValue({ cacheDirPath: buildContext.cacheDirPath, result });
|
await setCachedValue({ cacheDirPath: buildContext.cacheDirPath, result });
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
const { getCachedValue, setCachedValue } = (() => {
|
const { getCachedValue, setCachedValue } = (() => {
|
||||||
|
type Result = ReturnType<typeof getSupportedDockerImageTags>;
|
||||||
|
|
||||||
|
const zResult = (() => {
|
||||||
|
type TargetType = Result;
|
||||||
|
|
||||||
|
const zTargetType = z.object({
|
||||||
|
allSupportedTags: z.array(z.string()),
|
||||||
|
latestMajorTags: z.array(z.string())
|
||||||
|
});
|
||||||
|
|
||||||
|
type InferredType = z.infer<typeof zTargetType>;
|
||||||
|
|
||||||
|
assert<Equals<TargetType, InferredType>>;
|
||||||
|
|
||||||
|
return id<z.ZodType<TargetType>>(zTargetType);
|
||||||
|
})();
|
||||||
|
|
||||||
type Cache = {
|
type Cache = {
|
||||||
keycloakifyVersion: string;
|
keycloakifyVersion: string;
|
||||||
time: number;
|
time: number;
|
||||||
result: string[];
|
result: Result;
|
||||||
};
|
};
|
||||||
|
|
||||||
const zCache = (() => {
|
const zCache = (() => {
|
||||||
@ -139,7 +176,7 @@ const { getCachedValue, setCachedValue } = (() => {
|
|||||||
const zTargetType = z.object({
|
const zTargetType = z.object({
|
||||||
keycloakifyVersion: z.string(),
|
keycloakifyVersion: z.string(),
|
||||||
time: z.number(),
|
time: z.number(),
|
||||||
result: z.array(z.string())
|
result: zResult
|
||||||
});
|
});
|
||||||
|
|
||||||
type InferredType = z.infer<typeof zTargetType>;
|
type InferredType = z.infer<typeof zTargetType>;
|
||||||
|
@ -97,7 +97,7 @@ export async function command(params: {
|
|||||||
|
|
||||||
const { cliCommandOptions, buildContext } = params;
|
const { cliCommandOptions, buildContext } = params;
|
||||||
|
|
||||||
const availableTags = await getSupportedDockerImageTags({
|
const { allSupportedTags, latestMajorTags } = await getSupportedDockerImageTags({
|
||||||
buildContext
|
buildContext
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ export async function command(params: {
|
|||||||
if (cliCommandOptions.keycloakVersion !== undefined) {
|
if (cliCommandOptions.keycloakVersion !== undefined) {
|
||||||
const cliCommandOptions_keycloakVersion = cliCommandOptions.keycloakVersion;
|
const cliCommandOptions_keycloakVersion = cliCommandOptions.keycloakVersion;
|
||||||
|
|
||||||
const tag = availableTags.find(tag =>
|
const tag = allSupportedTags.find(tag =>
|
||||||
tag.startsWith(cliCommandOptions_keycloakVersion)
|
tag.startsWith(cliCommandOptions_keycloakVersion)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ export async function command(params: {
|
|||||||
);
|
);
|
||||||
|
|
||||||
const { value: tag } = await cliSelect<string>({
|
const { value: tag } = await cliSelect<string>({
|
||||||
values: availableTags
|
values: latestMajorTags
|
||||||
}).catch(() => {
|
}).catch(() => {
|
||||||
process.exit(-1);
|
process.exit(-1);
|
||||||
});
|
});
|
||||||
|
Loading…
x
Reference in New Issue
Block a user