Refactor and update docker script
This commit is contained in:
@ -0,0 +1,94 @@
|
|||||||
|
import * as fs from "fs";
|
||||||
|
import { join as pathJoin, dirname as pathDirname } from "path";
|
||||||
|
import { assert } from "tsafe/assert";
|
||||||
|
import { Reflect } from "tsafe/Reflect";
|
||||||
|
import type { BuildOptions } from "../BuildOptions";
|
||||||
|
import { resources_common, lastKeycloakVersionWithAccountV1 } from "../../constants";
|
||||||
|
import { downloadBuiltinKeycloakTheme } from "../../download-builtin-keycloak-theme";
|
||||||
|
import { transformCodebase } from "../../tools/transformCodebase";
|
||||||
|
|
||||||
|
export type BuildOptionsLike = {
|
||||||
|
keycloakifyBuildDirPath: string;
|
||||||
|
cacheDirPath: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
{
|
||||||
|
const buildOptions = Reflect<BuildOptions>();
|
||||||
|
|
||||||
|
assert<typeof buildOptions extends BuildOptionsLike ? true : false>();
|
||||||
|
}
|
||||||
|
|
||||||
|
export const accountV1 = "account-v1";
|
||||||
|
|
||||||
|
export async function bringInAccountV1(params: { buildOptions: BuildOptionsLike }) {
|
||||||
|
const { buildOptions } = params;
|
||||||
|
|
||||||
|
const builtinKeycloakThemeTmpDirPath = pathJoin(buildOptions.keycloakifyBuildDirPath, "..", "tmp_yxdE2_builtin_keycloak_theme");
|
||||||
|
|
||||||
|
await downloadBuiltinKeycloakTheme({
|
||||||
|
"destDirPath": builtinKeycloakThemeTmpDirPath,
|
||||||
|
"keycloakVersion": lastKeycloakVersionWithAccountV1,
|
||||||
|
buildOptions
|
||||||
|
});
|
||||||
|
|
||||||
|
const accountV1DirPath = pathJoin(buildOptions.keycloakifyBuildDirPath, "src", "main", "resources", "theme", accountV1, "account");
|
||||||
|
|
||||||
|
transformCodebase({
|
||||||
|
"srcDirPath": pathJoin(builtinKeycloakThemeTmpDirPath, "base", "account"),
|
||||||
|
"destDirPath": accountV1DirPath
|
||||||
|
});
|
||||||
|
|
||||||
|
const commonResourceFilePaths = [
|
||||||
|
"node_modules/patternfly/dist/css/patternfly.min.css",
|
||||||
|
"node_modules/patternfly/dist/css/patternfly-additions.min.css"
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const relativeFilePath of commonResourceFilePaths.map(path => pathJoin(...path.split("/")))) {
|
||||||
|
const destFilePath = pathJoin(accountV1DirPath, "resources", resources_common, relativeFilePath);
|
||||||
|
|
||||||
|
fs.mkdirSync(pathDirname(destFilePath), { "recursive": true });
|
||||||
|
|
||||||
|
fs.cpSync(pathJoin(builtinKeycloakThemeTmpDirPath, "keycloak", "common", "resources", relativeFilePath), destFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
const resourceFilePaths = ["css/account.css"];
|
||||||
|
|
||||||
|
for (const relativeFilePath of resourceFilePaths.map(path => pathJoin(...path.split("/")))) {
|
||||||
|
const destFilePath = pathJoin(accountV1DirPath, "resources", relativeFilePath);
|
||||||
|
|
||||||
|
fs.mkdirSync(pathDirname(destFilePath), { "recursive": true });
|
||||||
|
|
||||||
|
fs.cpSync(pathJoin(builtinKeycloakThemeTmpDirPath, "keycloak", "account", "resources", relativeFilePath), destFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
fs.rmSync(builtinKeycloakThemeTmpDirPath, { "recursive": true });
|
||||||
|
|
||||||
|
fs.writeFileSync(
|
||||||
|
pathJoin(accountV1DirPath, "theme.properties"),
|
||||||
|
Buffer.from(
|
||||||
|
[
|
||||||
|
"accountResourceProvider=org.keycloak.services.resources.account.AccountFormService",
|
||||||
|
"",
|
||||||
|
"locales=ar,ca,cs,da,de,en,es,fr,fi,hu,it,ja,lt,nl,no,pl,pt-BR,ru,sk,sv,tr,zh-CN",
|
||||||
|
"",
|
||||||
|
"styles=" + [...resourceFilePaths, ...commonResourceFilePaths.map(path => `resources_common/${path}`)].join(" "),
|
||||||
|
"",
|
||||||
|
"##### css classes for form buttons",
|
||||||
|
"# main class used for all buttons",
|
||||||
|
"kcButtonClass=btn",
|
||||||
|
"# classes defining priority of the button - primary or default (there is typically only one priority button for the form)",
|
||||||
|
"kcButtonPrimaryClass=btn-primary",
|
||||||
|
"kcButtonDefaultClass=btn-default",
|
||||||
|
"# classes defining size of the button",
|
||||||
|
"kcButtonLargeClass=btn-lg",
|
||||||
|
""
|
||||||
|
].join("\n"),
|
||||||
|
"utf8"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
transformCodebase({
|
||||||
|
"srcDirPath": pathJoin(__dirname, "account-v1-java"),
|
||||||
|
"destDirPath": pathJoin(buildOptions.keycloakifyBuildDirPath, "src", "main", "java", "org", "keycloak")
|
||||||
|
});
|
||||||
|
}
|
@ -3,9 +3,8 @@ import { join as pathJoin, dirname as pathDirname } from "path";
|
|||||||
import { assert } from "tsafe/assert";
|
import { assert } from "tsafe/assert";
|
||||||
import { Reflect } from "tsafe/Reflect";
|
import { Reflect } from "tsafe/Reflect";
|
||||||
import type { BuildOptions } from "../BuildOptions";
|
import type { BuildOptions } from "../BuildOptions";
|
||||||
import { type ThemeType, resources_common, lastKeycloakVersionWithAccountV1 } from "../../constants";
|
import { type ThemeType } from "../../constants";
|
||||||
import { downloadBuiltinKeycloakTheme } from "../../download-builtin-keycloak-theme";
|
import { bringInAccountV1, accountV1 } from "./bringInAccountV1";
|
||||||
import { transformCodebase } from "../../tools/transformCodebase";
|
|
||||||
|
|
||||||
export type BuildOptionsLike = {
|
export type BuildOptionsLike = {
|
||||||
themeName: string;
|
themeName: string;
|
||||||
@ -14,6 +13,7 @@ export type BuildOptionsLike = {
|
|||||||
artifactId: string;
|
artifactId: string;
|
||||||
themeVersion: string;
|
themeVersion: string;
|
||||||
cacheDirPath: string;
|
cacheDirPath: string;
|
||||||
|
keycloakifyBuildDirPath: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -23,13 +23,12 @@ export type BuildOptionsLike = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export async function generateJavaStackFiles(params: {
|
export async function generateJavaStackFiles(params: {
|
||||||
keycloakThemeBuildingDirPath: string;
|
|
||||||
implementedThemeTypes: Record<ThemeType | "email", boolean>;
|
implementedThemeTypes: Record<ThemeType | "email", boolean>;
|
||||||
buildOptions: BuildOptionsLike;
|
buildOptions: BuildOptionsLike;
|
||||||
}): Promise<{
|
}): Promise<{
|
||||||
jarFilePath: string;
|
jarFilePath: string;
|
||||||
}> {
|
}> {
|
||||||
const { keycloakThemeBuildingDirPath, implementedThemeTypes, buildOptions } = params;
|
const { implementedThemeTypes, buildOptions } = params;
|
||||||
|
|
||||||
{
|
{
|
||||||
const { pomFileCode } = (function generatePomFileCode(): {
|
const { pomFileCode } = (function generatePomFileCode(): {
|
||||||
@ -151,84 +150,15 @@ export async function generateJavaStackFiles(params: {
|
|||||||
return { pomFileCode };
|
return { pomFileCode };
|
||||||
})();
|
})();
|
||||||
|
|
||||||
fs.writeFileSync(pathJoin(keycloakThemeBuildingDirPath, "pom.xml"), Buffer.from(pomFileCode, "utf8"));
|
fs.writeFileSync(pathJoin(buildOptions.keycloakifyBuildDirPath, "pom.xml"), Buffer.from(pomFileCode, "utf8"));
|
||||||
}
|
}
|
||||||
|
|
||||||
const accountV1 = "account-v1";
|
if (implementedThemeTypes.account) {
|
||||||
|
await bringInAccountV1({ buildOptions });
|
||||||
{
|
|
||||||
const builtinKeycloakThemeTmpDirPath = pathJoin(keycloakThemeBuildingDirPath, "..", "tmp_yxdE2_builtin_keycloak_theme");
|
|
||||||
|
|
||||||
await downloadBuiltinKeycloakTheme({
|
|
||||||
"destDirPath": builtinKeycloakThemeTmpDirPath,
|
|
||||||
"keycloakVersion": lastKeycloakVersionWithAccountV1,
|
|
||||||
buildOptions
|
|
||||||
});
|
|
||||||
|
|
||||||
const accountV1DirPath = pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources", "theme", accountV1, "account");
|
|
||||||
|
|
||||||
transformCodebase({
|
|
||||||
"srcDirPath": pathJoin(builtinKeycloakThemeTmpDirPath, "base", "account"),
|
|
||||||
"destDirPath": accountV1DirPath
|
|
||||||
});
|
|
||||||
|
|
||||||
const commonResourceFilePaths = [
|
|
||||||
"node_modules/patternfly/dist/css/patternfly.min.css",
|
|
||||||
"node_modules/patternfly/dist/css/patternfly-additions.min.css"
|
|
||||||
];
|
|
||||||
|
|
||||||
for (const relativeFilePath of commonResourceFilePaths.map(path => pathJoin(...path.split("/")))) {
|
|
||||||
const destFilePath = pathJoin(accountV1DirPath, "resources", resources_common, relativeFilePath);
|
|
||||||
|
|
||||||
fs.mkdirSync(pathDirname(destFilePath), { "recursive": true });
|
|
||||||
|
|
||||||
fs.cpSync(pathJoin(builtinKeycloakThemeTmpDirPath, "keycloak", "common", "resources", relativeFilePath), destFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
const resourceFilePaths = ["css/account.css"];
|
|
||||||
|
|
||||||
for (const relativeFilePath of resourceFilePaths.map(path => pathJoin(...path.split("/")))) {
|
|
||||||
const destFilePath = pathJoin(accountV1DirPath, "resources", relativeFilePath);
|
|
||||||
|
|
||||||
fs.mkdirSync(pathDirname(destFilePath), { "recursive": true });
|
|
||||||
|
|
||||||
fs.cpSync(pathJoin(builtinKeycloakThemeTmpDirPath, "keycloak", "account", "resources", relativeFilePath), destFilePath);
|
|
||||||
}
|
|
||||||
|
|
||||||
fs.rmSync(builtinKeycloakThemeTmpDirPath, { "recursive": true });
|
|
||||||
|
|
||||||
fs.writeFileSync(
|
|
||||||
pathJoin(accountV1DirPath, "theme.properties"),
|
|
||||||
Buffer.from(
|
|
||||||
[
|
|
||||||
"accountResourceProvider=org.keycloak.services.resources.account.AccountFormService",
|
|
||||||
"",
|
|
||||||
"locales=ar,ca,cs,da,de,en,es,fr,fi,hu,it,ja,lt,nl,no,pl,pt-BR,ru,sk,sv,tr,zh-CN",
|
|
||||||
"",
|
|
||||||
"styles=" + [...resourceFilePaths, ...commonResourceFilePaths.map(path => `resources_common/${path}`)].join(" "),
|
|
||||||
"",
|
|
||||||
"##### css classes for form buttons",
|
|
||||||
"# main class used for all buttons",
|
|
||||||
"kcButtonClass=btn",
|
|
||||||
"# classes defining priority of the button - primary or default (there is typically only one priority button for the form)",
|
|
||||||
"kcButtonPrimaryClass=btn-primary",
|
|
||||||
"kcButtonDefaultClass=btn-default",
|
|
||||||
"# classes defining size of the button",
|
|
||||||
"kcButtonLargeClass=btn-lg",
|
|
||||||
""
|
|
||||||
].join("\n"),
|
|
||||||
"utf8"
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
transformCodebase({
|
|
||||||
"srcDirPath": pathJoin(__dirname, "account-v1-java"),
|
|
||||||
"destDirPath": pathJoin(keycloakThemeBuildingDirPath, "src", "main", "java", "org", "keycloak")
|
|
||||||
});
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const themeManifestFilePath = pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources", "META-INF", "keycloak-themes.json");
|
const themeManifestFilePath = pathJoin(buildOptions.keycloakifyBuildDirPath, "src", "main", "resources", "META-INF", "keycloak-themes.json");
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fs.mkdirSync(pathDirname(themeManifestFilePath));
|
fs.mkdirSync(pathDirname(themeManifestFilePath));
|
||||||
@ -240,16 +170,32 @@ export async function generateJavaStackFiles(params: {
|
|||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
{
|
{
|
||||||
"themes": [
|
"themes": [
|
||||||
{
|
...(!implementedThemeTypes.account
|
||||||
"name": accountV1,
|
? []
|
||||||
"types": ["account"]
|
: [
|
||||||
},
|
{
|
||||||
...[buildOptions.themeName, ...buildOptions.extraThemeNames].map(themeName => ({
|
"name": accountV1,
|
||||||
"name": themeName,
|
"types": ["account"]
|
||||||
"types": Object.entries(implementedThemeTypes)
|
}
|
||||||
.filter(([, isImplemented]) => isImplemented)
|
]),
|
||||||
.map(([themeType]) => themeType)
|
...[buildOptions.themeName, ...buildOptions.extraThemeNames]
|
||||||
}))
|
.map(themeName => [
|
||||||
|
{
|
||||||
|
"name": themeName,
|
||||||
|
"types": Object.entries(implementedThemeTypes)
|
||||||
|
.filter(([, isImplemented]) => isImplemented)
|
||||||
|
.map(([themeType]) => themeType)
|
||||||
|
},
|
||||||
|
...(!implementedThemeTypes.account
|
||||||
|
? []
|
||||||
|
: [
|
||||||
|
{
|
||||||
|
"name": `${themeName}_retrocompatible`,
|
||||||
|
"types": ["account"]
|
||||||
|
}
|
||||||
|
])
|
||||||
|
])
|
||||||
|
.flat()
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
null,
|
null,
|
||||||
@ -261,6 +207,6 @@ export async function generateJavaStackFiles(params: {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"jarFilePath": pathJoin(keycloakThemeBuildingDirPath, "target", `${buildOptions.artifactId}-${buildOptions.themeVersion}.jar`)
|
"jarFilePath": pathJoin(buildOptions.keycloakifyBuildDirPath, "target", `${buildOptions.artifactId}-${buildOptions.themeVersion}.jar`)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -5,8 +5,7 @@ import { Reflect } from "tsafe/Reflect";
|
|||||||
import type { BuildOptions } from "./BuildOptions";
|
import type { BuildOptions } from "./BuildOptions";
|
||||||
|
|
||||||
export type BuildOptionsLike = {
|
export type BuildOptionsLike = {
|
||||||
themeName: string;
|
keycloakifyBuildDirPath: string;
|
||||||
extraThemeNames: string[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
{
|
{
|
||||||
@ -20,39 +19,34 @@ generateStartKeycloakTestingContainer.basename = "start_keycloak_testing_contain
|
|||||||
const containerName = "keycloak-testing-container";
|
const containerName = "keycloak-testing-container";
|
||||||
|
|
||||||
/** Files for being able to run a hot reload keycloak container */
|
/** Files for being able to run a hot reload keycloak container */
|
||||||
export function generateStartKeycloakTestingContainer(params: {
|
export function generateStartKeycloakTestingContainer(params: { keycloakVersion: string; buildOptions: BuildOptionsLike }) {
|
||||||
keycloakVersion: string;
|
const { keycloakVersion, buildOptions } = params;
|
||||||
keycloakThemeBuildingDirPath: string;
|
|
||||||
buildOptions: BuildOptionsLike;
|
const themeRelativeDirPath = pathJoin("src", "main", "resources", "theme");
|
||||||
}) {
|
const themeDirPath = pathJoin(buildOptions.keycloakifyBuildDirPath, themeRelativeDirPath);
|
||||||
const {
|
|
||||||
keycloakThemeBuildingDirPath,
|
|
||||||
keycloakVersion,
|
|
||||||
buildOptions: { themeName, extraThemeNames }
|
|
||||||
} = params;
|
|
||||||
|
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
pathJoin(keycloakThemeBuildingDirPath, generateStartKeycloakTestingContainer.basename),
|
pathJoin(buildOptions.keycloakifyBuildDirPath, generateStartKeycloakTestingContainer.basename),
|
||||||
Buffer.from(
|
Buffer.from(
|
||||||
[
|
[
|
||||||
"#!/usr/bin/env bash",
|
"#!/usr/bin/env bash",
|
||||||
"",
|
"",
|
||||||
`docker rm ${containerName} || true`,
|
`docker rm ${containerName} || true`,
|
||||||
"",
|
"",
|
||||||
`cd "${keycloakThemeBuildingDirPath.replace(/\\/g, "/")}"`,
|
`cd "${buildOptions.keycloakifyBuildDirPath}"`,
|
||||||
"",
|
"",
|
||||||
"docker run \\",
|
"docker run \\",
|
||||||
" -p 8080:8080 \\",
|
" -p 8080:8080 \\",
|
||||||
` --name ${containerName} \\`,
|
` --name ${containerName} \\`,
|
||||||
" -e KEYCLOAK_ADMIN=admin \\",
|
" -e KEYCLOAK_ADMIN=admin \\",
|
||||||
" -e KEYCLOAK_ADMIN_PASSWORD=admin \\",
|
" -e KEYCLOAK_ADMIN_PASSWORD=admin \\",
|
||||||
...[themeName, ...extraThemeNames].map(
|
...fs
|
||||||
themeName =>
|
.readdirSync(themeDirPath)
|
||||||
` -v "${pathJoin(keycloakThemeBuildingDirPath, "src", "main", "resources", "theme", themeName).replace(
|
.filter(name => fs.lstatSync(pathJoin(themeDirPath, name)).isDirectory())
|
||||||
/\\/g,
|
.map(
|
||||||
"/"
|
themeName =>
|
||||||
)}":"/opt/keycloak/themes/${themeName}":rw \\`
|
` -v "${pathJoin(".", themeRelativeDirPath, themeName).replace(/\\/g, "/")}":"/opt/keycloak/themes/${themeName}":rw \\`
|
||||||
),
|
),
|
||||||
` -it quay.io/keycloak/keycloak:${keycloakVersion} \\`,
|
` -it quay.io/keycloak/keycloak:${keycloakVersion} \\`,
|
||||||
` start-dev --features=declarative-user-profile`,
|
` start-dev --features=declarative-user-profile`,
|
||||||
""
|
""
|
||||||
|
@ -45,7 +45,6 @@ export async function main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const { jarFilePath } = await generateJavaStackFiles({
|
const { jarFilePath } = await generateJavaStackFiles({
|
||||||
"keycloakThemeBuildingDirPath": buildOptions.keycloakifyBuildDirPath,
|
|
||||||
"implementedThemeTypes": (() => {
|
"implementedThemeTypes": (() => {
|
||||||
const implementedThemeTypes = {
|
const implementedThemeTypes = {
|
||||||
"login": false,
|
"login": false,
|
||||||
@ -65,11 +64,7 @@ export async function main() {
|
|||||||
buildOptions
|
buildOptions
|
||||||
});
|
});
|
||||||
|
|
||||||
create_jar: {
|
if (buildOptions.doCreateJar) {
|
||||||
if (!buildOptions.doCreateJar) {
|
|
||||||
break create_jar;
|
|
||||||
}
|
|
||||||
|
|
||||||
child_process.execSync("mvn package", { "cwd": buildOptions.keycloakifyBuildDirPath });
|
child_process.execSync("mvn package", { "cwd": buildOptions.keycloakifyBuildDirPath });
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +72,6 @@ export async function main() {
|
|||||||
const containerKeycloakVersion = "21.1.2";
|
const containerKeycloakVersion = "21.1.2";
|
||||||
|
|
||||||
generateStartKeycloakTestingContainer({
|
generateStartKeycloakTestingContainer({
|
||||||
keycloakThemeBuildingDirPath: buildOptions.keycloakifyBuildDirPath,
|
|
||||||
"keycloakVersion": containerKeycloakVersion,
|
"keycloakVersion": containerKeycloakVersion,
|
||||||
buildOptions
|
buildOptions
|
||||||
});
|
});
|
||||||
|
Reference in New Issue
Block a user