Build without pkg unless packaging

This commit is contained in:
hensm
2020-08-12 04:26:13 +01:00
committed by Matt Hensman
parent 19aaa8f27d
commit 10c92186f9
5 changed files with 125 additions and 164 deletions

View File

@@ -85,7 +85,7 @@ npm run remove-manifest
This will build the ext and app, outputting to `dist/`: This will build the ext and app, outputting to `dist/`:
* #### `dist/app/` * #### `dist/app/`
... contains the bridge executable and manifest with the path pointing that executable. The `install-manifest` script copies this manifest to the proper location (or adds its current location to the registry on Windows). ... contains the built bridge with launcher and manifest with the path pointing that launcher. The `install-manifest` script copies this manifest to the proper location (or adds its current location to the registry on Windows).
* #### `dist/ext/` * #### `dist/ext/`
... contains the unpacked extension. ... contains the unpacked extension.
@@ -107,7 +107,7 @@ npm run start --prefix ./ext
Should package with web-ext. Should package with web-ext.
* `--watch` * `--watch`
Should run webpack in watch mode. Should run webpack in watch mode.
* `--packageType` `"<appID>"` * `--mirroringAppId` `"<appID>"`
Provide an alternative default mirroring receiver app ID. Provide an alternative default mirroring receiver app ID.
* `--mode` `"production"`, `"development"` * `--mode` `"production"`, `"development"`
Run webpack in a different mode. Defaults to `"development"` unless combined with `--package`. Run webpack in a different mode. Defaults to `"development"` unless combined with `--package`.
@@ -132,20 +132,12 @@ npm run package:ext # Packaging extension
npm run package:app # Packaging bridge application npm run package:app # Packaging bridge application
# Linux platforms # Linux platforms
npm run package:app -- -- --platform=linux --packageType=deb npm run package:app -- -- --packageType=deb
npm run package:app -- -- --platform=linux --packageType=rpm npm run package:app -- -- --packageType=rpm
# Windows
npm run package:app -- -- --platform=win32
# macOS
npm run package:app -- -- --platform=darwin
```` ````
#### Bridge package script arguments #### Bridge package script arguments
* `--platform` `"win32"`,`"darwin"`,`"linux"`
Select the platform to build for. Defaults to current platform.
* `--arch` `"x64"`,`"x86"` * `--arch` `"x64"`,`"x86"`
Select platform arch to build for. Defaults to current platform arch. Select platform arch to build for. Defaults to current platform arch.
* `--packageType` `"deb"`,`"rpm"` * `--packageType` `"deb"`,`"rpm"`

View File

@@ -3,6 +3,7 @@
const fs = require("fs-extra"); const fs = require("fs-extra");
const os = require("os"); const os = require("os");
const path = require("path"); const path = require("path");
const minimist = require("minimist"); const minimist = require("minimist");
const glob = require("glob"); const glob = require("glob");
const mustache = require("mustache"); const mustache = require("mustache");
@@ -11,8 +12,7 @@ const pkg = require("pkg");
const { spawnSync } = require("child_process"); const { spawnSync } = require("child_process");
const { __applicationName: applicationName const meta = require("../package.json");
, __applicationVersion: applicationVersion } = require("../package.json");
const { author const { author
, homepage } = require("../../package.json"); , homepage } = require("../../package.json");
@@ -33,10 +33,9 @@ const { executableName
// Command line args // Command line args
const argv = minimist(process.argv.slice(2), { const argv = minimist(process.argv.slice(2), {
boolean: [ "package", "skipNativeBuilds" ] boolean: [ "package", "skipNativeBuilds" ]
, string: [ "platform", "arch", "packageType" ] , string: [ "arch", "packageType" ]
, default: { , default: {
platform: os.platform() arch: os.arch()
, arch: os.arch()
, package: false , package: false
// Linux package type (deb/rpm) // Linux package type (deb/rpm)
, packageType: "deb" , packageType: "deb"
@@ -61,7 +60,7 @@ for (const target of supportedTargets) {
supportedArchs.push(arch); supportedArchs.push(arch);
} }
if (!supportedPlatforms.includes(pkgPlatform[argv.platform])) { if (!supportedPlatforms.includes(pkgPlatform[process.platform])) {
console.error("Unsupported target platform"); console.error("Unsupported target platform");
process.exit(1); process.exit(1);
} }
@@ -80,9 +79,6 @@ const spawnOptions = {
, stdio: [ process.stdin, process.stdout, process.stderr ] , stdio: [ process.stdin, process.stdout, process.stderr ]
}; };
const isBuildingForMac = argv.platform === "darwin";
const isBuildingForMacOnMac = isBuildingForMac && process.platform === "darwin";
/** /**
* Shouldn't exist, but cleanup and re-create any existing * Shouldn't exist, but cleanup and re-create any existing
* build directories, just in case. * build directories, just in case.
@@ -98,54 +94,17 @@ const MDNS_BINDING_PATH = path.join(
const MDNS_BINDING_NAME = "dns_sd_bindings.node"; const MDNS_BINDING_NAME = "dns_sd_bindings.node";
async function build () { async function build () {
/**
* Because the native receiver selector can only be built on
* systems with the capacity to link to the native AppKit
* libraries, and the pkg installer can only be built on
* platforms with the requisite pkgbuild/productbuild binaries,
* there's no point in trying to build from other platforms.
*/
if (isBuildingForMac && !isBuildingForMacOnMac) {
console.error("macOS version must be built on macOS");
process.exit(1);
}
// Run tsc // Run tsc
spawnSync(`tsc --project ${ROOT_PATH} \ spawnSync(`tsc --project ${ROOT_PATH} \
--outDir ${BUILD_PATH}` --outDir ${BUILD_PATH}`
, spawnOptions); , spawnOptions);
// Move tsc output to build dir
if (process.platform === "linux") {
// Quick workaround for issue on linux
spawnSync("mv", [ path.join(BUILD_PATH, "src/*"), BUILD_PATH ]
, spawnOptions);
} else {
const buildSrcDir = path.join(BUILD_PATH, "src");
for (const fileName of fs.readdirSync(buildSrcDir)) {
fs.moveSync(path.join(buildSrcDir, fileName)
, path.join(BUILD_PATH, fileName));
}
fs.removeSync(buildSrcDir);
}
// Copy other files
fs.copySync(SRC_PATH, BUILD_PATH, {
overwrite: true
, filter (src, dest) {
return !/.(js|ts)$/.test(src);
}
});
/** /**
* Native app manifest * Native app manifest
* https://mdn.io/Native_manifests#Native_messaging_manifests * https://mdn.io/Native_manifests#Native_messaging_manifests
*/ */
const manifest = { const manifest = {
"name": applicationName "name": meta.__applicationName
, "description": "" , "description": ""
, "type": "stdio" , "type": "stdio"
, "allowed_extensions": [ extensionId ] , "allowed_extensions": [ extensionId ]
@@ -156,12 +115,68 @@ async function build () {
* add the path to the built executable in the dist folder. * add the path to the built executable in the dist folder.
*/ */
if (argv.package) { if (argv.package) {
// If packaging for windows, use win32 path helpers. // Need a minimal package.json for pkg.
manifest.path = (argv.platform === "win32" ? path.win32 : path) const pkgManifest = {
.join(executablePath[argv.platform] bin: "main.js"
, executableName[argv.platform]); , pkg: {
/**
* Workaround for pkg asset detection
* https://github.com/thibauts/node-castv2/issues/46
*/
"assets": "../../node_modules/castv2/lib/cast_channel.proto"
}
};
// Write pkg manifest
fs.writeFileSync(path.join(BUILD_PATH, "src/package.json")
, JSON.stringify(pkgManifest))
// Run pkg to create a single executable
await pkg.exec([
path.join(BUILD_PATH, "src")
, "--target", `node12-${pkgPlatform[process.platform]}-${argv.arch}`
, "--output", path.join(BUILD_PATH, executableName[process.platform])
]);
fs.copySync(path.join(MDNS_BINDING_PATH, MDNS_BINDING_NAME)
, path.join(BUILD_PATH, MDNS_BINDING_NAME));
fs.removeSync(path.join(BUILD_PATH, "src"));
manifest.path = path.join(executablePath[process.platform]
, executableName[process.platform]);
} else { } else {
manifest.path = path.join(DIST_PATH, executableName[argv.platform]); let launcherPath = path.join(BUILD_PATH
, meta.__applicationExecutableName);
const modulesDir = path.join(ROOT_PATH, "node_modules");
switch (process.platform) {
case "win32": {
launcherPath += ".bat";
fs.writeFileSync(launcherPath,
`@echo off
setlocal
set NODE_PATH=${modulesDir}
node .\\src\\main.js %*
endlocal
`);
break;
}
case "linux":
case "darwin": {
launcherPath += ".sh";
fs.writeFileSync(launcherPath,
`#!/usr/bin/env sh
NODE_PATH="${modulesDir}" node ./src/main.js "$@"
`);
break;
}
}
manifest.path = path.join(DIST_PATH, path.basename(launcherPath));
} }
@@ -176,34 +191,8 @@ async function build () {
} }
// Need a minimal package.json for pkg.
const pkgManifest = {
bin: "main.js"
, pkg: {
/**
* Workaround for pkg asset detection
* https://github.com/thibauts/node-castv2/issues/46
*/
"assets": "../node_modules/castv2/lib/cast_channel.proto"
}
};
// Write pkg manifest
fs.writeFileSync(path.join(BUILD_PATH, "package.json")
, JSON.stringify(pkgManifest))
// Run pkg to create a single executable
await pkg.exec([
BUILD_PATH
, "--target", `node12-${pkgPlatform[argv.platform]}-${argv.arch}`
, "--output", path.join(BUILD_PATH, executableName[argv.platform])
]);
fs.copySync(path.join(MDNS_BINDING_PATH, MDNS_BINDING_NAME)
, path.join(BUILD_PATH, MDNS_BINDING_NAME));
// Build NativeMacReceiverSelector // Build NativeMacReceiverSelector
if (isBuildingForMacOnMac && !argv.skipNativeBuilds) { if (process.platform === "darwin" && !argv.skipNativeBuilds) {
const selectorPath = path.join(__dirname, "../selector/mac/"); const selectorPath = path.join(__dirname, "../selector/mac/");
const derivedDataPath = path.join(__dirname, "../selector/mac/build/"); const derivedDataPath = path.join(__dirname, "../selector/mac/build/");
@@ -218,7 +207,8 @@ async function build () {
const selectorBundlePath = path.join(derivedDataPath const selectorBundlePath = path.join(derivedDataPath
, "Build/Products/Release/", selectorExecutableName); , "Build/Products/Release/", selectorExecutableName);
fs.moveSync(selectorBundlePath, path.join(BUILD_PATH, selectorExecutableName)); fs.moveSync(selectorBundlePath
, path.join(BUILD_PATH, selectorExecutableName));
fs.removeSync(derivedDataPath); fs.removeSync(derivedDataPath);
} }
@@ -229,7 +219,7 @@ async function build () {
* to dist. * to dist.
*/ */
if (argv.package) { if (argv.package) {
const installerName = await packageApp(argv.platform, argv.arch); const installerName = await packageApp(process.platform, argv.arch);
if (installerName) { if (installerName) {
// Move installer to dist // Move installer to dist
fs.moveSync( fs.moveSync(
@@ -238,37 +228,25 @@ async function build () {
, { overwrite: true }); , { overwrite: true });
} }
} else { } else {
// Move executable and app manifest to dist // Move tsc output and launcher to dist
fs.moveSync( fs.moveSync(BUILD_PATH, DIST_PATH, { overwrite: true });
path.join(BUILD_PATH, manifestName) /*
, path.join(DIST_PATH, manifestName) spawnSync("npm install --production", {
, { overwrite: true }); ...spawnOptions
fs.moveSync( , cwd: DIST_PATH
path.join(BUILD_PATH, executableName[argv.platform]) });
, path.join(DIST_PATH, executableName[argv.platform]) */
, { overwrite: true });
fs.moveSync(
path.join(BUILD_PATH, MDNS_BINDING_NAME)
, path.join(DIST_PATH, MDNS_BINDING_NAME)
, { overwrite: true });
if (isBuildingForMacOnMac && !argv.skipNativeBuilds) {
fs.moveSync(
path.join(BUILD_PATH, selectorExecutableName)
, path.join(DIST_PATH, selectorExecutableName)
, { overwrite: true });
}
} }
// Remove build directory // Remove build directory
fs.removeSync(BUILD_PATH); //fs.removeSync(BUILD_PATH);
} }
/** /**
* Takes a platform and returns the path of the created * Takes a platform and returns the path of the created
* installer package. * installer package.
*/ */
function packageApp (platform, arch) { async function packageApp (platform, arch) {
const packageFunctionArgs = [ const packageFunctionArgs = [
arch arch
, executableName[platform] // platformExecutableName , executableName[platform] // platformExecutableName
@@ -323,8 +301,9 @@ function packageDarwin (
, platformExecutablePath , platformExecutablePath
, platformManifestPath) { , platformManifestPath) {
const outputName = `${applicationName}-${applicationVersion}-${arch}.pkg`; const outputName = `${meta.__applicationName}-${
const componentName = `${applicationName}_component.pkg`; meta.__applicationVersion}-${arch}.pkg`;
const componentName = `${meta.__applicationName}_component.pkg`;
const packagingDir = path.join(__dirname, "../packaging/mac/"); const packagingDir = path.join(__dirname, "../packaging/mac/");
const packagingOutputDir = path.join(BUILD_PATH, "packaging"); const packagingOutputDir = path.join(BUILD_PATH, "packaging");
@@ -346,7 +325,7 @@ function packageDarwin (
fs.moveSync(path.join(BUILD_PATH, manifestName) fs.moveSync(path.join(BUILD_PATH, manifestName)
, path.join(rootManifestPath, manifestName)); , path.join(rootManifestPath, manifestName));
if (isBuildingForMacOnMac && !argv.skipNativeBuilds) { if (process.platform === "darwin" && !argv.skipNativeBuilds) {
// Move selector executable alongside main executable // Move selector executable alongside main executable
fs.moveSync(path.join(BUILD_PATH, selectorExecutableName) fs.moveSync(path.join(BUILD_PATH, selectorExecutableName)
, path.join(rootExecutablePath, selectorExecutableName)); , path.join(rootExecutablePath, selectorExecutableName));
@@ -357,10 +336,10 @@ function packageDarwin (
fs.copySync(packagingDir, packagingOutputDir); fs.copySync(packagingDir, packagingOutputDir);
const view = { const view = {
applicationName applicationName: meta.__applicationName
, manifestName , manifestName
, componentName , componentName
, packageId: `tf.matt.${applicationName}` , packageId: `tf.matt.${meta.__applicationName}`
, executablePath: platformExecutablePath , executablePath: platformExecutablePath
, manifestPath: platformManifestPath , manifestPath: platformManifestPath
}; };
@@ -381,8 +360,8 @@ function packageDarwin (
// Build component package // Build component package
spawnSync(` spawnSync(`
pkgbuild --root ${rootPath} \ pkgbuild --root ${rootPath} \
--identifier "tf.matt.${applicationName}" \ --identifier "tf.matt.${meta.__applicationName}" \
--version "${applicationVersion}" \ --version "${meta.__applicationVersion}" \
--scripts ${path.join(packagingOutputDir, "scripts")} \ --scripts ${path.join(packagingOutputDir, "scripts")} \
${path.join(BUILD_PATH, componentName)}` ${path.join(BUILD_PATH, componentName)}`
, spawnOptions); , spawnOptions);
@@ -415,7 +394,8 @@ function packageLinuxDeb (
, platformExecutablePath , platformExecutablePath
, platformManifestPath) { , platformManifestPath) {
const outputName = `${applicationName}-${applicationVersion}-${arch}.deb`; const outputName = `${meta.__applicationName}-${
meta.__applicationVersion}-${arch}.deb`;
// Create root // Create root
const rootPath = path.join(BUILD_PATH, "root"); const rootPath = path.join(BUILD_PATH, "root");
@@ -445,9 +425,9 @@ function packageLinuxDeb (
const view = { const view = {
// Debian package names can't contain underscores // Debian package names can't contain underscores
packageName: applicationName.replace(/_/g, "-") packageName: meta.__applicationName.replace(/_/g, "-")
, applicationName , applicationName: meta.__applicationName
, applicationVersion , applicationVersion: meta.__applicationVersion
, author , author
}; };
@@ -479,7 +459,8 @@ function packageLinuxRpm (
, platformExecutablePath , platformExecutablePath
, platformManifestPath) { , platformManifestPath) {
const outputName = `${applicationName}-${applicationVersion}-${arch}.rpm`; const outputName = `${meta.__applicationName}-${
meta.__applicationVersion}-${arch}.rpm`;
const specPath = path.join(__dirname const specPath = path.join(__dirname
, "../packaging/linux/rpm/package.spec"); , "../packaging/linux/rpm/package.spec");
@@ -487,9 +468,9 @@ function packageLinuxRpm (
const specOutputPath = path.join(BUILD_PATH, path.basename(specPath)); const specOutputPath = path.join(BUILD_PATH, path.basename(specPath));
const view = { const view = {
packageName: applicationName packageName: meta.__applicationName
, applicationName , applicationName: meta.__applicationName
, applicationVersion , applicationVersion: meta.__applicationVersion
, executablePath: platformExecutablePath , executablePath: platformExecutablePath
, manifestPath: platformManifestPath , manifestPath: platformManifestPath
, executableName: platformExecutableName , executableName: platformExecutableName
@@ -532,14 +513,15 @@ function packageWin32 (
, platformExecutablePath , platformExecutablePath
, platformManifestPath) { , platformManifestPath) {
const outputName = `${applicationName}-${applicationVersion}-${arch}.exe`; const outputName = `${meta.__applicationName}-${
meta.__applicationVersion}-${arch}.exe`;
const scriptPath = path.join(__dirname, "../packaging/win/installer.nsi"); const scriptPath = path.join(__dirname, "../packaging/win/installer.nsi");
const scriptOutputPath = path.join(BUILD_PATH, path.basename(scriptPath)); const scriptOutputPath = path.join(BUILD_PATH, path.basename(scriptPath));
const view = { const view = {
applicationName applicationName: meta.__applicationName
, applicationVersion , applicationVersion: meta.__applicationVersion
, executableName: platformExecutableName , executableName: platformExecutableName
, executablePath: platformExecutablePath , executablePath: platformExecutablePath
, manifestName , manifestName

11
app/package-lock.json generated
View File

@@ -187,12 +187,6 @@
"integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==",
"dev": true "dev": true
}, },
"@types/dedent": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/@types/dedent/-/dedent-0.7.0.tgz",
"integrity": "sha512-EGlKlgMhnLt/cM4DbUSafFdrkeJoC9Mvnj0PUCU7tFmTjMjNRT957kXCx0wYm3JuEq4o4ZsS5vG+NlkM2DMd2A==",
"dev": true
},
"@types/long": { "@types/long": {
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz",
@@ -470,11 +464,6 @@
"assert-plus": "^1.0.0" "assert-plus": "^1.0.0"
} }
}, },
"dedent": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz",
"integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw="
},
"deep-is": { "deep-is": {
"version": "0.1.3", "version": "0.1.3",
"resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",

View File

@@ -14,7 +14,6 @@
"bplist-creator": "0.0.8", "bplist-creator": "0.0.8",
"bplist-parser": "^0.2.0", "bplist-parser": "^0.2.0",
"castv2": "^0.1.10", "castv2": "^0.1.10",
"dedent": "^0.7.0",
"fast-srp-hap": "^2.0.2", "fast-srp-hap": "^2.0.2",
"mdns": "^2.5.1", "mdns": "^2.5.1",
"mime-types": "^2.1.27", "mime-types": "^2.1.27",
@@ -22,7 +21,6 @@
"tweetnacl": "^1.0.3" "tweetnacl": "^1.0.3"
}, },
"devDependencies": { "devDependencies": {
"@types/dedent": "^0.7.0",
"@types/mdns": "0.0.33", "@types/mdns": "0.0.33",
"@types/mime-types": "^2.1.0", "@types/mime-types": "^2.1.0",
"@types/node": "^13.13.5", "@types/node": "^13.13.5",

View File

@@ -1,12 +1,8 @@
"use strict"; "use strict";
import meta from "../package.json"; import path from "path";
import dedent from "dedent";
import minimist from "minimist"; import minimist from "minimist";
import * as daemon from "./daemon";
const argv = minimist(process.argv.slice(2), { const argv = minimist(process.argv.slice(2), {
boolean: [ "daemon", "help", "version" ] boolean: [ "daemon", "help", "version" ]
@@ -25,21 +21,22 @@ const argv = minimist(process.argv.slice(2), {
if (argv.version) { if (argv.version) {
console.log(meta.__applicationVersion); // TODO: Replace this automatically
console.log(`v0.0.7`);
} else if (argv.help) { } else if (argv.help) {
console.log(dedent` console.log(
Usage: ${meta.__applicationExecutableName} [options] `Usage: ${path.basename(process.argv[0])} [options]
Options: Options:
-h, --help Print usage info -h, --help Print usage info
-v, --version Print version info -v, --version Print version info
-d, --daemon Launch in daemon mode. This starts a WebSocket server that -d, --daemon Launch in daemon mode. This starts a WebSocket server that
the extension can be configured to connect to under bridge the extension can be configured to connect to under bridge
options. options.
-p, --port Set port number for WebSocket server. This must match the -p, --port Set port number for WebSocket server. This must match the
port set in the extension options. port set in the extension options.
`);
`);
} else if (argv.daemon) { } else if (argv.daemon) {
const port = parseInt(argv.port); const port = parseInt(argv.port);
if (!port || port < 1025 || port > 65535) { if (!port || port < 1025 || port > 65535) {
@@ -47,7 +44,10 @@ if (argv.version) {
process.exit(1); process.exit(1);
} }
daemon.init(port); import("./daemon")
.then(daemon => {
daemon.init(port);
});
} else { } else {
import("./bridge"); import("./bridge");
} }