Refactor and update docker script

This commit is contained in:
garronej
2023-09-04 00:25:36 +02:00
parent 72e6309c4a
commit 5af8d67b62
4 changed files with 145 additions and 117 deletions

View File

@ -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")
});
}

View File

@ -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`)
}; };
} }

View File

@ -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`,
"" ""

View File

@ -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
}); });