diff --git a/node_modules/@oclif/dev-cli/lib/commands/pack/macos.js b/node_modules/@oclif/dev-cli/lib/commands/pack/macos.js index cd771cd..4a66939 100644 --- a/node_modules/@oclif/dev-cli/lib/commands/pack/macos.js +++ b/node_modules/@oclif/dev-cli/lib/commands/pack/macos.js @@ -37,6 +37,7 @@ class PackMacos extends command_1.Command { if (process.env.OSX_KEYCHAIN) args.push('--keychain', process.env.OSX_KEYCHAIN); args.push(dist); + console.log(`pkgbuild "${args.join('" "')}"`); await qq.x('pkgbuild', args); } } diff --git a/node_modules/@oclif/dev-cli/lib/commands/pack/win.js b/node_modules/@oclif/dev-cli/lib/commands/pack/win.js index a9d4276..75c2f8b 100644 --- a/node_modules/@oclif/dev-cli/lib/commands/pack/win.js +++ b/node_modules/@oclif/dev-cli/lib/commands/pack/win.js @@ -3,11 +3,14 @@ Object.defineProperty(exports, "__esModule", { value: true }); const command_1 = require("@oclif/command"); const qq = require("qqjs"); const Tarballs = require("../../tarballs"); +const { fixPath } = require("../../util"); + class PackWin extends command_1.Command { async run() { await this.checkForNSIS(); const { flags } = this.parse(PackWin); - const buildConfig = await Tarballs.buildConfig(flags.root); + const targets = flags.targets !== undefined ? flags.targets.split(',') : undefined; + const buildConfig = await Tarballs.buildConfig(flags.root, {targets}); const { config } = buildConfig; await Tarballs.build(buildConfig, { platform: 'win32', pack: false }); const arches = buildConfig.targets.filter(t => t.platform === 'win32').map(t => t.arch); @@ -17,7 +20,7 @@ class PackWin extends command_1.Command { await qq.write([installerBase, `bin/${config.bin}`], scripts.sh(config)); await qq.write([installerBase, `${config.bin}.nsi`], scripts.nsis(config, arch)); await qq.mv(buildConfig.workspace({ platform: 'win32', arch }), [installerBase, 'client']); - await qq.x(`makensis ${installerBase}/${config.bin}.nsi | grep -v "\\[compress\\]" | grep -v "^File: Descending to"`); + await qq.x(`makensis ${fixPath(installerBase)}/${config.bin}.nsi | grep -v "\\[compress\\]" | grep -v "^File: Descending to"`) const o = buildConfig.dist(`win/${config.bin}-v${buildConfig.version}-${arch}.exe`); await qq.mv([installerBase, 'installer.exe'], o); this.log(`built ${o}`); @@ -40,6 +43,7 @@ class PackWin extends command_1.Command { PackWin.description = 'create windows installer from oclif CLI'; PackWin.flags = { root: command_1.flags.string({ char: 'r', description: 'path to oclif CLI root', default: '.', required: true }), + targets: command_1.flags.string({char: 't', description: 'comma-separated targets to pack (e.g.: win32-x86,win32-x64)'}), }; exports.default = PackWin; const scripts = { diff --git a/node_modules/@oclif/dev-cli/lib/tarballs/build.js b/node_modules/@oclif/dev-cli/lib/tarballs/build.js index 3e613e0..129d041 100644 --- a/node_modules/@oclif/dev-cli/lib/tarballs/build.js +++ b/node_modules/@oclif/dev-cli/lib/tarballs/build.js @@ -17,8 +17,11 @@ const pack = async (from, to) => { qq.cd(prevCwd); }; async function build(c, options = {}) { - const { xz, config } = c; + const { xz, config, tmp } = c; const prevCwd = qq.cwd(); + + console.log(`[patched @oclif/dev-cli] cwd="${prevCwd}"\n c.root="${c.root}" c.workspace()="${c.workspace()}"`); + const packCLI = async () => { const stdout = await qq.x.stdout('npm', ['pack', '--unsafe-perm'], { cwd: c.root }); return path.join(c.root, stdout.split('\n').pop()); @@ -34,6 +37,28 @@ async function build(c, options = {}) { await qq.mv(f, '.'); await qq.rm('package', tarball, 'bin/run.cmd'); }; + const copyCLI = async() => { + const ws = c.workspace(); + await qq.emptyDir(ws); + qq.cd(ws); + const sources = [ + 'bin', 'build', 'patches', 'typings', 'CHANGELOG.md', 'INSTALL.md', + 'LICENSE', 'package.json', 'npm-shrinkwrap.json', 'README.md', + 'TROUBLESHOOTING.md', + ]; + for (const source of sources) { + console.log(`cp "${source}" -> "${ws}"`); + await qq.cp(path.join(c.root, source), ws); + } + // rename the original balena-cli ./bin/balena entry point for oclif compatibility + await qq.mv('bin/balena', 'bin/run'); + await qq.rm('bin/run.cmd'); + // The oclif installers are produced with `npm i --production`, while the + // source `bin` folder may contain a `.fast-boot.json` produced with `npm i`. + // This has previously led to issues preventing the CLI from starting, so + // delete `.fast-boot.json` (if any) from the destination folder. + await qq.rm('bin/.fast-boot.json'); + } const updatePJSON = async () => { qq.cd(c.workspace()); const pjson = await qq.readJSON('package.json'); @@ -56,7 +81,13 @@ async function build(c, options = {}) { lockpath = qq.join(c.root, 'npm-shrinkwrap.json'); } await qq.cp(lockpath, '.'); - await qq.x('npm install --production'); + + const npmVersion = await qq.x.stdout('npm', ['--version']); + if (require('semver').lt(npmVersion, '6.9.0')) { + await qq.x('npx npm@6.9.0 install --production'); + } else { + await qq.x('npm install --production'); + } } }; const buildTarget = async (target) => { @@ -71,7 +102,8 @@ async function build(c, options = {}) { output: path.join(workspace, 'bin', 'node'), platform: target.platform, arch: target.arch, - tmp: qq.join(config.root, 'tmp'), + tmp, + projectRootPath: c.root, }); if (options.pack === false) return; @@ -124,7 +156,8 @@ async function build(c, options = {}) { await qq.writeJSON(c.dist(config.s3Key('manifest')), manifest); }; log_1.log(`gathering workspace for ${config.bin} to ${c.workspace()}`); - await extractCLI(await packCLI()); + // await extractCLI(await packCLI()); + await copyCLI(); await updatePJSON(); await addDependencies(); await bin_1.writeBinScripts({ config, baseWorkspace: c.workspace(), nodeVersion: c.nodeVersion }); diff --git a/node_modules/@oclif/dev-cli/lib/tarballs/config.js b/node_modules/@oclif/dev-cli/lib/tarballs/config.js index 320fc52..efe3f2f 100644 --- a/node_modules/@oclif/dev-cli/lib/tarballs/config.js +++ b/node_modules/@oclif/dev-cli/lib/tarballs/config.js @@ -10,7 +10,13 @@ function gitSha(cwd, options = {}) { } exports.gitSha = gitSha; async function Tmp(config) { - const tmp = path.join(config.root, 'tmp'); + let tmp; + if (process.env.BUILD_TMP) { + tmp = path.join(process.env.BUILD_TMP, 'oclif'); + } else { + tmp = path.join(config.root, 'tmp'); + } + console.log(`@oclif/dev-cli tmp="${tmp}"`); await qq.mkdirp(tmp); return tmp; } @@ -36,7 +42,7 @@ async function buildConfig(root, options = {}) { s3Config: updateConfig.s3, nodeVersion: updateConfig.node.version || process.versions.node, workspace(target) { - const base = qq.join(config.root, 'tmp'); + const base = tmp; if (target && target.platform) return qq.join(base, [target.platform, target.arch].join('-'), config.s3Key('baseDir', target)); return qq.join(base, config.s3Key('baseDir', target)); diff --git a/node_modules/@oclif/dev-cli/lib/tarballs/node.js b/node_modules/@oclif/dev-cli/lib/tarballs/node.js index 343eb00..5521e2d 100644 --- a/node_modules/@oclif/dev-cli/lib/tarballs/node.js +++ b/node_modules/@oclif/dev-cli/lib/tarballs/node.js @@ -1,28 +1,58 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const errors_1 = require("@oclif/errors"); +const { isMSYS2 } = require('qqjs'); const path = require("path"); const qq = require("qqjs"); const log_1 = require("../log"); -async function checkFor7Zip() { - try { - await qq.x('7z', { stdio: [0, null, 2] }); +const { fixPath } = require("../util"); +let try_install_7zip = true; +async function checkFor7Zip(projectRootPath) { + let zPaths = [ + fixPath(path.join(projectRootPath, 'node_modules', '7zip', '7zip-lite', '7z.exe')), + '7z', + ]; + let foundPath = ''; + for (const zPath of zPaths) { + try { + console.log(`probing 7zip at "${zPath}"...`); + await qq.x(zPath, { stdio: [0, null, 2] }); + foundPath = zPath; + break; + } + catch (err) {} } - catch (err) { - if (err.code === 127) - errors_1.error('install 7-zip to package windows tarball'); - else - throw err; + if (foundPath) { + console.log(`found 7zip at "${foundPath}"`); + } else if (try_install_7zip) { + try_install_7zip = false; + console.log(`attempting "npm install 7zip"...`); + qq.pushd(projectRootPath); + try { + await qq.x('npm', ['install', '--no-save', '7zip']); + } catch (err) { + errors_1.error('install 7-zip to package windows tarball', true); + } finally { + qq.popd(); + } + return checkFor7Zip(projectRootPath); + } else { + errors_1.error('install 7-zip to package windows tarball', true); } + return foundPath; } -async function fetchNodeBinary({ nodeVersion, output, platform, arch, tmp }) { +async function fetchNodeBinary({ nodeVersion, output, platform, arch, tmp, projectRootPath }) { + + console.log(`fetchNodeBinary using tmp="${tmp}`); + if (arch === 'arm') arch = 'armv6l'; let nodeBase = `node-v${nodeVersion}-${platform}-${arch}`; let tarball = path.join(tmp, 'node', `${nodeBase}.tar.xz`); let url = `https://nodejs.org/dist/v${nodeVersion}/${nodeBase}.tar.xz`; - if (platform === 'win32') { - await checkFor7Zip(); + let zPath = ''; + if (platform === 'win32') { + zPath = await checkFor7Zip(projectRootPath); nodeBase = `node-v${nodeVersion}-win-${arch}`; tarball = path.join(tmp, 'node', `${nodeBase}.7z`); url = `https://nodejs.org/dist/v${nodeVersion}/${nodeBase}.7z`; @@ -40,7 +70,8 @@ async function fetchNodeBinary({ nodeVersion, output, platform, arch, tmp }) { const basedir = path.dirname(tarball); await qq.mkdirp(basedir); await qq.download(url, tarball); - await qq.x(`grep ${path.basename(tarball)} ${shasums} | shasum -a 256 -c -`, { cwd: basedir }); + const shaCmd = isMSYS2 ? 'sha256sum -c -' : 'shasum -a 256 -c -'; + await qq.x(`grep ${path.basename(tarball)} ${fixPath(shasums)} | ${shaCmd}`, { cwd: basedir }); }; const extract = async () => { log_1.log(`extracting ${nodeBase}`); @@ -50,7 +81,7 @@ async function fetchNodeBinary({ nodeVersion, output, platform, arch, tmp }) { await qq.mkdirp(path.dirname(cache)); if (platform === 'win32') { qq.pushd(nodeTmp); - await qq.x(`7z x -bd -y ${tarball} > /dev/null`); + await qq.x(`"${zPath}" x -bd -y ${fixPath(tarball)} > /dev/null`); await qq.mv([nodeBase, 'node.exe'], cache); qq.popd(); } diff --git a/node_modules/@oclif/dev-cli/lib/util.js b/node_modules/@oclif/dev-cli/lib/util.js index 17368b4..9d3fcf9 100644 --- a/node_modules/@oclif/dev-cli/lib/util.js +++ b/node_modules/@oclif/dev-cli/lib/util.js @@ -1,6 +1,7 @@ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const _ = require("lodash"); +const { isCygwin, isMinGW, isMSYS2 } = require('qqjs'); function castArray(input) { if (input === undefined) return []; @@ -40,3 +41,17 @@ function sortBy(arr, fn) { } exports.sortBy = sortBy; exports.template = (context) => (t) => _.template(t || '')(context); + +function fixPath(badPath) { + console.log(`fixPath MSYSTEM=${process.env.MSYSTEM} OSTYPE=${process.env.OSTYPE} isMSYS2=${isMSYS2} isMingGW=${isMinGW} isCygwin=${isCygwin}`); + // 'c:\myfolder' -> '/c/myfolder' or '/cygdrive/c/myfolder' + let fixed = badPath.replace(/\\/g, '/'); + if (isMSYS2 || isMinGW) { + fixed = fixed.replace(/^([a-zA-Z]):/, '/$1'); + } else if (isCygwin) { + fixed = fixed.replace(/^([a-zA-Z]):/, '/cygdrive/$1'); + } + console.log(`[patched @oclif/dev-cli] fixPath before="${badPath}" after="${fixed}"`); + return fixed; +} +exports.fixPath = fixPath;