From d9cd211149473b8c405664ef8cc2b821adb0aea5 Mon Sep 17 00:00:00 2001 From: sawka Date: Tue, 1 Nov 2022 21:18:40 -0700 Subject: [PATCH] packaging with scripthaus-server and mshell binaries, separate dev/prod builds. emain to launch local server from package --- .gitignore | 1 + forge.config.js | 1 + package.json | 2 +- scripthaus.md | 19 +++++++-- src/emain.ts | 85 +++++++++++++++++++++++++++++++++------- static/index.html | 2 +- static/remotes.html | 1 - webpack.common.js | 4 +- webpack.dev.js | 5 +++ webpack.electron.js | 4 +- webpack.electron.prod.js | 34 ++++++++++++++++ webpack.prod.js | 11 ++---- 12 files changed, 139 insertions(+), 30 deletions(-) delete mode 100644 static/remotes.html create mode 100644 webpack.electron.prod.js diff --git a/.gitignore b/.gitignore index ee5bf5009..005352d31 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ dist/ +dist-dev/ node_modules/ *~ *.log diff --git a/forge.config.js b/forge.config.js index 893f79ec6..86fe06b32 100644 --- a/forge.config.js +++ b/forge.config.js @@ -3,6 +3,7 @@ var AllowedFirstParts = { "dist": true, "static": true, "node_modules": true, + "bin": true, }; var AllowedNodeModules = { diff --git a/package.json b/package.json index df1c2885a..e714179cf 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "ScriptHaus", "version": "1.0.0", - "main": "dist/emain-dev.js", + "main": "dist/emain.js", "license": "Proprietary", "dependencies": { "autobind-decorator": "^2.4.0", diff --git a/scripthaus.md b/scripthaus.md index 639f7c009..407f23ac3 100644 --- a/scripthaus.md +++ b/scripthaus.md @@ -34,7 +34,7 @@ node_modules/.bin/electron-rebuild ```bash # @scripthaus command electron # @scripthaus cd :playbook -SH_DEV=1 node_modules/.bin/electron dist/emain-dev.js +SH_DEV=1 node_modules/.bin/electron dist-dev/emain.js ``` ```bash @@ -52,7 +52,20 @@ node_modules/.bin/tsc --jsx preserve --noEmit --esModuleInterop --target ES5 --e ```bash # @scripthaus command build-package # @scripthaus cd :playbook -node_modules/.bin/webpack --config webpack.dev.js -node_modules/.bin/webpack --config webpack.electron.js +rm -rf dist/ +rm -rf bin/ +node_modules/.bin/webpack --config webpack.prod.js +node_modules/.bin/webpack --config webpack.electron.prod.js +(cd ../mshell; GOOS=darwin GOARCH=amd64 go build -ldflags="-s -w" -o ../sh2/bin/mshell/mshell-v0.2-darwin.amd64 main-mshell.go) +(cd ../mshell; GOOS=darwin GOARCH=arm64 go build -ldflags="-s -w" -o ../sh2/bin/mshell/mshell-v0.2-darwin.arm64 main-mshell.go) +(cd ../mshell; GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o ../sh2/bin/mshell/mshell-v0.2-linux.amd64 main-mshell.go) +(cd ../mshell; GOOS=linux GOARCH=arm64 go build -ldflags="-s -w" -o ../sh2/bin/mshell/mshell-v0.2-linux.arm64 main-mshell.go) +(cd ../sh2-server; GOOS=darwin GOARCH=amd64 go build -ldflags="-s -w" -o ../sh2/bin/scripthaus-local-server cmd/main-server.go) node_modules/.bin/electron-forge make ``` + +```bash +# @scripthaus command open-electron-package +# @scripthaus cd :playbook +open out/ScriptHaus-darwin-x64/ScriptHaus.app +``` diff --git a/src/emain.ts b/src/emain.ts index 100f60813..9cc08d691 100644 --- a/src/emain.ts +++ b/src/emain.ts @@ -10,10 +10,19 @@ import * as winston from "winston"; import * as util from "util"; import {sprintf} from "sprintf-js"; +const ScriptHausAppPathVarName = "SCRIPTHAUS_APP_PATH"; let isDev = (process.env.SH_DEV != null); let scHome = getScHomeDir(); ensureDir(scHome); +// these are either "darwin/amd64" or "darwin/arm64" +// normalize darwin/x64 to darwin/amd64 for GOARCH compatibility +let unamePlatform = process.platform; +let unameArch = process.arch; +if (unameArch == "x64") { + unameArch = "amd64" +} + let logger; let loggerConfig = { level: "info", @@ -33,14 +42,9 @@ function log(...msg) { logger.info(util.format(...msg)); } console.log = log; -console.log(sprintf("scripthaus-app starting, SCRIPTHAUS_HOME=%s, dirname=%s", scHome, __dirname)); - -// TODO fix these paths -const LocalServerPath = "/Users/mike/scripthaus/local-server"; -const LocalServerCmd = `${LocalServerPath} > ~/scripthaus/local-server.log 2>&1`; -// const LocalServerCwd = "/Users/mike/scripthaus/"; -const LocalServerCwd = "/Users/mike/work/gopath/src/github.com/scripthaus-dev/sh2-server"; +console.log(sprintf("scripthaus-app starting, SCRIPTHAUS_HOME=%s, apppath=%s arch=%s/%s", scHome, getAppBasePath(), unamePlatform, unameArch)); +const DevLocalServerPath = "/Users/mike/scripthaus/local-server"; let localServerProc = null; let localServerShouldRestart = false; @@ -57,6 +61,31 @@ function getScHomeDir() { return scHome; } +// for dev, this is just the github.com/scripthaus-dev/sh2 directory +// for prod, this is .../ScriptHaus.app/Contents/Resources/app +function getAppBasePath() { + return path.dirname(__dirname); +} + +function getLocalServerPath() { + if (isDev) { + return DevLocalServerPath + } + return path.join(getAppBasePath(), "bin", "scripthaus-local-server"); +} + +function getLocalServerCmd() { + let localServerPath = getLocalServerPath(); + let scHome = getScHomeDir(); + let logFile = path.join(scHome, "local-server.log"); + return `${localServerPath} > ${logFile} 2>&1`; +} + +function getLocalServerCwd() { + let scHome = getScHomeDir(); + return scHome; +} + function ensureDir(dir) { fs.mkdirSync(dir, {recursive: true, mode: 0o700}); } @@ -115,10 +144,10 @@ function createMainWindow(clientData) { width: bounds.width, height: bounds.height, webPreferences: { - preload: path.join(__dirname, "../dist/preload.js"), + preload: path.join(getAppBasePath(), "dist", "preload.js"), }, }); - win.loadFile(path.join(__dirname, "../static/index.html")); + win.loadFile(path.join(getAppBasePath(), "static", "index.html")); win.webContents.on("before-input-event", (e, input) => { if (input.type != "keyDown") { return; @@ -308,14 +337,24 @@ function sendLSSC() { } function runLocalServer() { - console.log("trying to run local server"); - let proc = child_process.spawn("/bin/bash", ["-c", LocalServerCmd], { - cwd: LocalServerCwd, + let pResolve = null; + let pReject = null; + let rtnPromise = new Promise((argResolve, argReject) => { + pResolve = argResolve; + pReject = argReject; + }); + let envCopy = Object.assign({}, process.env); + envCopy[ScriptHausAppPathVarName] = getAppBasePath(); + console.log("trying to run local server", getLocalServerPath()); + let proc = child_process.spawn("/bin/bash", ["-c", getLocalServerCmd()], { + cwd: getLocalServerCwd(), + env: envCopy, }); proc.on("exit", (e) => { console.log("local-server exit", e); localServerProc = null; sendLSSC(); + pReject(new Error(sprintf("failed to start local server (%s)", getLocalServerPath()))); if (localServerShouldRestart) { localServerShouldRestart = false; this.runLocalServer(); @@ -324,6 +363,7 @@ function runLocalServer() { proc.on("spawn", (e) => { console.log("spawnned local-server"); localServerProc = proc; + pResolve(true); setTimeout(() => { sendLSSC(); }, 100); @@ -337,6 +377,7 @@ function runLocalServer() { proc.stderr.on("data", output => { return; }); + return rtnPromise; } electron.ipcMain.on("context-screen", (event, {screenId}, {x, y}) => { @@ -346,18 +387,34 @@ electron.ipcMain.on("context-screen", (event, {screenId}, {x, y}) => { }); async function createMainWindowWrap() { - let clientData = await getClientData(); + let clientData = null; + try { + clientData = await getClientData(); + } + catch (e) { + console.log("error getting local-server clientdata", e.toString()); + } MainWindow = createMainWindow(clientData); if (clientData && clientData.winsize.fullscreen) { MainWindow.setFullScreen(true); } } +async function sleep(ms) { + return new Promise((resolve, reject) => setTimeout(resolve, ms)); +} + // ====== MAIN ====== // (async () => { - runLocalServer(); + try { + await runLocalServer(); + } + catch (e) { + console.log(e.toString()); + } + await sleep(500); // TODO remove this sleep, poll getClientData() in createMainWindow await app.whenReady(); await createMainWindowWrap(); app.on('activate', () => { diff --git a/static/index.html b/static/index.html index 1cc85bf74..e805125f4 100644 --- a/static/index.html +++ b/static/index.html @@ -2,7 +2,7 @@ - + diff --git a/static/remotes.html b/static/remotes.html deleted file mode 100644 index 5b850941b..000000000 --- a/static/remotes.html +++ /dev/null @@ -1 +0,0 @@ -

Remotes!

diff --git a/webpack.common.js b/webpack.common.js index cd1c55b6d..e104e0512 100644 --- a/webpack.common.js +++ b/webpack.common.js @@ -1,4 +1,5 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin'); +const LodashModuleReplacementPlugin = require('lodash-webpack-plugin'); const path = require("path"); module.exports = { @@ -8,7 +9,7 @@ module.exports = { }, output: { path: path.resolve(__dirname, "dist"), - filename: "[name]-dev.js" + filename: "[name].js", }, module: { rules: [ @@ -58,6 +59,7 @@ module.exports = { }, plugins: [ new MiniCssExtractPlugin({filename: "[name].css", ignoreOrder: true}), + new LodashModuleReplacementPlugin(), ], resolve: { extensions: ['.ts', '.tsx', '.js', '.mjs', '.cjs', '.wasm', '.json', '.less', '.css'] diff --git a/webpack.dev.js b/webpack.dev.js index a84e1a9f2..dab4aebfb 100644 --- a/webpack.dev.js +++ b/webpack.dev.js @@ -7,6 +7,10 @@ const VERSION = "v0.1.0"; var merged = merge.merge(common, { mode: "development", + output: { + path: path.resolve(__dirname, "dist-dev"), + filename: "[name].js", + }, devtool: "source-map", devServer: { static: { @@ -23,6 +27,7 @@ var merged = merge.merge(common, { }); var definePlugin = new webpack.DefinePlugin({ + __SHDEV__: "true", __SHVERSION__: JSON.stringify(VERSION), __SHBUILD__: JSON.stringify("devbuild"), }); diff --git a/webpack.electron.js b/webpack.electron.js index 145ff1ce0..856b5f650 100644 --- a/webpack.electron.js +++ b/webpack.electron.js @@ -8,8 +8,8 @@ module.exports = { }, target: "electron-main", output: { - path: path.resolve(__dirname, "dist"), - filename: "[name]-dev.js" + path: path.resolve(__dirname, "dist-dev"), + filename: "[name].js" }, externals: { "fs": "require('fs')", diff --git a/webpack.electron.prod.js b/webpack.electron.prod.js new file mode 100644 index 000000000..4b5be2bcc --- /dev/null +++ b/webpack.electron.prod.js @@ -0,0 +1,34 @@ +const webpack = require('webpack'); +const merge = require('webpack-merge'); +const common = require('./webpack.electron.js'); +const moment = require("dayjs"); +const VERSION = "v0.1.0"; +const path = require("path"); + +function makeBuildStr() { + let buildStr = moment().format("YYYYMMDD-HHmmss"); + console.log("ScriptHaus Electron " + VERSION + " build " + buildStr); + return buildStr; +} + +const BUILD = makeBuildStr(); + +let merged = merge.merge(common, { + mode: "production", + output: { + path: path.resolve(__dirname, "dist"), + filename: "[name].js" + }, + devtool: "source-map", + optimization: { + minimize: true, + }, +}); + +merged.plugins.push(new webpack.DefinePlugin({ + __SHDEV__: "false", + __SHVERSION__: JSON.stringify(VERSION), + __SHBUILD__: JSON.stringify(BUILD), +})); + +module.exports = merged; diff --git a/webpack.prod.js b/webpack.prod.js index 21f3cd311..62a4128ab 100644 --- a/webpack.prod.js +++ b/webpack.prod.js @@ -1,11 +1,9 @@ const webpack = require('webpack'); const merge = require('webpack-merge'); const common = require('./webpack.common.js'); -const MiniCssExtractPlugin = require('mini-css-extract-plugin'); -const LodashModuleReplacementPlugin = require('lodash-webpack-plugin'); const moment = require("dayjs"); -const fs = require("fs"); const VERSION = "v0.1.0"; +const path = require("path"); function makeBuildStr() { let buildStr = moment().format("YYYYMMDD-HHmmss"); @@ -23,8 +21,8 @@ if (process.env.WEBPACK_ANALYZE) { let merged = merge.merge(common, { mode: "production", output: { - path: __dirname, - filename: "build/hibiki/latest/[name]-prod.min.js" + path: path.resolve(__dirname, "dist"), + filename: "[name].js", }, devtool: "source-map", optimization: { @@ -32,12 +30,11 @@ let merged = merge.merge(common, { }, }); -merged.plugins.push(new LodashModuleReplacementPlugin()); -merged.plugins.push(new MiniCssExtractPlugin({filename: "dist/[name].css", ignoreOrder: true})); if (BundleAnalyzerPlugin != null) { merged.plugins.push(new BundleAnalyzerPlugin()); } merged.plugins.push(new webpack.DefinePlugin({ + __SHDEV__: "false", __SHVERSION__: JSON.stringify(VERSION), __SHBUILD__: JSON.stringify(BUILD), }));