pear-build
Advanced tools
+13
-42
| #!/usr/bin/env node | ||
| const { command, flag, summary } = require('paparam') | ||
| const { command, argv } = require('paparam') | ||
| const pkg = require('./package') | ||
| const build = require('.') | ||
| const cmd = command( | ||
| pkg.name, | ||
| summary(pkg.description), | ||
| flag('--version|-v', 'Print the current version'), | ||
| flag('--package [path]', 'Path to project package.json'), | ||
| flag('--target [path]', 'Target build dir'), | ||
| flag('--darwin-arm64-app [path]', 'Path to Mac ARM64 app'), | ||
| flag('--darwin-x64-app [path]', 'Path to Mac x64 app'), | ||
| flag('--linux-arm64-app [path]', 'Path to Linux ARM64 app'), | ||
| flag('--linux-x64-app [path]', 'Path to Linux x64 app'), | ||
| flag('--win32-x64-app [path]', 'Path to Windows x64 app'), | ||
| flag('--ios-arm64 [path]', 'Path to iOS ARM64 folder (ota bundle and assets)'), | ||
| flag( | ||
| '--ios-arm64-simulator [path]', | ||
| 'Path to iOS ARM64-Simulator folder (ota bundle and assets)' | ||
| ), | ||
| flag('--ios-x64-simulator [path]', 'Path to iOS x64-Simulator folder (ota bundle and assets)'), | ||
| flag('--android-arm64 [path]', 'Path to android ARM64 folder (ota bundle and assets)'), | ||
| async function (cmd) { | ||
| if (cmd.flags.version) return console.log(`v${pkg.version}`) | ||
| const dir = cmd.flags.package | ||
| const opts = { | ||
| target: cmd.flags.target, | ||
| darwinArm64App: cmd.flags.darwinArm64App, | ||
| darwinX64App: cmd.flags.darwinX64App, | ||
| linuxArm64App: cmd.flags.linuxArm64App, | ||
| linuxX64App: cmd.flags.linuxX64App, | ||
| win32X64App: cmd.flags.win32X64App, | ||
| iosArm64: cmd.flags.iosArm64, | ||
| iosArm64Simulator: cmd.flags.iosArm64Simulator, | ||
| iosX64Simulator: cmd.flags.iosX64Simulator, | ||
| androidArm64: cmd.flags.androidArm64 | ||
| } | ||
| try { | ||
| await build(dir, opts) | ||
| } catch (err) { | ||
| if (err) console.error(err) | ||
| if (typeof process !== 'undefined') process.exitCode = 1 | ||
| } | ||
| const cmd = command(pkg.name, pkg.command, async function (cmd) { | ||
| if (cmd.flags.version) return console.log(`v${pkg.version}`) | ||
| try { | ||
| const runner = build(cmd.flags) | ||
| runner.on('mirrored', (data) => console.log(data.from, data.message, data.to)) | ||
| runner.on('error', (err) => console.error(err)) | ||
| await runner.done() | ||
| } catch (err) { | ||
| if (typeof Bare !== 'undefined') Bare.exitCode = 1 | ||
| else if (typeof process !== 'undefined') process.exitCode = 1 | ||
| } | ||
| ) | ||
| }) | ||
| cmd.parse() | ||
| cmd.parse(argv().length === 0 ? ['--help'] : argv()) |
+81
-58
@@ -0,74 +1,97 @@ | ||
| 'use strict' | ||
| const path = require('path') | ||
| const fs = require('fs') | ||
| const { EventEmitter } = require('events') | ||
| const Localdrive = require('localdrive') | ||
| module.exports = async function build(dir, opts = {}) { | ||
| const pkgPath = path.resolve(dir) | ||
| const pkg = require(pkgPath) | ||
| const { target = path.resolve(pkg.name + '-' + pkg.version) } = opts | ||
| const darwinArm64App = opts.darwinArm64App | ||
| ? ['darwin-arm64', path.resolve(opts.darwinArm64App)] | ||
| : null | ||
| const darwinX64App = opts.darwinX64App ? ['darwin-x64', path.resolve(opts.darwinX64App)] : null | ||
| const linuxArm64App = opts.linuxArm64App | ||
| ? ['linux-arm64', path.resolve(opts.linuxArm64App)] | ||
| : null | ||
| const linuxX64App = opts.linuxX64App ? ['linux-x64', path.resolve(opts.linuxX64App)] : null | ||
| const win32X64App = opts.win32X64App ? ['win32-x64', path.resolve(opts.win32X64App)] : null | ||
| const iosArm64 = opts.iosArm64 ? ['ios-arm64', path.resolve(opts.iosArm64)] : null | ||
| const iosArm64Sim = opts.iosArm64Simulator | ||
| ? ['ios-arm64-simulator', path.resolve(opts.iosArm64Simulator)] | ||
| : null | ||
| const iosx64Sim = opts.iosX64Simulator | ||
| ? ['ios-x64-simulator', path.resolve(opts.iosX64Simulator)] | ||
| : null | ||
| const androidArm64 = opts.androidArm64 ? ['android-arm64', path.resolve(opts.androidArm64)] : null | ||
| class Build extends EventEmitter { | ||
| constructor(opts) { | ||
| super() | ||
| this._running = this.run(opts) | ||
| this._running.catch((err) => this.emit('error', err)) | ||
| } | ||
| const byArch = path.join(target, 'by-arch') | ||
| async run(opts) { | ||
| const pkgPath = path.resolve(opts.package) | ||
| const pkg = require(pkgPath) | ||
| const { target = path.resolve(pkg.name + '-' + pkg.version) } = opts | ||
| const darwinArm64App = opts.darwinArm64App | ||
| ? ['darwin-arm64', path.resolve(opts.darwinArm64App)] | ||
| : null | ||
| const darwinX64App = opts.darwinX64App ? ['darwin-x64', path.resolve(opts.darwinX64App)] : null | ||
| const linuxArm64App = opts.linuxArm64App | ||
| ? ['linux-arm64', path.resolve(opts.linuxArm64App)] | ||
| : null | ||
| const linuxX64App = opts.linuxX64App ? ['linux-x64', path.resolve(opts.linuxX64App)] : null | ||
| const win32X64App = opts.win32X64App ? ['win32-x64', path.resolve(opts.win32X64App)] : null | ||
| const iosArm64 = opts.iosArm64 ? ['ios-arm64', path.resolve(opts.iosArm64)] : null | ||
| const iosArm64Sim = opts.iosArm64Simulator | ||
| ? ['ios-arm64-simulator', path.resolve(opts.iosArm64Simulator)] | ||
| : null | ||
| const iosx64Sim = opts.iosX64Simulator | ||
| ? ['ios-x64-simulator', path.resolve(opts.iosX64Simulator)] | ||
| : null | ||
| const androidArm64 = opts.androidArm64 | ||
| ? ['android-arm64', path.resolve(opts.androidArm64)] | ||
| : null | ||
| await fs.promises.mkdir(byArch, { recursive: true }) | ||
| const byArch = path.join(target, 'by-arch') | ||
| await fs.promises.writeFile( | ||
| path.join(target, 'package.json'), | ||
| await fs.promises.readFile(pkgPath) | ||
| ) | ||
| await fs.promises.mkdir(byArch, { recursive: true }) | ||
| const apps = [ | ||
| darwinArm64App, | ||
| darwinX64App, | ||
| linuxArm64App, | ||
| linuxX64App, | ||
| win32X64App, | ||
| iosArm64, | ||
| iosArm64Sim, | ||
| iosx64Sim, | ||
| androidArm64 | ||
| ].filter(Boolean) | ||
| await fs.promises.writeFile( | ||
| path.join(target, 'package.json'), | ||
| await fs.promises.readFile(pkgPath) | ||
| ) | ||
| const appName = pkg.productName ?? pkg.name | ||
| const apps = [ | ||
| darwinArm64App, | ||
| darwinX64App, | ||
| linuxArm64App, | ||
| linuxX64App, | ||
| win32X64App, | ||
| iosArm64, | ||
| iosArm64Sim, | ||
| iosx64Sim, | ||
| androidArm64 | ||
| ].filter(Boolean) | ||
| const noop = () => {} | ||
| const promises = [] | ||
| for (const [arch, app] of apps) { | ||
| if (path.basename(app, path.extname(app)) !== appName) { | ||
| throw new Error(`expected directory ${appName} but got ${path.basename(app)} for ${arch}`) | ||
| const appName = pkg.productName ?? pkg.name | ||
| const noop = () => {} | ||
| const promises = [] | ||
| for (const [arch, app] of apps) { | ||
| if (path.basename(app, path.extname(app)) !== appName) { | ||
| throw new Error(`expected directory ${appName} but got ${path.basename(app)} for ${arch}`) | ||
| } | ||
| const archApp = path.join(byArch, arch, 'app') | ||
| await fs.promises.mkdir(archApp, { recursive: true }) | ||
| const src = new Localdrive(path.dirname(app)) | ||
| const dst = new Localdrive(archApp) | ||
| const mirror = src.mirror(dst, { prefix: '/' + path.basename(app) }) | ||
| await src.ready() | ||
| await dst.ready() | ||
| this.emit('mirroring', { message: 'mirroring to', from: app, to: archApp }) | ||
| const promise = mirror.done() | ||
| promises.push(promise) | ||
| promise.then( | ||
| () => this.emit('mirrored', { message: 'mirrored to', from: app, to: archApp }), | ||
| noop | ||
| ) | ||
| await src.close() | ||
| await dst.close() | ||
| } | ||
| const archApp = path.join(byArch, arch, 'app') | ||
| await fs.promises.mkdir(archApp, { recursive: true }) | ||
| const src = new Localdrive(path.dirname(app)) | ||
| const dst = new Localdrive(archApp) | ||
| const mirror = src.mirror(dst, { prefix: '/' + path.basename(app) }) | ||
| await Promise.all(promises) | ||
| } | ||
| await src.ready() | ||
| await dst.ready() | ||
| console.log(app, 'mirroring to', archApp) | ||
| const promise = mirror.done() | ||
| promises.push(promise) | ||
| promise.then(() => console.log(app, 'mirrored to', archApp), noop) | ||
| await src.close() | ||
| await dst.close() | ||
| async done() { | ||
| return await this._running | ||
| } | ||
| } | ||
| await Promise.all(promises) | ||
| module.exports = function build(opts) { | ||
| return new Build(opts) | ||
| } |
+32
-7
| { | ||
| "name": "pear-build", | ||
| "version": "0.2.0", | ||
| "version": "1.0.0", | ||
| "main": "index.js", | ||
| "type": "commonjs", | ||
| "bin": "bin.js", | ||
| "description": "Build appling for a Pear application", | ||
| "description": "Create project deployment folder", | ||
| "author": "Holepunch Inc", | ||
@@ -14,6 +14,21 @@ "license": "Apache-2.0", | ||
| ], | ||
| "command": { | ||
| "summary": "Create project deployment folder", | ||
| "flag --package [path]": "Path to project package.json", | ||
| "flag --target [path]": "Target build dir", | ||
| "flag --darwin-arm64-app [path]": "Path to Mac ARM64 app", | ||
| "flag --darwin-x64-app [path]": "Path to Mac x64 app", | ||
| "flag --linux-arm64-app [path]": "Path to Linux ARM64 app", | ||
| "flag --linux-x64-app [path]": "Path to Linux x64 app", | ||
| "flag --win32-x64-app [path]": "Path to Windows x64 app", | ||
| "flag --ios-arm64 [path]": "Path to iOS ARM64 folder (ota bundle and assets)", | ||
| "flag --ios-arm64-simulator [path]": "Path to iOS ARM64-Simulator folder (ota bundle and asset)", | ||
| "flag --ios-x64-simulator [path]": "Path to iOS x64-Simulator folder (ota bundle and assets)", | ||
| "flag --android-arm64 [path]": "Path to Android ARM64 folder (ota bundle and assets)", | ||
| "flag --json": "Newline delimited JSON output" | ||
| }, | ||
| "imports": { | ||
| "path": { | ||
| "bare": "bare-path", | ||
| "default": "path" | ||
| "events": { | ||
| "bare": "bare-events", | ||
| "default": "events" | ||
| }, | ||
@@ -23,2 +38,6 @@ "fs": { | ||
| "default": "fs" | ||
| }, | ||
| "path": { | ||
| "bare": "bare-path", | ||
| "default": "path" | ||
| } | ||
@@ -29,5 +48,8 @@ }, | ||
| "lint": "prettier --check . && lunte", | ||
| "test": "brittle-node test/all.js" | ||
| "test": "npm run test:node && npm run test:bare", | ||
| "test:bare": "brittle-bare --coverage test/all.js", | ||
| "test:node": "brittle-node --coverage test/all.js" | ||
| }, | ||
| "dependencies": { | ||
| "bare-events": "^2.8.2", | ||
| "bare-fs": "^4.5.3", | ||
@@ -39,7 +61,10 @@ "bare-path": "^3.0.0", | ||
| "devDependencies": { | ||
| "bare-fs": "^4.5.3", | ||
| "brittle": "^3.19.1", | ||
| "lunte": "^1.6.0", | ||
| "mirror-drive": "^1.13.0", | ||
| "prettier": "^3.7.4", | ||
| "prettier-config-holepunch": "^2.0.0" | ||
| "prettier-config-holepunch": "^2.0.0", | ||
| "test-tmp": "^1.4.0" | ||
| } | ||
| } |
+61
-1
@@ -14,7 +14,67 @@ # pear-build | ||
| ```bash | ||
| pear-build --package=./my-app/package.json --darwin-arm64-app ./my-app/dist/macos/Keet.app --linux-x64-app=./my-linux-build/Keet.AppImage --target=./my-build | ||
| pear-build \ | ||
| --package=./my-app/package.json \ | ||
| --darwin-arm64-app ./my-app/MyApp-darwin-arm64/MyApp.app \ | ||
| --linux-x64-app=./my-app/MyApp-linux-x64/MyApp.AppImage \ | ||
| --target=./my-build | ||
| ``` | ||
| ## Example | ||
| ```bash | ||
| node bin.js \ | ||
| --package ./test/fixtures/hello-pear-electron/package.json \ | ||
| --darwin-arm64-app ./test/fixtures/hello-pear-electron/out/HelloPear-darwin-arm64/HelloPear.app \ | ||
| --darwin-x64-app ./test/fixtures/hello-pear-electron/out/HelloPear-darwin-x64/HelloPear.app \ | ||
| --linux-arm64-app ./test/fixtures/hello-pear-electron/out/HelloPear-linux-arm64/HelloPear.AppImage \ | ||
| --linux-x64-app ./test/fixtures/hello-pear-electron/out/HelloPear-linux-x64/HelloPear.AppImage \ | ||
| --win32-x64-app ./test/fixtures/hello-pear-electron/out/HelloPear-win32-x64/HelloPear.msix \ | ||
| --ios-arm64 ./test/fixtures/hello-pear-react-native/ota/ios/HelloPear \ | ||
| --ios-arm64-simulator ./test/fixtures/hello-pear-react-native/ota/ios/HelloPear \ | ||
| --ios-x64-simulator ./test/fixtures/hello-pear-react-native/ota/ios/HelloPear \ | ||
| --android-arm64 ./test/fixtures/hello-pear-react-native/ota/android/HelloPear \ | ||
| --target ./my-build | ||
| ``` | ||
| `$ tree my-build/` | ||
| ```bash | ||
| my-build | ||
| ├── by-arch | ||
| │ ├── android-arm64 | ||
| │ │ └── app | ||
| │ │ └── HelloPear | ||
| │ │ └── app.bundle | ||
| │ ├── darwin-arm64 | ||
| │ │ └── app | ||
| │ │ └── HelloPear.app | ||
| │ ├── darwin-x64 | ||
| │ │ └── app | ||
| │ │ └── HelloPear.app | ||
| │ ├── ios-arm64 | ||
| │ │ └── app | ||
| │ │ └── HelloPear | ||
| │ │ └── app.bundle | ||
| │ ├── ios-arm64-simulator | ||
| │ │ └── app | ||
| │ │ └── HelloPear | ||
| │ │ └── app.bundle | ||
| │ ├── ios-x64-simulator | ||
| │ │ └── app | ||
| │ │ └── HelloPear | ||
| │ │ └── app.bundle | ||
| │ ├── linux-arm64 | ||
| │ │ └── app | ||
| │ │ └── HelloPear.AppImage | ||
| │ ├── linux-x64 | ||
| │ │ └── app | ||
| │ │ └── HelloPear.AppImage | ||
| │ └── win32-x64 | ||
| │ └── app | ||
| │ └── HelloPear.msix | ||
| └── package.json | ||
| ``` | ||
| ## License | ||
| Apache-2.0 |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
19672
16.69%1
-50%80
300%5
25%7
75%101
-8.18%+ Added