From 05401d655f71a43df865a1429b56c82fc1387cef Mon Sep 17 00:00:00 2001 From: Simon Ziegler Date: Wed, 28 Feb 2024 03:45:22 +0100 Subject: [PATCH] rewrote build script in typescript --- .eslintrc | 3 +- .gitignore | 4 +- build.ps1 | 52 -------- build/scripts/build.ts | 119 ++++++++++++++++++ .../scripts/license-reporter.config.ts | 3 +- .../scripts/sea-config.json | 0 build/scripts/tsconfig.json | 7 ++ package-lock.json | 21 ++++ package.json | 6 +- src/server/config.ts | 2 +- 10 files changed, 159 insertions(+), 58 deletions(-) delete mode 100644 build.ps1 create mode 100644 build/scripts/build.ts rename license-reporter.config.ts => build/scripts/license-reporter.config.ts (96%) rename sea-config.json => build/scripts/sea-config.json (100%) create mode 100644 build/scripts/tsconfig.json diff --git a/.eslintrc b/.eslintrc index 7c55373..9705965 100644 --- a/.eslintrc +++ b/.eslintrc @@ -8,7 +8,8 @@ "project": [ "src/server/tsconfig.json", "src/client/tsconfig.json", - "src/templates/tsconfig.json" + "src/templates/tsconfig.json", + "build/scripts/tsconfig.json" ] }, "extends": [ diff --git a/.gitignore b/.gitignore index e0a5ccc..63b900a 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,6 @@ dist client/*.js casparcg-templates/JohnCG/*.js *.map -client/webfonts/bahnschrift.ttf \ No newline at end of file +client/webfonts/bahnschrift.ttf +build/scripts/*.js +build/scripts/3rdpartylicenses.json \ No newline at end of file diff --git a/build.ps1 b/build.ps1 deleted file mode 100644 index 530837d..0000000 --- a/build.ps1 +++ /dev/null @@ -1,52 +0,0 @@ -# extract the buildname from the package.json -$package_json = Get-Content -Raw package.json | ConvertFrom-Json -$build_name = "JohnCG_" + $package_json.version - -# name of the executabe -$node_exec_name = $build_name + ".exe" -$node_exec_name = "node.exe" # overwritten until there is a solution for packaging `sharp` - -# clear the dist directory -Remove-Item -Path .\dist -Recurse -New-Item -Type Directory .\dist\build -New-Item -Type Directory .\dist\$build_name - -# bundle the files -npm run build-server -npm run build-client -npm run build-templates - -# create sea-prep.blob -# node --experimental-sea-config .\sea-config.json - -# get the node executable -node -e "require('fs').copyFileSync(process.execPath, 'dist/build/$node_exec_name')" - -# disabled until there is a solution for packaging `sharp` -# # remove the signature from the node executable -# & 'C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\signtool.exe' remove /s dist/build/$node_exec_name -# # modify the node executable -# npx postject dist/build/$node_exec_name NODE_SEA_BLOB dist/build/sea-prep.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 - -# copy the files in the output -Copy-Item -Path .\config.json -Destination .\dist\$build_name -Exclude .eslintrc -Copy-Item -Path .\casparcg-templates -Destination .\dist\$build_name -Exclude .eslintrc,*.map -Recurse -Copy-Item -Path .\client -Destination .\dist\$build_name -Exclude .eslintrc,*.map,bahnschrift.ttf -Recurse -Copy-Item -Path .\dist\build\$node_exec_name .\dist\$build_name -Recurse - -Copy-Item -Path .\node_modules\@img -Destination .\dist\$build_name\node_modules\@img\ -Recurse -Copy-Item -Path .\dist\build\main.js -Destination .\dist\$build_name\main.js - -# create a batch file, that starts node with the main.js -New-Item -Path .\dist\$build_name\$build_name.bat -Value "node.exe main.js`npause" - -# create and copy the licenses -npx esbuild license-generator.ts --platform=node --bundle --minify --outfile=.\dist\build\license-generator.js -npx license-reporter -node .\dist\build\license-generator.js - -Copy-Item -Path .\dist\build\licenses -Destination .\dist\$build_name\ -Recurse -# Copy-Item -Path .\LICENSE -Destination .\dist\$build_name\LICENSE - -# pack the files in a .tar.gz-file -tar -cvzf .\dist\$build_name.tar.gz --directory=dist $build_name \ No newline at end of file diff --git a/build/scripts/build.ts b/build/scripts/build.ts new file mode 100644 index 0000000..05b494b --- /dev/null +++ b/build/scripts/build.ts @@ -0,0 +1,119 @@ +import { execSync } from "child_process"; +import fs from "fs"; +import path from "path"; +import tar from "tar"; + +import { ConfigJSON } from "../../src/server/config"; + +// load the package.json +const package_json = JSON.parse(fs.readFileSync("package.json", "utf-8")) as { version: string; dependencies: string[] }; + +const build_name = "JohnCG_" + package_json.version; +// temporary method until there is a solution for packaging sharp +// const exec_name = build_name + ".exe"; +const exec_name = "node.exe"; +const build_dir = "dist/build"; +const release_dir = path.join("dist", build_name); + +// clear the build-directory +fs.rmSync("dist", { recursive: true, force: true }); +fs.mkdirSync(build_dir, { recursive: true }); +fs.mkdirSync(path.join("dist", build_name), { recursive: true }); + +const copy_build_file = (file: string, dest?: string) => fs.copyFileSync(file, path.join(build_dir, dest ?? path.basename(file))); +// const copy_build_dir = (dir: string, dest?: string, args?: fs.CopySyncOptions) => fs.cpSync(dir, path.join(build_dir, dest ?? path.basename(dir)), { recursive: true, ...args }); +const copy_release_file = (file: string, dest?: string) => fs.copyFileSync(file, path.join(release_dir, dest ?? path.basename(file))); +const copy_release_dir = (dir: string, dest?: string, args?: fs.CopySyncOptions) => fs.cpSync(dir, path.join(release_dir, dest ?? path.basename(dir)), { recursive: true, ...args }); + +// bundle the different scripts +execSync("npm run build-server"); +execSync("npm run build-client"); +execSync("npm run build-templates"); + +// temporary method until there is a solution for packaging sharp +// // create sea-prep.blob +// execSync("node --experimental-sea-config sea-config.json"); + +// get the node executable +copy_build_file(process.execPath, exec_name); + +// temporary method until there is a solution for packaging sharp +// // remove the signature from the node executable +// execSync(`'C:\\Program Files (x86)\\Windows Kits\\10\\bin\\10.0.22621.0\\x64\\signtool.exe' remove /s dist/build/${exec_name}`); +// // modify the node executable +// execSync(`npx postject dist/build/${exec_name} NODE_SEA_BLOB dist/build/sea-prep.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2`); + +// load the config-file, censor the file-paths and store it for the relase +const config_file = JSON.parse(fs.readFileSync("config.json", "utf-8")) as ConfigJSON; +config_file.path = { + background_image: "C:/path/to/image/directory", + song: "D:/path/to/song/directory" +}; +config_file.casparcg.templates = "e:/path/to/the/casparcg/templates/directory"; +fs.writeFileSync(path.join(release_dir, "config.json"), JSON.stringify(config_file, undefined, "\t")); + +// copy the file to the output +copy_release_file(path.join(build_dir, exec_name)); +copy_release_file(path.join(build_dir, "main.js")); + +copy_release_dir("casparcg-templates", undefined, { filter: (src) => { + switch (true) { + case path.basename(src) === ".eslintrc": + case [".js", ".map"].includes(path.extname(src)): + return false; + default: + return true; + } +} }); +copy_release_dir("client", undefined, { filter: (src) => { + switch (true) { + case [".eslintrc", "bahnschrift.ttf"].includes(path.basename(src)): + case [".js", ".map"].includes(path.extname(src)): + return false; + default: + return true; + } +} }); +copy_release_dir("node_modules/@img", path.join(release_dir, "node_modules/@img/")); + +// temporary method until there is a solution for packaging sharp +// create a batch file, that start node with the main.js +fs.writeFileSync(path.join(release_dir, build_name + ".bat"), `${exec_name} main.js\npause`); + +// create and copy the licenses +// void lr.cli(["--config=build/scripts/license-reporter.config.ts"]); +try { + execSync("npx license-reporter --config build/scripts/license-reporter.config.ts"); +} catch (e) { /* empty */ } + +// eslint-disable-next-line @typescript-eslint/naming-convention +interface License { name: string; licenseText: string } +const licenses_orig = JSON.parse(fs.readFileSync("build/scripts/3rdpartylicenses.json", "utf-8")) as License[]; + +const licenses: Record = {}; + +licenses_orig.forEach((pack) => { + licenses[pack.name] = pack; +}); + +fs.mkdirSync("dist/build/licenses"); + +Object.keys(package_json.dependencies).forEach((pack) => { + const lic = licenses[pack]; + + try { + fs.writeFileSync(`dist/build/licenses/${lic.name}.txt`, lic.licenseText, "utf-8"); + } catch (e) { + if (lic.licenseText === undefined) { + throw new EvalError(`ERROR: no license was found for the package '${lic.name}'`); + } + } +}); + +copy_release_file("LICENSE", "LICENSE.txt"); + +// copy the licenses +copy_release_dir(path.join(build_dir, "licenses")); + +// pack the files in a .tar.gz-file +void tar.c({ gzip: true, file: release_dir + ".tar.gz" }, [release_dir]); \ No newline at end of file diff --git a/license-reporter.config.ts b/build/scripts/license-reporter.config.ts similarity index 96% rename from license-reporter.config.ts rename to build/scripts/license-reporter.config.ts index 6a7e395..400f16f 100644 --- a/license-reporter.config.ts +++ b/build/scripts/license-reporter.config.ts @@ -2,7 +2,8 @@ import { IReporterConfiguration } from "@weichwarenprojekt/license-reporter"; export const configuration: Partial = { // defaultLicenseText: undefined, - output: "dist/build/3rdpartylicenses.json", + output: "build/scripts/3rdpartylicenses.json", + ignore: ["dist/*"], overrides: [ { name: "osc" diff --git a/sea-config.json b/build/scripts/sea-config.json similarity index 100% rename from sea-config.json rename to build/scripts/sea-config.json diff --git a/build/scripts/tsconfig.json b/build/scripts/tsconfig.json new file mode 100644 index 0000000..6005d72 --- /dev/null +++ b/build/scripts/tsconfig.json @@ -0,0 +1,7 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "removeComments": true + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 194e61a..86e8494 100644 --- a/package-lock.json +++ b/package-lock.json @@ -27,6 +27,7 @@ "@types/mime-types": "^2.1.4", "@types/node": "^20.11.16", "@types/node-osc": "^6.0.3", + "@types/tar": "^6.1.11", "@types/tmp": "^0.2.6", "@types/ws": "^8.5.10", "@typescript-eslint/eslint-plugin": "^6.21.0", @@ -35,6 +36,7 @@ "esbuild": "^0.20.0", "eslint": "^8.56.0", "postject": "^1.0.0-alpha.6", + "tar": "^6.2.0", "typescript": "^5.3.3" } }, @@ -721,6 +723,25 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/tar": { + "version": "6.1.11", + "resolved": "https://registry.npmjs.org/@types/tar/-/tar-6.1.11.tgz", + "integrity": "sha512-ThA1WD8aDdVU4VLuyq5NEqriwXErF5gEIJeyT6gHBWU7JtSmW2a5qjNv3/vR82O20mW+1vhmeZJfBQPT3HCugg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "minipass": "^4.0.0" + } + }, + "node_modules/@types/tar/node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/@types/tmp": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.2.6.tgz", diff --git a/package.json b/package.json index 17e78b4..243b1f4 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,7 @@ "@types/mime-types": "^2.1.4", "@types/node": "^20.11.16", "@types/node-osc": "^6.0.3", + "@types/tar": "^6.1.11", "@types/tmp": "^0.2.6", "@types/ws": "^8.5.10", "@typescript-eslint/eslint-plugin": "^6.21.0", @@ -28,12 +29,13 @@ "esbuild": "^0.20.0", "eslint": "^8.56.0", "postject": "^1.0.0-alpha.6", + "tar": "^6.2.0", "typescript": "^5.3.3" }, "scripts": { "lint": "eslint src/**/*.ts", - "build-release": "@powershell -NoProfile -ExecutionPolicy Unrestricted -Command ./build.ps1", - "build-server": "esbuild src/server/main.ts --outfile=dist/build/main.js --tsconfig=src/server/tsconfig.json --platform=node --minify --bundle", + "build-release": "esbuild build/scripts/build.ts --outfile=build/scripts/build.js --tsconfig=build/scripts/tsconfig.json --platform=node --bundle && node build/scripts/build.js", + "build-server": "esbuild src/server/main.ts --outfile=dist/build/main.js --tsconfig=src/server/tsconfig.json --platform=node --minify --bundle --external:pdfjs-dist --external:canvas", "build-client": "esbuild src/client/main.ts --outfile=client/main.js --tsconfig=src/client/tsconfig.json --bundle --minify", "watch-client": "esbuild src/client/main.ts --outfile=client/main.js --tsconfig=src/client/tsconfig.json --bundle --sourcemap --watch", "build-templates": "esbuild src/templates/*.ts --outdir=casparcg-templates/JohnCG/ --tsconfig=src/templates/tsconfig.json --target=chrome117 --minify", diff --git a/src/server/config.ts b/src/server/config.ts index a1916a5..062a0a1 100644 --- a/src/server/config.ts +++ b/src/server/config.ts @@ -5,7 +5,7 @@ export interface CasparCGConnectionSettings { layers: [number, number]; } -interface ConfigJSON { +export interface ConfigJSON { behaviour: { show_on_load: boolean; };