From d90ad8301bc753fee5ac1ecc520edc73331cabda Mon Sep 17 00:00:00 2001 From: "Vipul Gupta (@vipulgupta2048)" Date: Thu, 8 Apr 2021 18:39:22 +0530 Subject: [PATCH] Publish ARM Signed-off-by: Vipul Gupta (@vipulgupta2048) --- npm-shrinkwrap.json | 19 +- patches/@oclif+dev-cli+1.22.2.patch | 339 ---------------------------- patches/@oclif+dev-cli+1.26.0.patch | 262 +++++++++++++++++++++ 3 files changed, 276 insertions(+), 344 deletions(-) delete mode 100644 patches/@oclif+dev-cli+1.22.2.patch create mode 100644 patches/@oclif+dev-cli+1.26.0.patch diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 086a315e..33049578 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -3211,11 +3211,25 @@ "isarray": "^1.0.0" } }, + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=" + }, "sax": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.1.tgz", "integrity": "sha1-e45lYZCyKOgaZq6nSEgNgozS03o=" }, + "url": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/url/-/url-0.10.3.tgz", + "integrity": "sha1-Ah5NnHcF8hu/N9A861h2dAJ3TGQ=", + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + } + }, "uuid": { "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", @@ -13822,11 +13836,6 @@ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" - }, "randombytes": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", diff --git a/patches/@oclif+dev-cli+1.22.2.patch b/patches/@oclif+dev-cli+1.22.2.patch deleted file mode 100644 index 16e42629..00000000 --- a/patches/@oclif+dev-cli+1.22.2.patch +++ /dev/null @@ -1,339 +0,0 @@ -diff --git a/node_modules/@oclif/dev-cli/lib/commands/pack/deb.js b/node_modules/@oclif/dev-cli/lib/commands/pack/deb.js -index 51bce6e..b9d21bb 100644 ---- a/node_modules/@oclif/dev-cli/lib/commands/pack/deb.js -+++ b/node_modules/@oclif/dev-cli/lib/commands/pack/deb.js -@@ -37,8 +37,8 @@ class PackDeb extends command_1.Command { - await qq.write([workspace, 'DEBIAN/control'], scripts.control(buildConfig, debArch(arch))); - await qq.chmod([workspace, 'usr/lib', config.dirname, 'bin', config.bin], 0o755); - await qq.x(`ln -s "../lib/${config.dirname}/bin/${config.bin}" "${workspace}/usr/bin/${config.bin}"`); -- await qq.x(`chown -R root "${workspace}"`); -- await qq.x(`chgrp -R root "${workspace}"`); -+ await qq.x(`sudo chown -R root "${workspace}"`); -+ await qq.x(`sudo chgrp -R root "${workspace}"`); - await qq.x(`dpkg --build "${workspace}" "${qq.join(dist, `${versionedDebBase}.deb`)}"`); - }; - const arches = _.uniq(buildConfig.targets -@@ -89,9 +89,13 @@ export ${config.scopedEnvVarKey('UPDATE_INSTRUCTIONS')}="update with \\"sudo apt - Version: ${debVersion(config)} - Section: main - Priority: standard -+Depends: neofetch, openssh-client, avahi-daemon -+Recommends: yes, make, python -+Suggests: cowsay, gnome-terminal | x-terminal-emulator, gnome-system-tools, nautilus, menu-xdg (>= 0.2) - Architecture: ${arch} - Maintainer: ${config.config.scopedEnvVar('AUTHOR') || config.config.pjson.author} - Description: ${config.config.pjson.description} -+Homepage: ${config.config.pjson.homepage} - `, - ftparchive: (config) => ` - APT::FTPArchive::Release { -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..4ac508f 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 = { -@@ -89,6 +93,13 @@ VIAddVersionKey /LANG=\${LANG_ENGLISH} "ProductVersion" "\${VERSION}.0" - InstallDir "\$PROGRAMFILES${arch === 'x64' ? '64' : ''}\\${config.dirname}" - - Section "${config.name} CLI \${VERSION}" -+ ; First remove any old client files. -+ ; (Remnants of old versions were causing CLI errors) -+ ; Initially tried running the Uninstall.exe, but was -+ ; unable to make script wait for completion (despite using _?) -+ DetailPrint "Removing files from previous version." -+ RMDir /r "$INSTDIR\\client" -+ - SetOutPath $INSTDIR - File /r bin - File /r client -diff --git a/node_modules/@oclif/dev-cli/lib/tarballs/build.js b/node_modules/@oclif/dev-cli/lib/tarballs/build.js -index 3e613e0..4059ff4 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,44 @@ 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 = [ -+ 'CHANGELOG.md', -+ 'INSTALL.md', -+ 'LICENSE', -+ 'README.md', -+ 'TROUBLESHOOTING.md', -+ 'automation/check-npm-version.js', -+ 'bin', -+ 'build', -+ 'npm-shrinkwrap.json', -+ 'package.json', -+ 'patches', -+ 'typings', -+ 'oclif.manifest.json', -+ ]; -+ for (const source of sources) { -+ let destDir = ws; -+ const dirname = path.dirname(source); -+ if (dirname && dirname !== '.') { -+ destDir = path.join(ws, dirname); -+ qq.mkdirp(destDir); -+ } -+ console.log(`cp "${source}" -> "${ws}"`); -+ await qq.cp(path.join(c.root, source), destDir); -+ } -+ // 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 +97,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 +118,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 +172,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 b3918c5..073515a 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 = 'armv7l'; - 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`; -+ let zPath = ''; - if (platform === 'win32') { -- await checkFor7Zip(); -+ 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; diff --git a/patches/@oclif+dev-cli+1.26.0.patch b/patches/@oclif+dev-cli+1.26.0.patch new file mode 100644 index 00000000..f3775b19 --- /dev/null +++ b/patches/@oclif+dev-cli+1.26.0.patch @@ -0,0 +1,262 @@ +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 e0abbbe..debf799 100644 +--- a/node_modules/@oclif/dev-cli/lib/commands/pack/macos.js ++++ b/node_modules/@oclif/dev-cli/lib/commands/pack/macos.js +@@ -128,6 +128,7 @@ class PackMacos extends command_1.Command { + if (process.env.OSX_KEYCHAIN) + args.push('--keychain', process.env.OSX_KEYCHAIN); + args.push(dist); ++ console.error(`[debug] @oclif/dev-cli 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 a313991..6681892 100644 +--- a/node_modules/@oclif/dev-cli/lib/commands/pack/win.js ++++ b/node_modules/@oclif/dev-cli/lib/commands/pack/win.js +@@ -51,6 +51,13 @@ VIAddVersionKey /LANG=\${LANG_ENGLISH} "ProductVersion" "\${VERSION}.0" + InstallDir "\$PROGRAMFILES${arch === 'x64' ? '64' : ''}\\${config.dirname}" + + Section "${config.name} CLI \${VERSION}" ++ ; First remove any old client files. ++ ; (Remnants of old versions were causing CLI errors) ++ ; Initially tried running the Uninstall.exe, but was ++ ; unable to make script wait for completion (despite using _?) ++ DetailPrint "Removing files from previous version." ++ RMDir /r "$INSTDIR\\client" ++ + SetOutPath $INSTDIR + File /r bin + File /r client +@@ -192,7 +199,8 @@ 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 ? 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); +@@ -207,7 +215,8 @@ class PackWin extends command_1.Command { + // eslint-disable-next-line no-await-in-loop + await qq.mv(buildConfig.workspace({ platform: 'win32', arch }), [installerBase, 'client']); + // eslint-disable-next-line no-await-in-loop +- await qq.x(`makensis ${installerBase}/${config.bin}.nsi | grep -v "\\[compress\\]" | grep -v "^File: Descending to"`); ++ const { msysExec, toMsysPath } = require("../../util"); ++ await msysExec(`makensis ${toMsysPath(installerBase)}/${config.bin}.nsi | grep -v "\\[compress\\]" | grep -v "^File: Descending to"`); + const o = buildConfig.dist(`win/${config.bin}-v${buildConfig.version}-${arch}.exe`); + // eslint-disable-next-line no-await-in-loop + await qq.mv([installerBase, 'installer.exe'], o); +@@ -232,4 +241,5 @@ exports.default = PackWin; + 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)'}), + }; +diff --git a/node_modules/@oclif/dev-cli/lib/commands/publish/deb.js b/node_modules/@oclif/dev-cli/lib/commands/publish/deb.js +index 90176b3..1f7f040 100644 +--- a/node_modules/@oclif/dev-cli/lib/commands/publish/deb.js ++++ b/node_modules/@oclif/dev-cli/lib/commands/publish/deb.js +@@ -29,6 +29,7 @@ class PublishDeb extends command_1.Command { + }; + await uploadDeb('amd64'); + await uploadDeb('i386'); ++ await uploadDeb('armel'); + await upload('Packages.gz'); + await upload('Packages.xz'); + await upload('Packages.bz2'); +diff --git a/node_modules/@oclif/dev-cli/lib/tarballs/build.js b/node_modules/@oclif/dev-cli/lib/tarballs/build.js +index c6bd245..baa7f6f 100644 +--- a/node_modules/@oclif/dev-cli/lib/tarballs/build.js ++++ b/node_modules/@oclif/dev-cli/lib/tarballs/build.js +@@ -18,8 +18,9 @@ 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.error(`[debug] @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()); +@@ -30,11 +31,19 @@ async function build(c, options = {}) { + tarball = path.basename(tarball); + tarball = qq.join([c.workspace(), tarball]); + qq.cd(c.workspace()); +- await qq.x(`tar -xzf ${tarball}`); ++ const { msysExec, toMsysPath } = require("../util"); ++ await msysExec(`tar -xzf ${toMsysPath(tarball)}`); + // eslint-disable-next-line no-await-in-loop + for (const f of await qq.ls('package', { fullpath: true })) + await qq.mv(f, '.'); + await qq.rm('package', tarball, 'bin/run.cmd'); ++ // rename the original balena-cli ./bin/balena entry point for oclif compatibility ++ await qq.mv('bin/balena', 'bin/run'); ++ // The oclif installers are a production installation, while the source ++ // `bin` folder may contain a `.fast-boot.json` file of a dev installation. ++ // 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()); +@@ -46,21 +55,21 @@ async function build(c, options = {}) { + await qq.writeJSON('package.json', pjson); + }; + const addDependencies = async () => { +- qq.cd(c.workspace()); +- const yarnRoot = findYarnWorkspaceRoot(c.root) || c.root; +- const yarn = await qq.exists([yarnRoot, 'yarn.lock']); +- if (yarn) { +- await qq.cp([yarnRoot, 'yarn.lock'], '.'); +- await qq.x('yarn --no-progress --production --non-interactive'); +- } +- else { +- let lockpath = qq.join(c.root, 'package-lock.json'); +- if (!await qq.exists(lockpath)) { +- lockpath = qq.join(c.root, 'npm-shrinkwrap.json'); +- } +- await qq.cp(lockpath, '.'); +- await qq.x('npm install --production'); ++ const ws = c.workspace(); ++ qq.cd(ws); ++ console.error(`[debug] @oclif/dev-cli copying node_modules to "${ws}"`) ++ const source = path.join(c.root, 'node_modules'); ++ if (process.platform === 'win32') { ++ // xcopy is much faster than `qq.cp(source, ws)` ++ await qq.x(`xcopy "${source}" "${ws}\\node_modules" /S /E /B /I /K /Q /Y`); ++ } else { ++ // use the shell's `cp` on macOS in order to preserve extended ++ // file attributes containing `codesign` digital signatures ++ await qq.x(`cp -pR "${source}" "${ws}"`); + } ++ console.error(`[debug] @oclif/dev-cli running "npm prune --production" in "${ws}"`); ++ await qq.x('npm prune --production'); ++ console.error(`[debug] @oclif/dev-cli done`); + }; + const buildTarget = async (target) => { + const workspace = c.workspace(target); +@@ -74,7 +83,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; +diff --git a/node_modules/@oclif/dev-cli/lib/tarballs/config.js b/node_modules/@oclif/dev-cli/lib/tarballs/config.js +index 9754a6b..68ef6b7 100644 +--- a/node_modules/@oclif/dev-cli/lib/tarballs/config.js ++++ b/node_modules/@oclif/dev-cli/lib/tarballs/config.js +@@ -17,7 +17,10 @@ function gitSha(cwd, options = {}) { + } + exports.gitSha = gitSha; + async function Tmp(config) { +- const tmp = path.join(config.root, 'tmp'); ++ const tmp = process.env.BUILD_TMP ++ ? path.join(process.env.BUILD_TMP, 'oclif') ++ : path.join(config.root, 'tmp'); ++ console.error(`[debug] @oclif/dev-cli tmp="${tmp}"`); + await qq.mkdirp(tmp); + return tmp; + } +@@ -44,7 +47,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 fabe5c4..e32dd76 100644 +--- a/node_modules/@oclif/dev-cli/lib/tarballs/node.js ++++ b/node_modules/@oclif/dev-cli/lib/tarballs/node.js +@@ -4,9 +4,10 @@ const errors_1 = require("@oclif/errors"); + const path = require("path"); + const qq = require("qqjs"); + const log_1 = require("../log"); ++const { isMSYS2, msysExec, toMsysPath } = require("../util"); + async function checkFor7Zip() { + try { +- await qq.x('7z', { stdio: [0, null, 2] }); ++ await msysExec('7z', { stdio: [0, null, 2] }); + } + catch (error) { + if (error.code === 127) +@@ -41,7 +42,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 msysExec(`grep ${path.basename(tarball)} ${toMsysPath(shasums)} | ${shaCmd}`, { cwd: basedir }); + }; + const extract = async () => { + log_1.log(`extracting ${nodeBase}`); +@@ -51,7 +53,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 msysExec(`7z x -bd -y ${toMsysPath(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 b3d48b7..540bbe6 100644 +--- a/node_modules/@oclif/dev-cli/lib/util.js ++++ b/node_modules/@oclif/dev-cli/lib/util.js +@@ -40,3 +40,47 @@ function sortBy(arr, fn) { + } + exports.sortBy = sortBy; + exports.template = (context) => (t) => _.template(t || '')(context); ++ ++// OSTYPE is 'msys' for MSYS 1.0 and for MSYS2, or 'cygwin' for Cygwin ++// but note that OSTYPE is not "exported" by default, so run: export OSTYPE=$OSTYPE ++// MSYSTEM is 'MINGW32' for MSYS 1.0, 'MSYS' for MSYS2, and undefined for Cygwin ++const isCygwin = process.env.OSTYPE === 'cygwin'; ++const isMinGW = process.env.MSYSTEM && process.env.MSYSTEM.startsWith('MINGW'); ++const isMSYS2 = process.env.MSYSTEM && process.env.MSYSTEM.startsWith('MSYS'); ++const MSYSSHELLPATH = process.env.MSYSSHELLPATH || ++ (isMSYS2 ? 'C:\\msys64\\usr\\bin\\bash.exe' : ++ (isMinGW ? 'C:\\MinGW\\msys\\1.0\\bin\\bash.exe' : ++ (isCygwin ? 'C:\\cygwin64\\bin\\bash.exe' : '/bin/sh'))); ++ ++exports.isCygwin = isCygwin; ++exports.isMinGW = isMinGW; ++exports.isMSYS2 = isMSYS2; ++console.error(`[debug] @oclif/dev-cli MSYSSHELLPATH=${MSYSSHELLPATH} MSYSTEM=${process.env.MSYSTEM} OSTYPE=${process.env.OSTYPE} isMSYS2=${isMSYS2} isMingGW=${isMinGW} isCygwin=${isCygwin}`); ++ ++const qq = require("qqjs"); ++ ++/* Convert a Windows path like 'C:\tmp' to a MSYS path like '/c/tmp' */ ++function toMsysPath(windowsPath) { ++ // 'c:\myfolder' -> '/c/myfolder' or '/cygdrive/c/myfolder' ++ let msysPath = windowsPath.replace(/\\/g, '/'); ++ if (isMSYS2 || isMinGW) { ++ msysPath = msysPath.replace(/^([a-zA-Z]):/, '/$1'); ++ } else if (isCygwin) { ++ msysPath = msysPath.replace(/^([a-zA-Z]):/, '/cygdrive/$1'); ++ } ++ console.error(`[debug] @oclif/dev-cli toMsysPath before="${windowsPath}" after="${msysPath}"`); ++ return msysPath; ++} ++exports.toMsysPath = toMsysPath; ++ ++/* Like qqjs qq.x(), but using MSYS bash on Windows instead of cmd.exe */ ++async function msysExec(cmd, options = {}) { ++ if (process.platform !== 'win32') { ++ return qq.x(cmd, options); ++ } ++ const sh = MSYSSHELLPATH; ++ const args = ['-c', cmd]; ++ console.error(`[debug] @oclif/dev-cli msysExec sh="${sh}" args=${JSON.stringify(args)} options=${JSON.stringify(options)}`); ++ return qq.x(sh, args, options); ++} ++exports.msysExec = msysExec;