Improve start-keycloak command
This commit is contained in:
@ -3,7 +3,7 @@ import { join as pathJoin, relative as pathRelative, sep as pathSep } from "path
|
|||||||
import * as child_process from "child_process";
|
import * as child_process from "child_process";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { readBuildOptions } from "../shared/buildOptions";
|
import { readBuildOptions } from "../shared/buildOptions";
|
||||||
import { vitePluginSubScriptEnvNames } from "../shared/constants";
|
import { vitePluginSubScriptEnvNames, skipBuildJarsEnvName } from "../shared/constants";
|
||||||
import { buildJars } from "./buildJars";
|
import { buildJars } from "./buildJars";
|
||||||
import type { CliCommandOptions } from "../main";
|
import type { CliCommandOptions } from "../main";
|
||||||
import chalk from "chalk";
|
import chalk from "chalk";
|
||||||
@ -76,7 +76,13 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
build_jars: {
|
||||||
|
if (process.env[skipBuildJarsEnvName]) {
|
||||||
|
break build_jars;
|
||||||
|
}
|
||||||
|
|
||||||
await buildJars({ buildOptions });
|
await buildJars({ buildOptions });
|
||||||
|
}
|
||||||
|
|
||||||
console.log(chalk.green(`✓ built in ${((Date.now() - startTime) / 1000).toFixed(2)}s`));
|
console.log(chalk.green(`✓ built in ${((Date.now() - startTime) / 1000).toFixed(2)}s`));
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ export const vitePluginSubScriptEnvNames = {
|
|||||||
"resolveViteConfig": "KEYCLOAKIFY_RESOLVE_VITE_CONFIG"
|
"resolveViteConfig": "KEYCLOAKIFY_RESOLVE_VITE_CONFIG"
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
|
export const skipBuildJarsEnvName = "KEYCLOAKIFY_SKIP_BUILD_JAR";
|
||||||
|
|
||||||
export const loginThemePageIds = [
|
export const loginThemePageIds = [
|
||||||
"login.ftl",
|
"login.ftl",
|
||||||
"login-username.ftl",
|
"login-username.ftl",
|
||||||
|
@ -2,15 +2,19 @@ import { readBuildOptions } from "./shared/buildOptions";
|
|||||||
import type { CliCommandOptions as CliCommandOptions_common } from "./main";
|
import type { CliCommandOptions as CliCommandOptions_common } from "./main";
|
||||||
import { promptKeycloakVersion } from "./shared/promptKeycloakVersion";
|
import { promptKeycloakVersion } from "./shared/promptKeycloakVersion";
|
||||||
import { readMetaInfKeycloakThemes } from "./shared/metaInfKeycloakThemes";
|
import { readMetaInfKeycloakThemes } from "./shared/metaInfKeycloakThemes";
|
||||||
import { accountV1ThemeName } from "./shared/constants";
|
import { accountV1ThemeName, skipBuildJarsEnvName } from "./shared/constants";
|
||||||
import { SemVer } from "./tools/SemVer";
|
import { SemVer } from "./tools/SemVer";
|
||||||
import type { KeycloakVersionRange } from "./shared/KeycloakVersionRange";
|
import type { KeycloakVersionRange } from "./shared/KeycloakVersionRange";
|
||||||
import { getJarFileBasename } from "./shared/getJarFileBasename";
|
import { getJarFileBasename } from "./shared/getJarFileBasename";
|
||||||
import { assert, type Equals } from "tsafe/assert";
|
import { assert, type Equals } from "tsafe/assert";
|
||||||
import * as fs from "fs";
|
import * as fs from "fs";
|
||||||
import { join as pathJoin, posix as pathPosix } from "path";
|
import { join as pathJoin, relative as pathRelative, sep as pathSep, posix as pathPosix } from "path";
|
||||||
import * as child_process from "child_process";
|
import * as child_process from "child_process";
|
||||||
import chalk from "chalk";
|
import chalk from "chalk";
|
||||||
|
import chokidar from "chokidar";
|
||||||
|
import { waitForDebounceFactory } from "powerhooks/tools/waitForDebounce";
|
||||||
|
import { getThemeSrcDirPath } from "./shared/getThemeSrcDirPath";
|
||||||
|
import { Deferred } from "evt/tools/Deferred";
|
||||||
|
|
||||||
export type CliCommandOptions = CliCommandOptions_common & {
|
export type CliCommandOptions = CliCommandOptions_common & {
|
||||||
port: number;
|
port: number;
|
||||||
@ -91,13 +95,15 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("On which version of Keycloak do you want to test your theme?");
|
console.log(chalk.cyan("On which version of Keycloak do you want to test your theme?"));
|
||||||
|
|
||||||
const { keycloakVersion } = await promptKeycloakVersion({
|
const { keycloakVersion } = await promptKeycloakVersion({
|
||||||
"startingFromMajor": 17,
|
"startingFromMajor": 17,
|
||||||
"cacheDirPath": buildOptions.cacheDirPath
|
"cacheDirPath": buildOptions.cacheDirPath
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log(`→ ${keycloakVersion}`);
|
||||||
|
|
||||||
const keycloakMajorNumber = SemVer.parse(keycloakVersion).major;
|
const keycloakMajorNumber = SemVer.parse(keycloakVersion).major;
|
||||||
|
|
||||||
if (doesImplementAccountTheme && keycloakMajorNumber === 22) {
|
if (doesImplementAccountTheme && keycloakMajorNumber === 22) {
|
||||||
@ -182,10 +188,10 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|||||||
const containerName = "keycloak-keycloakify";
|
const containerName = "keycloak-keycloakify";
|
||||||
|
|
||||||
try {
|
try {
|
||||||
child_process.execSync(`docker rm ${containerName}`, { "stdio": "ignore" });
|
child_process.execSync(`docker rm --force ${containerName}`, { "stdio": "ignore" });
|
||||||
} catch {}
|
} catch {}
|
||||||
|
|
||||||
const child = child_process.spawn(
|
const spawnParams = [
|
||||||
"docker",
|
"docker",
|
||||||
[
|
[
|
||||||
"run",
|
"run",
|
||||||
@ -203,12 +209,20 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|||||||
{
|
{
|
||||||
"cwd": buildOptions.keycloakifyBuildDirPath
|
"cwd": buildOptions.keycloakifyBuildDirPath
|
||||||
}
|
}
|
||||||
);
|
] as const;
|
||||||
|
|
||||||
|
console.log(JSON.stringify(spawnParams, null, 2));
|
||||||
|
|
||||||
|
const child = child_process.spawn(...spawnParams);
|
||||||
|
|
||||||
child.stdout.on("data", data => process.stdout.write(data));
|
child.stdout.on("data", data => process.stdout.write(data));
|
||||||
|
|
||||||
child.stderr.on("data", data => process.stderr.write(data));
|
child.stderr.on("data", data => process.stderr.write(data));
|
||||||
|
|
||||||
|
child.on("exit", process.exit);
|
||||||
|
|
||||||
|
const { themeSrcDirPath } = getThemeSrcDirPath({ "reactAppRootDirPath": buildOptions.reactAppRootDirPath });
|
||||||
|
|
||||||
{
|
{
|
||||||
const handler = async (data: Buffer) => {
|
const handler = async (data: Buffer) => {
|
||||||
if (!data.toString("utf8").includes("Listening on: http://0.0.0.0:8080")) {
|
if (!data.toString("utf8").includes("Listening on: http://0.0.0.0:8080")) {
|
||||||
@ -224,7 +238,12 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|||||||
"",
|
"",
|
||||||
`${chalk.green("Your theme is accessible at:")}`,
|
`${chalk.green("Your theme is accessible at:")}`,
|
||||||
`${chalk.green("➜")} ${chalk.cyan.bold("https://test.keycloakify.dev/")}`,
|
`${chalk.green("➜")} ${chalk.cyan.bold("https://test.keycloakify.dev/")}`,
|
||||||
""
|
"",
|
||||||
|
`Keycloak Admin console: ${chalk.cyan.bold(`http://localhost:${cliCommandOptions.port}`)}`,
|
||||||
|
`- user: ${chalk.cyan.bold("admin")}`,
|
||||||
|
`- password: ${chalk.cyan.bold("admin")}`,
|
||||||
|
"",
|
||||||
|
`Watching for changes in ${chalk.bold(`.${pathSep}${pathRelative(process.cwd(), themeSrcDirPath)}`)} ...`
|
||||||
].join("\n")
|
].join("\n")
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -232,5 +251,50 @@ export async function command(params: { cliCommandOptions: CliCommandOptions })
|
|||||||
child.stdout.on("data", handler);
|
child.stdout.on("data", handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
child.on("exit", process.exit);
|
{
|
||||||
|
const { waitForDebounce } = waitForDebounceFactory({ "delay": 400 });
|
||||||
|
|
||||||
|
chokidar.watch(themeSrcDirPath, { "ignoreInitial": true }).on("all", async (...eventArgs) => {
|
||||||
|
console.log({ eventArgs });
|
||||||
|
|
||||||
|
await waitForDebounce();
|
||||||
|
|
||||||
|
console.log(chalk.cyan("Detected changes in the theme. Rebuilding ..."));
|
||||||
|
|
||||||
|
const dViteBuildDone = new Deferred<void>();
|
||||||
|
|
||||||
|
{
|
||||||
|
const child = child_process.spawn("npx", ["vite"], {
|
||||||
|
"cwd": buildOptions.reactAppRootDirPath,
|
||||||
|
"env": process.env
|
||||||
|
});
|
||||||
|
|
||||||
|
child.stdout.on("data", data => process.stdout.write(data));
|
||||||
|
|
||||||
|
child.stderr.on("data", data => process.stderr.write(data));
|
||||||
|
|
||||||
|
child.on("exit", code => {
|
||||||
|
if (code === 0) {
|
||||||
|
dViteBuildDone.resolve();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await dViteBuildDone.pr;
|
||||||
|
|
||||||
|
{
|
||||||
|
const child = child_process.spawn("npx", ["keycloakify", "build"], {
|
||||||
|
"cwd": buildOptions.reactAppRootDirPath,
|
||||||
|
"env": {
|
||||||
|
...process.env,
|
||||||
|
[skipBuildJarsEnvName]: "true"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
child.stdout.on("data", data => process.stdout.write(data));
|
||||||
|
|
||||||
|
child.stderr.on("data", data => process.stderr.write(data));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user