introduce options to choose a bundle strategy

Pick from 'none', 'keycloakify' or 'mvn', default to 'mvn'. 'none' will
not create a jar, 'keycloakify' will create a jar file using only tools
available to native nodejs, no additional  system library required.
Choosing 'mvn' will behave as before, starting maven in a subprocess.

The bundler can be chosen in `package.json` or via `KEYCLOAKIFY_BUNDLER`
env var.

This commit also adds `KEYCLOAKIFY_GROUP_ID` and
`KEYCLOAKIFY_ARTIFACT_ID` env vars, which will be used to
define group id and artifact id in pom.xml and pom.properties, if given.
This commit is contained in:
Waldemar Reusch 2023-02-03 14:28:06 +01:00
parent 2b87c35058
commit f4a547df11
3 changed files with 44 additions and 17 deletions

View File

@ -4,6 +4,8 @@ import type { Equals } from "tsafe";
import { id } from "tsafe/id";
import { parse as urlParse } from "url";
const BUNDLERS = ["mvn", "keycloakify", "none"] as const;
type Bundler = typeof BUNDLERS[number];
type ParsedPackageJson = {
name: string;
version: string;
@ -12,6 +14,9 @@ type ParsedPackageJson = {
extraPages?: string[];
extraThemeProperties?: string[];
areAppAndKeycloakServerSharingSameDomain?: boolean;
artifactId?: string;
groupId?: string;
bundler?: Bundler;
};
};
@ -23,7 +28,10 @@ const zParsedPackageJson = z.object({
.object({
"extraPages": z.array(z.string()).optional(),
"extraThemeProperties": z.array(z.string()).optional(),
"areAppAndKeycloakServerSharingSameDomain": z.boolean().optional()
"areAppAndKeycloakServerSharingSameDomain": z.boolean().optional(),
"artifactId": z.string().optional(),
"groupId": z.string().optional(),
"bundler": z.enum(BUNDLERS).optional()
})
.optional()
});
@ -40,8 +48,9 @@ export namespace BuildOptions {
themeName: string;
extraPages?: string[];
extraThemeProperties?: string[];
//NOTE: Only for the pom.xml file, questionable utility...
groupId: string;
artifactId?: string;
bundler?: Bundler;
};
export type Standalone = Common & {
@ -108,7 +117,7 @@ export function readBuildOptions(params: {
const common: BuildOptions.Common = (() => {
const { name, keycloakify = {}, version, homepage } = parsedPackageJson;
const { extraPages, extraThemeProperties } = keycloakify ?? {};
const { extraPages, extraThemeProperties, groupId, artifactId, bundler } = keycloakify ?? {};
const themeName = name
.replace(/^@(.*)/, "$1")
@ -117,10 +126,14 @@ export function readBuildOptions(params: {
return {
themeName,
"bundler": (process.env.KEYCLOAKIFY_BUNDLER ?? bundler) as Bundler | undefined,
"artifactId": process.env.KEYCLOAKIFY_ARTIFACT_ID ?? artifactId,
"groupId": (() => {
const fallbackGroupId = `${themeName}.keycloak`;
return (
process.env.KEYCLOAKIFY_GROUP_ID ??
groupId ??
(!homepage
? fallbackGroupId
: urlParse(homepage)
@ -130,7 +143,7 @@ export function readBuildOptions(params: {
.join(".") ?? fallbackGroupId) + ".keycloak"
);
})(),
"version": version,
"version": process.env.KEYCLOAKFIY_VERSION ?? version,
extraPages,
extraThemeProperties,
isSilent

View File

@ -7,6 +7,8 @@ import type { BuildOptions } from "./BuildOptions";
export type BuildOptionsLike = {
themeName: string;
groupId: string;
artifactId?: string;
version: string;
};
{
@ -16,7 +18,6 @@ export type BuildOptionsLike = {
}
export function generateJavaStackFiles(params: {
version: string;
keycloakThemeBuildingDirPath: string;
doBundlesEmailTemplate: boolean;
buildOptions: BuildOptionsLike;
@ -24,18 +25,17 @@ export function generateJavaStackFiles(params: {
jarFilePath: string;
} {
const {
version,
buildOptions: { groupId, themeName },
buildOptions: { groupId, themeName, version, artifactId },
keycloakThemeBuildingDirPath,
doBundlesEmailTemplate
} = params;
const finalArtifactId = artifactId ?? `${themeName}-keycloak-theme`;
{
const { pomFileCode } = (function generatePomFileCode(): {
pomFileCode: string;
} {
const artefactId = `${themeName}-keycloak-theme`;
const pomFileCode = [
`<?xml version="1.0"?>`,
`<project xmlns="http://maven.apache.org/POM/4.0.0"`,
@ -43,9 +43,9 @@ export function generateJavaStackFiles(params: {
` xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">`,
` <modelVersion>4.0.0</modelVersion>`,
` <groupId>${groupId}</groupId>`,
` <artifactId>${artefactId}</artifactId>`,
` <artifactId>${finalArtifactId}</artifactId>`,
` <version>${version}</version>`,
` <name>${artefactId}</name>`,
` <name>${finalArtifactId}</name>`,
` <description />`,
`</project>`
].join("\n");
@ -84,6 +84,6 @@ export function generateJavaStackFiles(params: {
}
return {
"jarFilePath": pathJoin(keycloakThemeBuildingDirPath, "target", `${themeName}-${version}.jar`)
"jarFilePath": pathJoin(keycloakThemeBuildingDirPath, "target", `${finalArtifactId}-${version}.jar`)
};
}

View File

@ -7,6 +7,7 @@ import * as fs from "fs";
import { readBuildOptions } from "./BuildOptions";
import { getLogger } from "../tools/logger";
import { getCliOptions } from "../tools/cliOptions";
import jar from "../tools/jar";
const reactProjectDirPath = process.cwd();
@ -45,17 +46,30 @@ export async function main() {
});
const { jarFilePath } = generateJavaStackFiles({
"version": buildOptions.version,
keycloakThemeBuildingDirPath,
doBundlesEmailTemplate,
buildOptions
});
child_process.execSync("mvn package", {
"cwd": keycloakThemeBuildingDirPath
});
if (buildOptions.bundler === "none") {
logger.log("😱 Skipping bundling step, there will be no jar");
} else if (buildOptions.bundler === "keycloakify") {
logger.log("🫶 Let keycloakify do its thang");
await jar({
"rootPath": keycloakThemeBuildingDirPath,
"version": buildOptions.version,
"groupId": buildOptions.groupId,
"artifactId": buildOptions.artifactId || `${buildOptions.themeName}-keycloak-theme`,
"targetPath": jarFilePath
});
} else {
logger.log("🫙 Run maven to deliver a jar");
child_process.execSync("mvn package", {
"cwd": keycloakThemeBuildingDirPath
});
}
//We want, however, to test in a container running the latest Keycloak version
// We want, however, to test in a container running the latest Keycloak version
const containerKeycloakVersion = "20.0.1";
generateStartKeycloakTestingContainer({