Remove inhouse bundler, we actually need Maven to build now
This commit is contained in:
parent
21d6d27435
commit
8c3e9ff192
@ -1,9 +1,5 @@
|
||||
import { assert } from "tsafe/assert";
|
||||
import { id } from "tsafe/id";
|
||||
import { parse as urlParse } from "url";
|
||||
import { typeGuard } from "tsafe/typeGuard";
|
||||
import { symToStr } from "tsafe/symToStr";
|
||||
import { bundlers, getParsedPackageJson, type Bundler } from "./parsedPackageJson";
|
||||
import { getParsedPackageJson } from "./parsedPackageJson";
|
||||
import { join as pathJoin, sep as pathSep } from "path";
|
||||
import parseArgv from "minimist";
|
||||
|
||||
@ -16,7 +12,7 @@ export type BuildOptions = {
|
||||
extraThemeProperties: string[] | undefined;
|
||||
groupId: string;
|
||||
artifactId: string;
|
||||
bundler: Bundler;
|
||||
doCreateJar: boolean;
|
||||
loginThemeResourcesFromKeycloakVersion: string;
|
||||
/** Directory of your built react project. Defaults to {cwd}/build */
|
||||
reactAppBuildDirPath: string;
|
||||
@ -42,7 +38,14 @@ export function readBuildOptions(params: { projectDirPath: string; processArgv:
|
||||
|
||||
const { name, keycloakify = {}, version, homepage } = parsedPackageJson;
|
||||
|
||||
const { extraThemeProperties, groupId, artifactId, bundler, loginThemeResourcesFromKeycloakVersion, extraThemeNames = [] } = keycloakify ?? {};
|
||||
const {
|
||||
extraThemeProperties,
|
||||
groupId,
|
||||
artifactId,
|
||||
doCreateJar,
|
||||
loginThemeResourcesFromKeycloakVersion,
|
||||
extraThemeNames = []
|
||||
} = keycloakify ?? {};
|
||||
|
||||
const themeName =
|
||||
keycloakify.themeName ??
|
||||
@ -54,16 +57,7 @@ export function readBuildOptions(params: { projectDirPath: string; processArgv:
|
||||
return {
|
||||
themeName,
|
||||
extraThemeNames,
|
||||
"bundler": (() => {
|
||||
const { KEYCLOAKIFY_BUNDLER } = process.env;
|
||||
|
||||
assert(
|
||||
typeGuard<Bundler | undefined>(KEYCLOAKIFY_BUNDLER, [undefined, ...id<readonly string[]>(bundlers)].includes(KEYCLOAKIFY_BUNDLER)),
|
||||
`${symToStr({ KEYCLOAKIFY_BUNDLER })} should be one of ${bundlers.join(", ")}`
|
||||
);
|
||||
|
||||
return KEYCLOAKIFY_BUNDLER ?? bundler ?? "keycloakify";
|
||||
})(),
|
||||
"doCreateJar": doCreateJar ?? true,
|
||||
"artifactId": process.env.KEYCLOAKIFY_ARTIFACT_ID ?? artifactId ?? `${themeName}-keycloak-theme`,
|
||||
"groupId": (() => {
|
||||
const fallbackGroupId = `${themeName}.keycloak`;
|
||||
|
@ -6,9 +6,7 @@ import { generateStartKeycloakTestingContainer } from "./generateStartKeycloakTe
|
||||
import * as fs from "fs";
|
||||
import { readBuildOptions } from "./BuildOptions";
|
||||
import { getLogger } from "../tools/logger";
|
||||
import jar from "../tools/jar";
|
||||
import { assert } from "tsafe/assert";
|
||||
import { Equals } from "tsafe";
|
||||
import { getThemeSrcDirPath } from "../getSrcDirPath";
|
||||
import { getProjectRoot } from "../tools/getProjectRoot";
|
||||
import { objectKeys } from "tsafe/objectKeys";
|
||||
@ -71,26 +69,12 @@ export async function main() {
|
||||
buildOptions
|
||||
});
|
||||
|
||||
switch (buildOptions.bundler) {
|
||||
case "none":
|
||||
logger.log("😱 Skipping bundling step, there will be no jar");
|
||||
break;
|
||||
case "keycloakify":
|
||||
logger.log("🫶 Let keycloakify do its thang");
|
||||
await jar({
|
||||
"rootPath": buildOptions.keycloakifyBuildDirPath,
|
||||
"version": buildOptions.themeVersion,
|
||||
"groupId": buildOptions.groupId,
|
||||
"artifactId": buildOptions.artifactId,
|
||||
"targetPath": jarFilePath
|
||||
});
|
||||
break;
|
||||
case "mvn":
|
||||
logger.log("🫙 Run maven to deliver a jar");
|
||||
create_jar: {
|
||||
if (!buildOptions.doCreateJar) {
|
||||
break create_jar;
|
||||
}
|
||||
|
||||
child_process.execSync("mvn package", { "cwd": buildOptions.keycloakifyBuildDirPath });
|
||||
break;
|
||||
default:
|
||||
assert<Equals<typeof buildOptions.bundler, never>>(false);
|
||||
}
|
||||
|
||||
// We want, however, to test in a container running the latest Keycloak version
|
||||
|
@ -4,8 +4,6 @@ import type { Equals } from "tsafe";
|
||||
import { z } from "zod";
|
||||
import { pathJoin } from "../tools/pathJoin";
|
||||
|
||||
export const bundlers = ["mvn", "keycloakify", "none"] as const;
|
||||
export type Bundler = (typeof bundlers)[number];
|
||||
export type ParsedPackageJson = {
|
||||
name: string;
|
||||
version?: string;
|
||||
@ -15,7 +13,7 @@ export type ParsedPackageJson = {
|
||||
areAppAndKeycloakServerSharingSameDomain?: boolean;
|
||||
artifactId?: string;
|
||||
groupId?: string;
|
||||
bundler?: Bundler;
|
||||
doCreateJar?: boolean;
|
||||
loginThemeResourcesFromKeycloakVersion?: string;
|
||||
reactAppBuildDirPath?: string;
|
||||
keycloakifyBuildDirPath?: string;
|
||||
@ -34,7 +32,7 @@ export const zParsedPackageJson = z.object({
|
||||
"areAppAndKeycloakServerSharingSameDomain": z.boolean().optional(),
|
||||
"artifactId": z.string().optional(),
|
||||
"groupId": z.string().optional(),
|
||||
"bundler": z.enum(bundlers).optional(),
|
||||
"doCreateJar": z.boolean().optional(),
|
||||
"loginThemeResourcesFromKeycloakVersion": z.string().optional(),
|
||||
"reactAppBuildDirPath": z.string().optional(),
|
||||
"keycloakifyBuildDirPath": z.string().optional(),
|
||||
|
@ -1,99 +0,0 @@
|
||||
import { dirname, relative, sep, join } from "path";
|
||||
import { createWriteStream } from "fs";
|
||||
|
||||
import walk from "./walk";
|
||||
import { ZipFile } from "yazl";
|
||||
import { mkdir } from "fs/promises";
|
||||
import trimIndent from "./trimIndent";
|
||||
|
||||
export type ZipEntry = { zipPath: string } & ({ fsPath: string } | { buffer: Buffer });
|
||||
export type ZipEntryGenerator = AsyncGenerator<ZipEntry, void, unknown>;
|
||||
|
||||
type CommonJarArgs = {
|
||||
groupId: string;
|
||||
artifactId: string;
|
||||
version: string;
|
||||
};
|
||||
|
||||
export type JarStreamArgs = CommonJarArgs & {
|
||||
asyncPathGeneratorFn(): ZipEntryGenerator;
|
||||
};
|
||||
|
||||
export type JarArgs = CommonJarArgs & {
|
||||
targetPath: string;
|
||||
rootPath: string;
|
||||
};
|
||||
|
||||
export async function jarStream({ groupId, artifactId, version, asyncPathGeneratorFn }: JarStreamArgs) {
|
||||
const manifestPath = "META-INF/MANIFEST.MF";
|
||||
const manifestData = Buffer.from(trimIndent`
|
||||
Manifest-Version: 1.0
|
||||
Archiver-Version: Plexus Archiver
|
||||
Created-By: Keycloakify
|
||||
Built-By: unknown
|
||||
Build-Jdk: 19.0.0
|
||||
`);
|
||||
|
||||
const pomPropsPath = `META-INF/maven/${groupId}/${artifactId}/pom.properties`;
|
||||
const pomPropsData = Buffer.from(trimIndent`
|
||||
# Generated by keycloakify
|
||||
# ${new Date()}
|
||||
artifactId=${artifactId}
|
||||
groupId=${groupId}
|
||||
version=${version}
|
||||
`);
|
||||
|
||||
const zipFile = new ZipFile();
|
||||
|
||||
for await (const entry of asyncPathGeneratorFn()) {
|
||||
if ("buffer" in entry) {
|
||||
zipFile.addBuffer(entry.buffer, entry.zipPath);
|
||||
} else if ("fsPath" in entry) {
|
||||
if (entry.fsPath.endsWith(sep)) {
|
||||
zipFile.addEmptyDirectory(entry.zipPath);
|
||||
} else {
|
||||
zipFile.addFile(entry.fsPath, entry.zipPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
zipFile.addBuffer(manifestData, manifestPath);
|
||||
zipFile.addBuffer(pomPropsData, pomPropsPath);
|
||||
|
||||
zipFile.end();
|
||||
|
||||
return zipFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a jar archive, using the resources found at `rootPath` (a directory) and write the
|
||||
* archive to `targetPath` (a file). Use `groupId`, `artifactId` and `version` to define
|
||||
* the contents of the pom.properties file which is going to be added to the archive.
|
||||
* The root directory is expectedto have a conventional maven/gradle folder structure with a
|
||||
* single `pom.xml` file at the root and a `src/main/resources` directory containing all
|
||||
* application resources.
|
||||
*/
|
||||
export default async function jar({ groupId, artifactId, version, rootPath, targetPath }: JarArgs) {
|
||||
await mkdir(dirname(targetPath), { recursive: true });
|
||||
|
||||
const asyncPathGeneratorFn = async function* (): ZipEntryGenerator {
|
||||
const resourcesPath = join(rootPath, "src", "main", "resources");
|
||||
for await (const fsPath of walk(resourcesPath)) {
|
||||
const zipPath = relative(resourcesPath, fsPath).split(sep).join("/");
|
||||
yield { fsPath, zipPath };
|
||||
}
|
||||
yield {
|
||||
fsPath: join(rootPath, "pom.xml"),
|
||||
zipPath: `META-INF/maven/${groupId}/${artifactId}/pom.xml`
|
||||
};
|
||||
};
|
||||
|
||||
const zipFile = await jarStream({ groupId, artifactId, version, asyncPathGeneratorFn });
|
||||
|
||||
await new Promise<void>(async (resolve, reject) => {
|
||||
zipFile.outputStream
|
||||
.pipe(createWriteStream(targetPath, { encoding: "binary" }))
|
||||
.on("close", () => resolve())
|
||||
.on("error", e => reject(e));
|
||||
});
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
import { readdir } from "fs/promises";
|
||||
import { resolve, sep } from "path";
|
||||
|
||||
/**
|
||||
* Asynchronously and recursively walk a directory tree, yielding every file and directory
|
||||
* found. Directory paths will _always_ end with a path separator.
|
||||
*
|
||||
* @param root the starting directory
|
||||
* @returns AsyncGenerator
|
||||
*/
|
||||
export default async function* walk(root: string): AsyncGenerator<string, void, unknown> {
|
||||
for (const entry of await readdir(root, { withFileTypes: true })) {
|
||||
const absolutePath = resolve(root, entry.name);
|
||||
if (entry.isDirectory()) {
|
||||
yield absolutePath.endsWith(sep) ? absolutePath : absolutePath + sep;
|
||||
yield* walk(absolutePath);
|
||||
} else yield absolutePath.endsWith(sep) ? absolutePath.substring(0, absolutePath.length - 1) : absolutePath;
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user