diff --git a/.idea/dictionaries/develar.xml b/.idea/dictionaries/develar.xml index 634338cd7e1..a153c8145c4 100644 --- a/.idea/dictionaries/develar.xml +++ b/.idea/dictionaries/develar.xml @@ -60,6 +60,8 @@ docdash docstrap dpkg + dylibbundler + eacces ebusy electronuserland emoji @@ -202,6 +204,7 @@ rimraf rollout rollouts + rpmbuild scripthost semver setfinderinfo diff --git a/.travis.yml b/.travis.yml index 98d2bc80ad4..8e1459bf16d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,47 +1,34 @@ osx_image: xcode8.3 +language: node_js matrix: include: - os: osx - env: TEST_FILES=BuildTest,extraMetadataTest,globTest,filesTest,ignoreTest,linux.*,windows.* NODE_VERSION=6 PUBLISH_TO_NPM=true + env: TEST_FILES=BuildTest,extraMetadataTest,globTest,filesTest,ignoreTest,linux.*,windows.* +# env: TEST_FILES=oneClickInstallerTest.* + node_js: "8" - os: osx - env: TEST_FILES=mac.* NODE_VERSION=8 + env: TEST_FILES=mac.* + node_js: "8" - os: osx - env: TEST_FILES=mac.* NODE_VERSION=6 - -language: c + env: TEST_FILES=mac.* + node_js: "6" cache: + yarn: true directories: - node_modules - $HOME/Library/Caches/electron - - $HOME/Library/Caches/electron-builder - /tmp/jest-electron-builder-tests -before_install: - - curl -L https://dl.bintray.com/develar/bin/7za -o /tmp/7za - - chmod +x /tmp/7za - - curl -L https://dl.bintray.com/develar/bin/wine-2.0.7z -o /tmp/wine.7z - - /tmp/7za x -o/usr/local/Cellar -y /tmp/wine.7z - - brew link --overwrite gnutls libtasn1 libusb libusb-compat nettle openssl wine git-lfs gnu-tar dpkg xz - - git-lfs pull - -# fontconfig jasper libgphoto2 libicns little-cms2 sane-backends webp gd - install: -- nvm install $NODE_VERSION -- nvm use --delete-prefix $NODE_VERSION -- ln -sf $PWD/test/vendor/yarn.js /usr/local/bin/yarn -- yarn --link-duplicates --pure-lockfile -- if [[ "$TRAVIS_BRANCH" == "master" && "$TRAVIS_PULL_REQUEST" == "false" && "$AUTO_PUBLISH" != "false" && "$TRAVIS_TAG" == "" && "$PUBLISH_TO_NPM" == "true" ]]; then yarn add @develar/semantic-release@next --dev ; fi + - mkdir -p /tmp/git-lfs && curl -L https://github.com/github/git-lfs/releases/download/v2.1.1/git-lfs-$([ "$TRAVIS_OS_NAME" == "linux" ] && echo "linux" || echo "darwin")-amd64-2.1.1.tar.gz | tar -xz -C /tmp/git-lfs --strip-components 1 && /tmp/git-lfs/git-lfs pull + - yarn script: -- yarn test - -after_success: -- if [[ "$TRAVIS_BRANCH" == "master" && "$TRAVIS_PULL_REQUEST" == "false" && "$AUTO_PUBLISH" != "false" && "$TRAVIS_TAG" == "" && "$PUBLISH_TO_NPM" == "true" ]]; then npm run semantic-release ; fi + - yarn test branches: except: diff --git a/README.md b/README.md index e3d8094bd59..e332f150edc 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ _Note: Platform specific `7zip-bin-*` packages are `optionalDependencies`, which ``` Then you can run `npm run dist` (to package in a distributable format (e.g. dmg, windows installer, deb package)) or `npm run pack` (only generates the package directory without really packaging it. This is useful for testing purposes). - To ensure your native dependencies are always matched electron version, simply add `"postinstall": "install-app-deps"` to your `package.json`. + To ensure your native dependencies are always matched electron version, simply add script `"postinstall": "electron-builder install-app-deps"` to your `package.json`. 5. If you have native addons of your own that are part of the application (not as a dependency), add `"nodeGypRebuild": true` to the `build` section of your development `package.json`. :bulb: Don't [use](https://github.com/electron-userland/electron-builder/issues/683#issuecomment-241214075) [npm](http://electron.atom.io/docs/tutorial/using-native-node-modules/#using-npm) (neither `.npmrc`) for configuring electron headers. Use [node-gyp-rebuild](https://github.com/electron-userland/electron-builder/issues/683#issuecomment-241488783) bin instead. diff --git a/docker/base/Dockerfile b/docker/base/Dockerfile index ee005b6af00..768e8357c8d 100644 --- a/docker/base/Dockerfile +++ b/docker/base/Dockerfile @@ -2,7 +2,6 @@ FROM buildpack-deps:zesty-curl # rpm is required for FPM to build rpm package # yasm is required to build p7zip -# osslsigncode to sign windows on Linux # install modern multi-thread xz # ldconfig - see 4.6. liblzma.so (or similar) not found when running xz diff --git a/docs/Home.md b/docs/Home.md index 3539558b63c..d93934e7d42 100644 --- a/docs/Home.md +++ b/docs/Home.md @@ -18,5 +18,4 @@ **Programmatic API** * [[electron-builder]] -* [[electron-builder-util]] * [[electron-publish]] diff --git a/docs/Multi Platform Build.md b/docs/Multi Platform Build.md index e4c6054b011..2fe4ad5b3e7 100644 --- a/docs/Multi Platform Build.md +++ b/docs/Multi Platform Build.md @@ -22,20 +22,9 @@ You don't need to clean dist output before build — output directory is cleaned ## macOS -Use [brew](http://brew.sh) to install required packages. +All required system dependencies (except rpm) will be downloaded automatically on demand on macOS 10.12+ (macOS Sierra). On Travis, please add `osx_image: xcode8.3` -### To build app for Windows on macOS: -``` -brew install wine --without-x11 -brew install mono -``` - -### To build app for Linux on macOS: -``` -brew install gnu-tar xz -``` - -To build rpm: `brew install rpm`. +To build rpm: `brew install rpm` ([brew](https://brew.sh)). ## Linux diff --git a/docs/_Sidebar.md b/docs/_Sidebar.md index 292b0cc3f3d..3d1f9e8e2ba 100644 --- a/docs/_Sidebar.md +++ b/docs/_Sidebar.md @@ -18,5 +18,4 @@ **Programmatic API** * [[electron-builder]] -* [[electron-builder-util]] * [[electron-publish]] \ No newline at end of file diff --git a/package.json b/package.json index e19c8a52761..4b773a06f39 100644 --- a/package.json +++ b/package.json @@ -5,11 +5,11 @@ "compile": "ts-babel packages/asar-integrity packages/electron-builder-http packages/electron-builder-util packages/electron-publish packages/electron-builder packages/electron-builder-squirrel-windows packages/electron-updater packages/electron-publisher-s3 test && node ./test/vendor/yarn.js schema", "lint": "node test/out/helpers/lint.js", "lint-deps": "node ./test/out/helpers/checkDeps.js", - "pretest": "node ./test/vendor/yarn.js compile && concurrently \"node test/out/helpers/lint.js\" \"node ./test/out/helpers/checkDeps.js\"", + "pretest": "node ./test/vendor/yarn.js compile && node test/out/helpers/lint.js && node ./test/out/helpers/checkDeps.js", "///": "Please see https://github.com/electron-userland/electron-builder/blob/master/CONTRIBUTING.md#run-test-using-cli how to run particular test instead full (and very slow) run", "test": "node ./test/out/helpers/runTests.js skipArtifactPublisher ALL_TESTS=isCi", "test-all": "node ./test/vendor/yarn.js pretest && node ./test/out/helpers/runTests.js", - "test-linux": "docker run --rm -ti -v ${PWD}: /project -v ${PWD##*/}-node-modules:/project/node_modules -v ~/.electron:/root/.electron electronuserland/electron-builder:wine /bin/bash -c \"node ./test/vendor/yarn.js && node ./test/vendor/yarn.js test\"", + "test-linux": "docker run --rm -ti -v ${PWD}:/project -v ${PWD##*/}-node-modules:/project/node_modules -v ~/.electron:/root/.electron electronuserland/electron-builder:wine /bin/bash -c \"node ./test/vendor/yarn.js && node ./test/vendor/yarn.js test\"", "//": "Update wiki if docs changed. Update only if functionalily are generally available (latest release, not next)", "update-wiki": "(git branch -D wiki || true) && git subtree split -b wiki --prefix docs/ && git push -f wiki wiki:master", "whitespace": "whitespace 'src/**/*.ts'", @@ -30,7 +30,7 @@ "ajv": "^5.2.0", "ajv-keywords": "^2.1.0", "archiver": "^1.3.0", - "aws-sdk": "^2.72.0", + "aws-sdk": "^2.73.0", "bluebird-lst": "^1.0.2", "chalk": "^1.1.3", "chromium-pickle-js": "^0.2.0", @@ -66,7 +66,7 @@ }, "devDependencies": { "@types/ini": "^1.3.29", - "@types/jest": "^20.0.0", + "@types/jest": "^20.0.1", "@types/js-yaml": "^3.5.31", "@types/node-forge": "^0.6.9", "@types/source-map-support": "^0.4.0", @@ -77,7 +77,6 @@ "babel-plugin-transform-es2015-parameters": "^6.24.1", "babel-plugin-transform-es2015-spread": "^6.22.0", "babel-plugin-transform-inline-imports-commonjs": "^1.2.0", - "concurrently": "^3.4.0", "convert-source-map": "^1.5.0", "decompress-zip": "^0.3.0", "depcheck": "^0.6.7", diff --git a/packages/electron-builder-squirrel-windows/src/squirrelPack.ts b/packages/electron-builder-squirrel-windows/src/squirrelPack.ts index d7ec5627346..95b5683fa76 100644 --- a/packages/electron-builder-squirrel-windows/src/squirrelPack.ts +++ b/packages/electron-builder-squirrel-windows/src/squirrelPack.ts @@ -1,7 +1,7 @@ import BluebirdPromise from "bluebird-lst" -import { debug, exec, execWine, prepareArgs, spawn } from "electron-builder-util" +import { debug, exec, log, spawn } from "electron-builder-util" import { copyFile, walk } from "electron-builder-util/out/fs" -import { log } from "electron-builder-util/out/log" +import { execWine, prepareArgs } from "electron-builder/out/util/wine" import { WinPackager } from "electron-builder/out/winPackager" import { createWriteStream, ensureDir, remove, stat, unlink } from "fs-extra-p" import * as path from "path" @@ -231,7 +231,8 @@ async function encodedZip(archive: any, dir: string, prefix: string, vendorPath: }) // createExecutableStubForExe - if (file.endsWith(".exe") && !file.includes("squirrel.exe")) { + // https://github.com/Squirrel/Squirrel.Windows/pull/1051 Only generate execution stubs for the top-level executables + if (file.endsWith(".exe") && !file.includes("squirrel.exe") && !relativeSafeFilePath.includes("/")) { const tempFile = await packager.getTempFile("stub.exe") await copyFile(path.join(vendorPath, "StubExecutable.exe"), tempFile) await execWine(path.join(vendorPath, "WriteZipToSetup.exe"), ["--copy-stub-resources", file, tempFile]) diff --git a/packages/electron-builder-squirrel-windows/src/squirrelWindows.ts b/packages/electron-builder-squirrel-windows/src/squirrelWindows.ts index e5ab5d42d65..6652dda5a33 100644 --- a/packages/electron-builder-squirrel-windows/src/squirrelWindows.ts +++ b/packages/electron-builder-squirrel-windows/src/squirrelWindows.ts @@ -1,6 +1,6 @@ import { Arch, getArchSuffix, Target } from "electron-builder" +import { log, warn } from "electron-builder-util" import { getBinFromGithub } from "electron-builder-util/out/binDownload" -import { log, warn } from "electron-builder-util/out/log" import { SquirrelWindowsOptions } from "electron-builder/out/options/winOptions" import { WinPackager } from "electron-builder/out/winPackager" import * as path from "path" diff --git a/packages/electron-builder-util/src/binDownload.ts b/packages/electron-builder-util/src/binDownload.ts index d0bcacda926..b169e3b0c6a 100644 --- a/packages/electron-builder-util/src/binDownload.ts +++ b/packages/electron-builder-util/src/binDownload.ts @@ -4,6 +4,7 @@ import { CancellationToken, DownloadOptions } from "electron-builder-http" import { emptyDir, rename, unlink } from "fs-extra-p" import * as path from "path" import { statOrNull } from "./fs" +import { log, warn } from "./log" import { httpExecutor } from "./nodeHttpExecutor" import { debug, debug7zArgs, getCacheDirectory, getTempName, spawn } from "./util" @@ -46,6 +47,8 @@ async function doGetBin(name: string, dirName: string, url: string, checksum: st return dirPath } + log(`Downloading ${dirName}, please wait`) + // 7z cannot be extracted from the input stream, temp file is required const tempUnpackDir = path.join(cachePath, getTempName()) const archiveName = `${tempUnpackDir}.7z` @@ -64,7 +67,21 @@ async function doGetBin(name: string, dirName: string, url: string, checksum: st (options).sha512 = checksum } - await httpExecutor.download(url, archiveName, options) + for (let attemptNumber = 1; attemptNumber < 4; attemptNumber++) { + try { + await httpExecutor.download(url, archiveName, options) + } + catch (e) { + if (attemptNumber >= 3) { + throw e + } + + warn(`Cannot download ${name}, attempt #${attemptNumber}: ${e}`) + await new BluebirdPromise((resolve, reject) => { + setTimeout(() => httpExecutor.download(url, archiveName, options).then(resolve).catch(reject), 1000 * attemptNumber) + }) + } + } await spawn(path7za, debug7zArgs("x").concat(archiveName, `-o${tempUnpackDir}`), { cwd: cachePath, diff --git a/packages/electron-builder-util/src/util.ts b/packages/electron-builder-util/src/util.ts index 608fcfcb896..70ba8dd5f3a 100644 --- a/packages/electron-builder-util/src/util.ts +++ b/packages/electron-builder-util/src/util.ts @@ -10,6 +10,7 @@ import { statOrNull } from "./fs" import { log, warn } from "./log" export { TmpDir } from "./tmp" +export { log, warn, task, subTask } from "./log" export const debug = _debug("electron-builder") export const debug7z = _debug("electron-builder:7z") @@ -36,17 +37,6 @@ export function removePassword(input: string) { }) } -export function execWine(file: string, args: Array, options?: ExecOptions): Promise { - return exec(process.platform === "win32" ? file : "wine", prepareArgs(args, file), options) -} - -export function prepareArgs(args: Array, exePath: string) { - if (process.platform !== "win32") { - args.unshift(exePath) - } - return args -} - export function exec(file: string, args?: Array | null, options?: ExecOptions): Promise { if (debug.enabled) { debug(`Executing ${file} ${args == null ? "" : removePassword(args.join(" "))}`) diff --git a/packages/electron-builder/src/appInfo.ts b/packages/electron-builder/src/appInfo.ts index ddf47d27b0e..38dc085722d 100644 --- a/packages/electron-builder/src/appInfo.ts +++ b/packages/electron-builder/src/appInfo.ts @@ -1,5 +1,4 @@ -import { isEmptyOrSpaces, smarten } from "electron-builder-util" -import { warn } from "electron-builder-util/out/log" +import { isEmptyOrSpaces, smarten, warn } from "electron-builder-util" import sanitizeFileName from "sanitize-filename" import { SemVer } from "semver" import { Config, Metadata } from "./metadata" diff --git a/packages/electron-builder/src/builder.ts b/packages/electron-builder/src/builder.ts index 0dfc95a3249..351db2d9809 100644 --- a/packages/electron-builder/src/builder.ts +++ b/packages/electron-builder/src/builder.ts @@ -1,8 +1,7 @@ import BluebirdPromise from "bluebird-lst" import { underline } from "chalk" import { CancellationToken } from "electron-builder-http" -import { addValue, isEmptyOrSpaces } from "electron-builder-util" -import { warn } from "electron-builder-util/out/log" +import { addValue, isEmptyOrSpaces, warn } from "electron-builder-util" import { executeFinally } from "electron-builder-util/out/promise" import { PublishOptions } from "electron-publish" import { Arch, archFromString, DIR_TARGET, Platform } from "./core" diff --git a/packages/electron-builder/src/cli/cli.ts b/packages/electron-builder/src/cli/cli.ts index 89255983b30..373242df14d 100644 --- a/packages/electron-builder/src/cli/cli.ts +++ b/packages/electron-builder/src/cli/cli.ts @@ -1,8 +1,7 @@ #! /usr/bin/env node import { cyan, dim, green, reset, underline } from "chalk" -import { exec } from "electron-builder-util" -import { log, warn } from "electron-builder-util/out/log" +import { exec, log, warn } from "electron-builder-util" import { printErrorAndExit } from "electron-builder-util/out/promise" import { readJson } from "fs-extra-p" import isCi from "is-ci" @@ -10,7 +9,7 @@ import * as path from "path" import updateNotifier from "update-notifier" import yargs from "yargs" import { build, configureBuildCommand } from "../builder" -import { getElectronVersion, loadConfig } from "../util/config" +import { getConfig, getElectronVersion } from "../util/config" import { getGypEnv } from "../util/yarn" import { createSelfSignedCert } from "./create-self-signed-cert" import { configureInstallAppDepsCommand, installAppDeps } from "./install-app-deps" @@ -65,7 +64,7 @@ function checkIsOutdated() { async function rebuildAppNativeCode(args: any) { const projectDir = process.cwd() - const config = await loadConfig(projectDir) + const config = await getConfig(projectDir, null, null, null) log(`Execute node-gyp rebuild for ${args.platform}:${args.arch}`) // this script must be used only for electron await exec(process.platform === "win32" ? "node-gyp.cmd" : "node-gyp", ["rebuild"], { diff --git a/packages/electron-builder/src/cli/create-self-signed-cert.ts b/packages/electron-builder/src/cli/create-self-signed-cert.ts index fea01767d0d..1d12960147b 100644 --- a/packages/electron-builder/src/cli/create-self-signed-cert.ts +++ b/packages/electron-builder/src/cli/create-self-signed-cert.ts @@ -1,7 +1,6 @@ import { bold } from "chalk" -import { exec, spawn, TmpDir } from "electron-builder-util" +import { exec, log, spawn, TmpDir } from "electron-builder-util" import { unlinkIfExists } from "electron-builder-util/out/fs" -import { log } from "electron-builder-util/out/log" import { ensureDir } from "fs-extra-p" import * as path from "path" import sanitizeFileName from "sanitize-filename" diff --git a/packages/electron-builder/src/cli/install-app-deps.ts b/packages/electron-builder/src/cli/install-app-deps.ts index 6ea80eb179c..e31eb04580e 100644 --- a/packages/electron-builder/src/cli/install-app-deps.ts +++ b/packages/electron-builder/src/cli/install-app-deps.ts @@ -1,11 +1,10 @@ #! /usr/bin/env node import BluebirdPromise from "bluebird-lst" -import { computeDefaultAppDirectory, use } from "electron-builder-util" -import { log, warn } from "electron-builder-util/out/log" +import { computeDefaultAppDirectory, log, use, warn } from "electron-builder-util" import { printErrorAndExit } from "electron-builder-util/out/promise" import yargs from "yargs" -import { getElectronVersion, loadConfig } from "../util/config" +import { getConfig, getElectronVersion } from "../util/config" import { installOrRebuild } from "../util/yarn" declare const PACKAGE_VERSION: string @@ -40,7 +39,7 @@ export async function installAppDeps(args: any) { } const projectDir = process.cwd() - const config = (await loadConfig(projectDir)) || {} + const config = (await getConfig(projectDir, null, null, null)) || {} const muonVersion = config.muonVersion const results = await BluebirdPromise.all([ computeDefaultAppDirectory(projectDir, use(config.directories, it => it!.app)), diff --git a/packages/electron-builder/src/fileMatcher.ts b/packages/electron-builder/src/fileMatcher.ts index 389ef911e25..cb57d599e30 100644 --- a/packages/electron-builder/src/fileMatcher.ts +++ b/packages/electron-builder/src/fileMatcher.ts @@ -1,7 +1,6 @@ import BluebirdPromise from "bluebird-lst" -import { asArray, debug } from "electron-builder-util" +import { asArray, debug, warn } from "electron-builder-util" import { copyDir, copyOrLinkFile, Filter, statOrNull } from "electron-builder-util/out/fs" -import { warn } from "electron-builder-util/out/log" import { mkdirs } from "fs-extra-p" import { Minimatch } from "minimatch" import * as path from "path" diff --git a/packages/electron-builder/src/fileTransformer.ts b/packages/electron-builder/src/fileTransformer.ts index d6a1cd336c2..ec1589268ea 100644 --- a/packages/electron-builder/src/fileTransformer.ts +++ b/packages/electron-builder/src/fileTransformer.ts @@ -1,7 +1,6 @@ -import { debug } from "electron-builder-util" +import { debug, warn } from "electron-builder-util" import { deepAssign } from "electron-builder-util/out/deepAssign" import { FileTransformer } from "electron-builder-util/out/fs" -import { warn } from "electron-builder-util/out/log" import { readJson } from "fs-extra-p" import * as path from "path" import { BuildInfo } from "./packagerApi" diff --git a/packages/electron-builder/src/macPackager.ts b/packages/electron-builder/src/macPackager.ts index ba6b0fe76b4..78aac0a555d 100644 --- a/packages/electron-builder/src/macPackager.ts +++ b/packages/electron-builder/src/macPackager.ts @@ -1,7 +1,6 @@ import BluebirdPromise from "bluebird-lst" -import { exec, isPullRequest } from "electron-builder-util" +import { exec, isPullRequest, log, task, warn } from "electron-builder-util" import { deepAssign } from "electron-builder-util/out/deepAssign" -import { log, task, warn } from "electron-builder-util/out/log" import { signAsync, SignOptions } from "electron-osx-sign" import { ensureDir } from "fs-extra-p" import * as path from "path" diff --git a/packages/electron-builder/src/options/winOptions.ts b/packages/electron-builder/src/options/winOptions.ts index d25dd545dbb..bed38abd78a 100644 --- a/packages/electron-builder/src/options/winOptions.ts +++ b/packages/electron-builder/src/options/winOptions.ts @@ -272,9 +272,10 @@ export interface NsisWebOptions extends NsisOptions { } /** - * Squirrel.Windows options. + * Squirrel.Windows options. Squirrel.Windows target is maintained, but deprecated. Please use `nsis` instead. * - * To use Squirrel.Windows please install `electron-builder-squirrel-windows` dependency. Squirrel.Windows target is maintained, but deprecated. Please use `nsis` instead. + * To use Squirrel.Windows please install `electron-builder-squirrel-windows` dependency. + * To build for Squirrel.Windows on macOS, please install `mono`: `brew install mono`. */ export interface SquirrelWindowsOptions extends WinBuildOptions { /** diff --git a/packages/electron-builder/src/packager.ts b/packages/electron-builder/src/packager.ts index fdd01bc3699..b8d0ac4cd3d 100644 --- a/packages/electron-builder/src/packager.ts +++ b/packages/electron-builder/src/packager.ts @@ -1,13 +1,11 @@ import BluebirdPromise from "bluebird-lst" import { CancellationToken } from "electron-builder-http" -import { computeDefaultAppDirectory, debug, exec, Lazy, safeStringifyJson, TmpDir, use } from "electron-builder-util" +import { computeDefaultAppDirectory, debug, exec, Lazy, log, safeStringifyJson, TmpDir, use } from "electron-builder-util" import { deepAssign } from "electron-builder-util/out/deepAssign" -import { log } from "electron-builder-util/out/log" import { all, executeFinally, orNullIfFileNotExist } from "electron-builder-util/out/promise" import { EventEmitter } from "events" import { ensureDir } from "fs-extra-p" import * as path from "path" -import { lt as isVersionLessThan } from "semver" import { AppInfo } from "./appInfo" import { readAsarJson } from "./asar" import { Arch, Platform, SourceRepositoryInfo, Target } from "./core" @@ -16,7 +14,7 @@ import { AfterPackContext, Config, Metadata } from "./metadata" import { ArtifactCreated, BuildInfo, PackagerOptions } from "./packagerApi" import { PlatformPackager } from "./platformPackager" import { computeArchToTargetNamesMap, createTargets, NoOpTarget } from "./targets/targetFactory" -import { computeFinalConfig, getElectronVersion, validateConfig } from "./util/config" +import { getConfig, getElectronVersion, validateConfig } from "./util/config" import { checkMetadata, readPackageJson } from "./util/packageMetadata" import { getRepositoryInfo } from "./util/repositoryInfo" import { getGypEnv, installOrRebuild } from "./util/yarn" @@ -124,7 +122,7 @@ export class Packager implements BuildInfo { this.devMetadata = await orNullIfFileNotExist(readPackageJson(devPackageFile)) const devMetadata = this.devMetadata - const config = await computeFinalConfig(projectDir, configPath, devMetadata, configFromOptions) + const config = await getConfig(projectDir, configPath, devMetadata, configFromOptions) if (debug.enabled) { debug(`Effective config: ${safeStringifyJson(config)}`) } @@ -184,8 +182,6 @@ export class Packager implements BuildInfo { const platformToTarget = new Map>() const createdOutDirs = new Set() - // custom packager - don't check wine - let checkWine = this.prepackaged == null && this.options.platformPackagerFactory == null for (const [platform, archToType] of this.options.targets!) { if (this.cancellationToken.cancelled) { break @@ -195,11 +191,6 @@ export class Packager implements BuildInfo { throw new Error("Build for macOS is supported only on macOS, please see https://github.com/electron-userland/electron-builder/wiki/Multi-Platform-Build") } - let wineCheck: Promise | null = null - if (checkWine && process.platform !== "win32" && platform === Platform.WINDOWS) { - wineCheck = exec("wine", ["--version"]) - } - const packager = this.createHelper(platform, cleanupTasks) const nameToTarget: Map = new Map() platformToTarget.set(platform, nameToTarget) @@ -215,11 +206,6 @@ export class Packager implements BuildInfo { break } - if (checkWine && wineCheck != null) { - checkWine = false - await checkWineVersion(wineCheck) - } - const targetList = createTargets(nameToTarget, targetNames.length === 0 ? packager.defaultTarget : targetNames, outDir, packager, cleanupTasks) const ourDirs = new Set() for (const target of targetList) { @@ -362,50 +348,6 @@ export function normalizePlatforms(rawPlatforms: Array | stri } } -/** - * @private - */ -export async function checkWineVersion(checkPromise: Promise) { - function wineError(prefix: string): string { - return `${prefix}, please see https://github.com/electron-userland/electron-builder/wiki/Multi-Platform-Build#${(process.platform === "linux" ? "linux" : "macos")}` - } - - let wineVersion: string - try { - wineVersion = (await checkPromise).trim() - } - catch (e) { - if (e.code === "ENOENT") { - throw new Error(wineError("wine is required")) - } - else { - throw new Error(`Cannot check wine version: ${e}`) - } - } - - if (wineVersion.startsWith("wine-")) { - wineVersion = wineVersion.substring("wine-".length) - } - - const spaceIndex = wineVersion.indexOf(" ") - if (spaceIndex > 0) { - wineVersion = wineVersion.substring(0, spaceIndex) - } - - const suffixIndex = wineVersion.indexOf("-") - if (suffixIndex > 0) { - wineVersion = wineVersion.substring(0, suffixIndex) - } - - if (wineVersion.split(".").length === 2) { - wineVersion += ".0" - } - - if (isVersionLessThan(wineVersion, "1.8.0")) { - throw new Error(wineError(`wine 1.8+ is required, but your version is ${wineVersion}`)) - } -} - export interface BuildResult { readonly outDir: string readonly platformToTargets: Map> diff --git a/packages/electron-builder/src/packager/dirPackager.ts b/packages/electron-builder/src/packager/dirPackager.ts index f76a9bde598..2beb309eeb0 100644 --- a/packages/electron-builder/src/packager/dirPackager.ts +++ b/packages/electron-builder/src/packager/dirPackager.ts @@ -1,8 +1,7 @@ import { path7za } from "7zip-bin" import BluebirdPromise from "bluebird-lst" -import { debug7zArgs, spawn } from "electron-builder-util" +import { debug7zArgs, log, spawn, warn } from "electron-builder-util" import { copyDir, DO_NOT_USE_HARD_LINKS } from "electron-builder-util/out/fs" -import { log, warn } from "electron-builder-util/out/log" import { chmod, emptyDir } from "fs-extra-p" import * as path from "path" import { PlatformPackager } from "../platformPackager" diff --git a/packages/electron-builder/src/packager/mac.ts b/packages/electron-builder/src/packager/mac.ts index ea39a9363ea..9311980d3eb 100644 --- a/packages/electron-builder/src/packager/mac.ts +++ b/packages/electron-builder/src/packager/mac.ts @@ -1,8 +1,7 @@ import { AsarIntegrity } from "asar-integrity" import BluebirdPromise from "bluebird-lst" -import { asArray, getPlatformIconFileName, use } from "electron-builder-util" +import { asArray, getPlatformIconFileName, use, warn } from "electron-builder-util" import { copyFile, copyOrLinkFile, unlinkIfExists } from "electron-builder-util/out/fs" -import { warn } from "electron-builder-util/out/log" import { readFile, rename, utimes, writeFile } from "fs-extra-p" import * as path from "path" import { build as buildPlist, parse as parsePlist } from "plist" diff --git a/packages/electron-builder/src/platformPackager.ts b/packages/electron-builder/src/platformPackager.ts index 8a8cd9f9994..75d05017f0d 100644 --- a/packages/electron-builder/src/platformPackager.ts +++ b/packages/electron-builder/src/platformPackager.ts @@ -1,9 +1,8 @@ import { computeData } from "asar-integrity" import BluebirdPromise from "bluebird-lst" -import { asArray, isEmptyOrSpaces, Lazy, use } from "electron-builder-util" +import { asArray, isEmptyOrSpaces, Lazy, log, use, warn } from "electron-builder-util" import { deepAssign } from "electron-builder-util/out/deepAssign" import { copyDir, statOrNull, unlinkIfExists } from "electron-builder-util/out/fs" -import { log, warn } from "electron-builder-util/out/log" import { orIfFileNotExist } from "electron-builder-util/out/promise" import { readdir, rename } from "fs-extra-p" import { Minimatch } from "minimatch" diff --git a/packages/electron-builder/src/presets/rectCra.ts b/packages/electron-builder/src/presets/rectCra.ts index ce3c8ca157c..347bc25657b 100644 --- a/packages/electron-builder/src/presets/rectCra.ts +++ b/packages/electron-builder/src/presets/rectCra.ts @@ -1,5 +1,5 @@ +import { warn } from "electron-builder-util" import { statOrNull } from "electron-builder-util/out/fs" -import { warn } from "electron-builder-util/out/log" import * as path from "path" import { Config } from "../metadata" diff --git a/packages/electron-builder/src/publish/PublishManager.ts b/packages/electron-builder/src/publish/PublishManager.ts index db84e0cc4af..441e85cf3ab 100644 --- a/packages/electron-builder/src/publish/PublishManager.ts +++ b/packages/electron-builder/src/publish/PublishManager.ts @@ -3,8 +3,7 @@ import BluebirdPromise from "bluebird-lst" import { CancellationToken } from "electron-builder-http" import { BintrayOptions, GenericServerOptions, GithubOptions, githubUrl, PublishConfiguration, PublishProvider, S3Options, s3Url } from "electron-builder-http/out/publishOptions" import { UpdateInfo } from "electron-builder-http/out/updateInfo" -import { asArray, debug, isEmptyOrSpaces, isPullRequest, Lazy, safeStringifyJson } from "electron-builder-util" -import { log, warn } from "electron-builder-util/out/log" +import { asArray, debug, isEmptyOrSpaces, isPullRequest, Lazy, log, safeStringifyJson, warn } from "electron-builder-util" import { throwError } from "electron-builder-util/out/promise" import { HttpPublisher, PublishContext, Publisher, PublishOptions } from "electron-publish" import { BintrayPublisher } from "electron-publish/out/BintrayPublisher" diff --git a/packages/electron-builder/src/targets/ArchiveTarget.ts b/packages/electron-builder/src/targets/ArchiveTarget.ts index eef72f3947c..a7476d3603e 100644 --- a/packages/electron-builder/src/targets/ArchiveTarget.ts +++ b/packages/electron-builder/src/targets/ArchiveTarget.ts @@ -1,4 +1,4 @@ -import { log } from "electron-builder-util/out/log" +import { log } from "electron-builder-util" import * as path from "path" import { Arch, Platform, Target } from "../core" import { PlatformPackager } from "../platformPackager" diff --git a/packages/electron-builder/src/targets/appImage.ts b/packages/electron-builder/src/targets/appImage.ts index 6fad26b4eff..cea17382867 100644 --- a/packages/electron-builder/src/targets/appImage.ts +++ b/packages/electron-builder/src/targets/appImage.ts @@ -1,8 +1,7 @@ import BluebirdPromise from "bluebird-lst" -import { exec } from "electron-builder-util" -import { getBin } from "electron-builder-util/out/binDownload" +import { exec, log } from "electron-builder-util" +import { getBin, getBinFromGithub } from "electron-builder-util/out/binDownload" import { unlinkIfExists } from "electron-builder-util/out/fs" -import { log } from "electron-builder-util/out/log" import { chmod, close, createReadStream, createWriteStream, open, write } from "fs-extra-p" import * as path from "path" import { v1 as uuid1 } from "uuid-1345" @@ -11,11 +10,9 @@ import { LinuxPackager } from "../linuxPackager" import { LinuxBuildOptions } from "../options/linuxOptions" import { LinuxTargetHelper } from "./LinuxTargetHelper" -const appImageVersion = process.platform === "darwin" ? "AppImage-09-07-16-mac" : "AppImage-09-07-16-linux" +const appImageVersion = process.platform === "darwin" ? "AppImage-17-06-17-mac" : "AppImage-09-07-16-linux" //noinspection SpellCheckingInspection -const appImageSha256 = process.platform === "darwin" ? "5d4a954876654403698a01ef5bd7f218f18826261332e7d31d93ab4432fa0312" : "ac324e90b502f4e995f6a169451dbfc911bb55c0077e897d746838e720ae0221" -//noinspection SpellCheckingInspection -const appImagePathPromise = getBin("AppImage", appImageVersion, `https://dl.bintray.com/electron-userland/bin/${appImageVersion}.7z`, appImageSha256) +const appImagePathPromise = process.platform === "darwin" ? getBinFromGithub("AppImage", "17-06-17-mac", "vIaikS8Z2dEnZXKSgtcTn4gimPHCclp+v62KV2Eh9EhxvOvpDFgR3FCgdOsON4EqP8PvnfifNtxgBixCfuQU0A==") : getBin("AppImage", appImageVersion, `https://dl.bintray.com/electron-userland/bin/${appImageVersion}.7z`, "ac324e90b502f4e995f6a169451dbfc911bb55c0077e897d746838e720ae0221") export default class AppImageTarget extends Target { readonly options: LinuxBuildOptions = Object.assign({}, this.packager.platformSpecificBuildOptions, (this.packager.config)[this.name]) @@ -65,7 +62,7 @@ export default class AppImageTarget extends Target { if (arch === Arch.x64) { // noinspection SpellCheckingInspection - const libDir = await getBin("AppImage-packages", "10.03.17", "https://bintray.com/electron-userland/bin/download_file?file_path=AppImage-packages-10.03.17-x64.7z", "172f9977fe9b24d35091d26ecbfebe2a14d96516a9c903e109e12b2a929042fe") + const libDir = process.platform === "darwin" ? path.join(appImagePath, "packages") : await getBin("AppImage-packages", "10.03.17", "https://bintray.com/electron-userland/bin/download_file?file_path=AppImage-packages-10.03.17-x64.7z", "172f9977fe9b24d35091d26ecbfebe2a14d96516a9c903e109e12b2a929042fe") args.push("-map", libDir, "/usr/lib") } diff --git a/packages/electron-builder/src/targets/archive.ts b/packages/electron-builder/src/targets/archive.ts index 7ad2dbd9d7e..b85ca93fc46 100644 --- a/packages/electron-builder/src/targets/archive.ts +++ b/packages/electron-builder/src/targets/archive.ts @@ -4,6 +4,8 @@ import { exists } from "electron-builder-util/out/fs" import { unlink } from "fs-extra-p" import * as path from "path" import { CompressionLevel } from "../core" +import { computeEnv, getLinuxToolsPath } from "../util/bundledTool" +import { isMacOsSierra } from "../util/macosVersion" class CompressionDescriptor { constructor(public flag: string, public env: string, public minLevel: string, public maxLevel: string = "-9") { @@ -24,11 +26,11 @@ export async function tar(compression: CompressionLevel | n, format: string, out const info = extToCompressionDescriptor[format] let tarEnv = process.env if (process.env.ELECTRON_BUILDER_COMPRESSION_LEVEL != null) { - tarEnv = Object.assign({}, process.env) + tarEnv = Object.assign({}, tarEnv) tarEnv[info.env] = "-" + process.env.ELECTRON_BUILDER_COMPRESSION_LEVEL } else if (compression != null && compression !== "normal") { - tarEnv = Object.assign({}, process.env) + tarEnv = Object.assign({}, tarEnv) tarEnv[info.env] = compression === "store" ? info.minLevel : info.maxLevel } @@ -37,6 +39,16 @@ export async function tar(compression: CompressionLevel | n, format: string, out args.push("--transform", `s,^\\.,${path.basename(outFile, "." + format)},`) } args.push(isMacApp ? path.basename(dirToArchive) : ".") + + if (await isMacOsSierra()) { + const linuxToolsPath = await getLinuxToolsPath() + tarEnv = Object.assign({}, tarEnv, { + PATH: computeEnv(process.env.PATH, [path.join(linuxToolsPath, "bin")]), + LANG: "en_US.UTF-8", + LC_CTYPE: "UTF-8", + }) + } + await spawn(process.platform === "darwin" || process.platform === "freebsd" ? "gtar" : "tar", args, { cwd: isMacApp ? path.dirname(dirToArchive) : dirToArchive, env: tarEnv diff --git a/packages/electron-builder/src/targets/dmg.ts b/packages/electron-builder/src/targets/dmg.ts index f422e1c1120..643f81829bd 100644 --- a/packages/electron-builder/src/targets/dmg.ts +++ b/packages/electron-builder/src/targets/dmg.ts @@ -1,8 +1,7 @@ import BluebirdPromise from "bluebird-lst" -import { debug, exec, isEmptyOrSpaces, spawn } from "electron-builder-util" +import { debug, exec, isEmptyOrSpaces, log, spawn, warn } from "electron-builder-util" import { deepAssign } from "electron-builder-util/out/deepAssign" import { copyFile, exists, statOrNull } from "electron-builder-util/out/fs" -import { log, warn } from "electron-builder-util/out/log" import { executeFinally } from "electron-builder-util/out/promise" import { outputFile, readFile, remove, unlink } from "fs-extra-p" import * as path from "path" diff --git a/packages/electron-builder/src/targets/fpm.ts b/packages/electron-builder/src/targets/fpm.ts index ff89b5e1955..8b0dd40f236 100644 --- a/packages/electron-builder/src/targets/fpm.ts +++ b/packages/electron-builder/src/targets/fpm.ts @@ -1,14 +1,15 @@ import BluebirdPromise from "bluebird-lst" -import { exec, smarten, TmpDir, use } from "electron-builder-util" +import { debug, exec, log, smarten, TmpDir, use, warn } from "electron-builder-util" import { getBin } from "electron-builder-util/out/binDownload" import { unlinkIfExists } from "electron-builder-util/out/fs" -import { log, warn } from "electron-builder-util/out/log" import { ensureDir, outputFile, readFile } from "fs-extra-p" import * as path from "path" import { Arch, Target, toLinuxArchString } from "../core" import * as errorMessages from "../errorMessages" import { LinuxPackager } from "../linuxPackager" import { DebOptions, LinuxTargetSpecificOptions } from "../options/linuxOptions" +import { computeEnv, getLinuxToolsPath } from "../util/bundledTool" +import { isMacOsSierra } from "../util/macosVersion" import { installPrefix, LinuxTargetHelper } from "./LinuxTargetHelper" const fpmPath = (process.platform === "win32" || process.env.USE_SYSTEM_FPM === "true") ? @@ -119,6 +120,12 @@ export default class FpmTarget extends Target { "--url", projectUrl, ] + if (debug.enabled) { + // args.push( + // "--log", "debug", + // "--debug") + } + const packageCategory = options.packageCategory if (packageCategory != null && packageCategory !== null) { args.push("--category", packageCategory) @@ -183,7 +190,21 @@ export default class FpmTarget extends Target { return } - await exec(await fpmPath, args) + let env = Object.assign({}, process.env, { + LANG: "en_US.UTF-8", + LC_CTYPE: "UTF-8", + }) + + // rpmbuild wants directory rpm with some default config files. Even if we can use dylibbundler, path to such config files are not changed (we need to replace in the binary) + // so, for now, brew install rpm is still required. + if (target !== "rpm" && await isMacOsSierra()) { + const linuxToolsPath = await getLinuxToolsPath() + Object.assign(env, { + PATH: computeEnv(process.env.PATH, [path.join(linuxToolsPath, "bin")]), + DYLD_LIBRARY_PATH: computeEnv(process.env.DYLD_LIBRARY_PATH, [path.join(linuxToolsPath, "lib")]), + }) + } + await exec(await fpmPath, args, {env}) this.packager.dispatchArtifactCreated(destination, this, arch) } diff --git a/packages/electron-builder/src/targets/nsis.ts b/packages/electron-builder/src/targets/nsis.ts index 5155a7969ac..40a374f515e 100644 --- a/packages/electron-builder/src/targets/nsis.ts +++ b/packages/electron-builder/src/targets/nsis.ts @@ -1,9 +1,8 @@ import BluebirdPromise from "bluebird-lst" import _debug from "debug" -import { asArray, debug, doSpawn, exec, getPlatformIconFileName, handleProcess, isEmptyOrSpaces, use } from "electron-builder-util" +import { asArray, debug, doSpawn, getPlatformIconFileName, handleProcess, isEmptyOrSpaces, log, subTask, use, warn } from "electron-builder-util" import { getBinFromGithub } from "electron-builder-util/out/binDownload" import { copyFile } from "electron-builder-util/out/fs" -import { log, subTask, warn } from "electron-builder-util/out/log" import { asyncAll } from "electron-builder-util/out/promise" import { outputFile, readFile, unlink } from "fs-extra-p" import { safeLoad } from "js-yaml" @@ -13,6 +12,7 @@ import { v5 as uuid5 } from "uuid-1345" import { Arch, Target } from "../core" import { NsisOptions, PortableOptions } from "../options/winOptions" import { normalizeExt } from "../platformPackager" +import { execWine } from "../util/wine" import { WinPackager } from "../winPackager" import { archive } from "./archive" import { bundledLanguages, getLicenseFiles, lcid, toLangWithRegion } from "./license" @@ -269,7 +269,7 @@ export class NsisTarget extends Target { defines.BUILD_UNINSTALLER = null defines.UNINSTALLER_OUT_FILE = isWin ? uninstallerPath : path.win32.join("Z:", uninstallerPath) await this.executeMakensis(defines, commands, await this.computeFinalScript(script, false)) - await exec(isWin ? installerPath : "wine", isWin ? [] : [installerPath]) + await execWine(installerPath, []) await packager.sign(uninstallerPath, " Signing NSIS uninstaller") delete defines.BUILD_UNINSTALLER @@ -430,8 +430,23 @@ export class NsisTarget extends Target { env: Object.assign({}, process.env, {NSISDIR: nsisPath, LC_CTYPE: "en_US.UTF-8"}), cwd: this.nsisTemplatesDir, }, true) - handleProcess("close", childProcess, command, resolve, error => { - reject(error + "\nNSIS script:\n" + script) + + const timeout = setTimeout(() => childProcess.kill(), 4 * 60 * 1000) + + handleProcess("close", childProcess, command, () => { + try { + clearTimeout(timeout) + } + finally { + resolve() + } + }, error => { + try { + clearTimeout(timeout) + } + finally { + reject(error + "\nNSIS script:\n" + script) + } }) childProcess.stdin.end(script) diff --git a/packages/electron-builder/src/targets/pkg.ts b/packages/electron-builder/src/targets/pkg.ts index bebf1f7900f..06d1c2391f4 100644 --- a/packages/electron-builder/src/targets/pkg.ts +++ b/packages/electron-builder/src/targets/pkg.ts @@ -9,14 +9,18 @@ import MacPackager from "../macPackager" import { PkgOptions } from "../options/macOptions" import { filterCFBundleIdentifier } from "../packager/mac" +const certType = "Developer ID Installer" + // http://www.shanekirk.com/2013/10/creating-flat-packages-in-osx/ +// to use --scripts, we must build .app bundle separately using pkgbuild +// productbuild --scripts doesn't work (because scripts in this case not added to our package) +// https://github.com/electron-userland/electron-osx-sign/issues/96#issuecomment-274986942 export class PkgTarget extends Target { readonly options: PkgOptions = Object.assign({ allowAnywhere: true, allowCurrentUserHome: true, allowRootDirectory: true, }, this.packager.config.pkg) - private readonly installLocation = this.options.installLocation || "/Applications" constructor(private readonly packager: MacPackager, readonly outDir: string) { super("pkg") @@ -28,38 +32,26 @@ export class PkgTarget extends Target { const appInfo = packager.appInfo const keychainName = (await packager.codeSigningInfo).keychainName - const certType = "Developer ID Installer" - const identity = await findIdentity(certType, options.identity || packager.platformSpecificBuildOptions.identity, keychainName) - if (identity == null && packager.forceCodeSigning) { - throw new Error(`Cannot find valid "${certType}" to sign standalone installer, please see https://github.com/electron-userland/electron-builder/wiki/Code-Signing`) - } const appOutDir = this.outDir const distInfoFile = path.join(appOutDir, "distribution.xml") - await exec("productbuild", ["--synthesize", "--component", appPath, this.installLocation, distInfoFile], { - cwd: appOutDir, - }) - let distInfo = await readFile(distInfoFile, "utf-8") - const insertIndex = distInfo.lastIndexOf("") - distInfo = distInfo.substring(0, insertIndex) + ` \n` + distInfo.substring(insertIndex) - await writeFile(distInfoFile, distInfo) - - debug(distInfo) - - // to use --scripts, we must build .app bundle separately using pkgbuild - // productbuild --scripts doesn't work (because scripts in this case not added to our package) - // https://github.com/electron-userland/electron-osx-sign/issues/96#issuecomment-274986942 const innerPackageFile = path.join(appOutDir, `${filterCFBundleIdentifier(appInfo.id)}.pkg`) - await this.buildComponentPackage(appPath, innerPackageFile) + const identity = (await BluebirdPromise.all([ + findIdentity(certType, options.identity || packager.platformSpecificBuildOptions.identity, keychainName), + this.customizeDistributionConfiguration(distInfoFile, appPath), + this.buildComponentPackage(appPath, innerPackageFile), + ]))[0] + + if (identity == null && packager.forceCodeSigning) { + throw new Error(`Cannot find valid "${certType}" to sign standalone installer, please see https://github.com/electron-userland/electron-builder/wiki/Code-Signing`) + } const outFile = path.join(appOutDir, packager.expandArtifactNamePattern(options, "pkg")) const args = prepareProductBuildArgs(identity, keychainName) args.push("--distribution", distInfoFile) args.push(outFile) - use(options.productbuild, it => args.push(...it)) - await exec("productbuild", args, { cwd: appOutDir, }) @@ -68,12 +60,25 @@ export class PkgTarget extends Target { packager.dispatchArtifactCreated(outFile, this, arch, `${appInfo.name}-${appInfo.version}.pkg`) } + private async customizeDistributionConfiguration(distInfoFile: string, appPath: string) { + await exec("productbuild", ["--synthesize", "--component", appPath, distInfoFile], { + cwd: this.outDir, + }) + + const options = this.options + let distInfo = await readFile(distInfoFile, "utf-8") + const insertIndex = distInfo.lastIndexOf("") + distInfo = distInfo.substring(0, insertIndex) + ` \n` + distInfo.substring(insertIndex) + debug(distInfo) + await writeFile(distInfoFile, distInfo) + } + private async buildComponentPackage(appPath: string, outFile: string) { const options = this.options const args = [ "--component", appPath, - "--install-location", this.installLocation, ] + use(this.options.installLocation || "/Applications", it => args.push("--install-location", it!)) if (options.scripts != null) { args.push("--scripts", path.resolve(this.packager.buildResourcesDir, options.scripts)) } diff --git a/packages/electron-builder/src/targets/snap.ts b/packages/electron-builder/src/targets/snap.ts index 52b9cbdde86..6d5d83262b5 100644 --- a/packages/electron-builder/src/targets/snap.ts +++ b/packages/electron-builder/src/targets/snap.ts @@ -1,6 +1,5 @@ -import { replaceDefault, spawn } from "electron-builder-util" +import { log, replaceDefault, spawn } from "electron-builder-util" import { copyFile } from "electron-builder-util/out/fs" -import { log } from "electron-builder-util/out/log" import { emptyDir, outputFile } from "fs-extra-p" import { safeDump } from "js-yaml" import { homedir } from "os" diff --git a/packages/electron-builder/src/util/asarUtil.ts b/packages/electron-builder/src/util/asarUtil.ts index 06a5d6c9c8a..f5def512b55 100644 --- a/packages/electron-builder/src/util/asarUtil.ts +++ b/packages/electron-builder/src/util/asarUtil.ts @@ -1,7 +1,6 @@ import BluebirdPromise from "bluebird-lst" -import { debug } from "electron-builder-util" +import { debug, log } from "electron-builder-util" import { CONCURRENCY, FileCopier, FileTransformer, Filter, MAX_FILE_REQUESTS, statOrNull, walk } from "electron-builder-util/out/fs" -import { log } from "electron-builder-util/out/log" import { createReadStream, createWriteStream, ensureDir, readFile, readlink, stat, Stats, writeFile } from "fs-extra-p" import * as path from "path" import { AsarFilesystem, Node, readAsar } from "../asar" diff --git a/packages/electron-builder/src/util/bundledTool.ts b/packages/electron-builder/src/util/bundledTool.ts new file mode 100644 index 00000000000..dd905db6a92 --- /dev/null +++ b/packages/electron-builder/src/util/bundledTool.ts @@ -0,0 +1,26 @@ +import { getBinFromGithub } from "electron-builder-util/out/binDownload" + +// 2 minutes +export const EXEC_TIMEOUT = {timeout: 120 * 1000} + +export interface ToolInfo { + path: string + env?: any +} + +export function computeEnv(oldValue: string | null | undefined, newValues: Array): string { + let parsedOldValue = oldValue ? oldValue.split(":") : [] + return newValues.concat(parsedOldValue).filter(it => it.length > 0).join(":") +} + +export function computeToolEnv(libPath: Array): any { + // noinspection SpellCheckingInspection + return Object.assign({}, process.env, { + DYLD_LIBRARY_PATH: computeEnv(process.env.DYLD_LIBRARY_PATH, libPath) + }) +} + +export function getLinuxToolsPath() { + //noinspection SpellCheckingInspection + return getBinFromGithub("linux-tools", "mac-10.12", "DowDogHsS6X4a5au4r8T8qYprf7hqjfzcU7DL5oiD43jhZMfkQOjmFFYC1s7Lp9ARXp+sm8OJhuwaqCHMVGZYg==") +} \ No newline at end of file diff --git a/packages/electron-builder/src/util/config.ts b/packages/electron-builder/src/util/config.ts index 4da037642c2..3be52f41fc0 100644 --- a/packages/electron-builder/src/util/config.ts +++ b/packages/electron-builder/src/util/config.ts @@ -1,9 +1,7 @@ import Ajv from "ajv" import { CancellationToken } from "electron-builder-http" -import { debug } from "electron-builder-util" +import { debug, log, warn } from "electron-builder-util" import { deepAssign } from "electron-builder-util/out/deepAssign" -import { statOrNull } from "electron-builder-util/out/fs" -import { log, warn } from "electron-builder-util/out/log" import { httpExecutor } from "electron-builder-util/out/nodeHttpExecutor" import { orNullIfFileNotExist } from "electron-builder-util/out/promise" import { readFile, readJson } from "fs-extra-p" @@ -16,12 +14,11 @@ import AdditionalPropertiesParams = ajv.AdditionalPropertiesParams import ErrorObject = ajv.ErrorObject import TypeParams = ajv.TypeParams -function getConfigFromPackageData(metadata: any) { - return metadata.build +function getConfigFromPackageData(metadata: any | null) { + return metadata == null ? null : metadata.build } -/** @internal */ -export async function doLoadConfig(configFile: string, projectDir: string): Promise { +async function doLoadConfig(configFile: string, projectDir: string): Promise { const data = await readFile(configFile, "utf8") let result if (configFile.endsWith(".json5") || configFile.endsWith(".json")) { @@ -39,30 +36,24 @@ export async function doLoadConfig(configFile: string, projectDir: string): Prom return result } -/** @internal */ -export async function loadConfig(projectDir: string, packageMetadata?: any): Promise { - for (const configFile of ["electron-builder.yml", "electron-builder.yaml", "electron-builder.json", "electron-builder.json5", "electron-builder.toml"]) { - const data = await orNullIfFileNotExist(doLoadConfig(path.join(projectDir, configFile), projectDir)) - if (data != null) { - return data - } - } - - const data = getConfigFromPackageData(packageMetadata || (await orNullIfFileNotExist(readJson(path.join(projectDir, "package.json"))))) +async function loadConfig(projectDir: string, packageMetadata?: any): Promise { + let data = getConfigFromPackageData(packageMetadata || (await orNullIfFileNotExist(readJson(path.join(projectDir, "package.json"))))) if (data != null) { return data } - if ((await statOrNull(path.join(projectDir, "app.asar"))) != null) { - // prepacked, do not throw error, just ignore - return null + for (const configFile of ["electron-builder.yml", "electron-builder.yaml", "electron-builder.json", "electron-builder.json5", "electron-builder.toml"]) { + data = await orNullIfFileNotExist(doLoadConfig(path.join(projectDir, configFile), projectDir)) + if (data != null) { + return data + } } - throw new Error(`Cannot find package.json in the ${projectDir}`) + return null } /** @internal */ -export async function computeFinalConfig(projectDir: string, configPath: string | null, packageMetadata: any | null, configFromOptions: Config | null | undefined): Promise { +export async function getConfig(projectDir: string, configPath: string | null, packageMetadata: any | null, configFromOptions: Config | null | undefined): Promise { let fileOrPackageConfig if (configPath == null) { fileOrPackageConfig = packageMetadata == null ? null : await loadConfig(projectDir, packageMetadata) diff --git a/packages/electron-builder/src/util/macosVersion.ts b/packages/electron-builder/src/util/macosVersion.ts new file mode 100644 index 00000000000..003b5ea90d1 --- /dev/null +++ b/packages/electron-builder/src/util/macosVersion.ts @@ -0,0 +1,25 @@ +import { Lazy } from "electron-builder-util" +import { readFile } from "fs-extra-p" +import * as semver from "semver" + +const macOsVersion = new Lazy(async () => { + const file = await readFile("/System/Library/CoreServices/SystemVersion.plist", "utf8") + const matches = /ProductVersion<\/key>[\s\S]*([\d.]+)<\/string>/.exec(file) + if (!matches) { + throw new Error("Couldn't find the macOS version") + } + return matches[1] +}) + +function clean(version: string) { + return version.split(".").length === 2 ? `${version}.0` : version +} + +/** @internal */ +export async function isOsVersionGreaterThanOrEqualTo(input: string) { + return semver.gte(await macOsVersion.value, clean(input)) +} + +export async function isMacOsSierra() { + return process.platform === "darwin" && await isOsVersionGreaterThanOrEqualTo("10.12") +} \ No newline at end of file diff --git a/packages/electron-builder/src/util/packageMetadata.ts b/packages/electron-builder/src/util/packageMetadata.ts index d20e2cc2898..3119418286c 100644 --- a/packages/electron-builder/src/util/packageMetadata.ts +++ b/packages/electron-builder/src/util/packageMetadata.ts @@ -1,5 +1,4 @@ -import { isEmptyOrSpaces } from "electron-builder-util" -import { warn } from "electron-builder-util/out/log" +import { isEmptyOrSpaces, log, warn } from "electron-builder-util" import { readFile, readJson } from "fs-extra-p" import * as path from "path" import { Metadata } from "../metadata" @@ -70,6 +69,11 @@ export function checkMetadata(metadata: Metadata, devMetadata: any | null, appPa } } + const devDependencies = (metadata).devDependencies + if (devDependencies != null && "electron-rebuild" in devDependencies) { + log('electron-rebuild not required if you use electron-builder, please consider to remove excess dependency from devDependencies\n\nTo ensure your native dependencies are always matched electron version, simply add script `"postinstall": "electron-builder install-app-deps" to your `package.json`') + } + if (errors.length > 0) { throw new Error(errors.join("\n")) } diff --git a/packages/electron-builder/src/util/wine.ts b/packages/electron-builder/src/util/wine.ts new file mode 100644 index 00000000000..aaa5b513d0b --- /dev/null +++ b/packages/electron-builder/src/util/wine.ts @@ -0,0 +1,84 @@ +import { exec, ExecOptions, Lazy } from "electron-builder-util" +import { getBinFromGithub } from "electron-builder-util/out/binDownload" +import * as path from "path" +import { lt as isVersionLessThan } from "semver" +import { computeEnv, EXEC_TIMEOUT, ToolInfo } from "./bundledTool" +import { isOsVersionGreaterThanOrEqualTo } from "./macosVersion" + +const wineExecutable = new Lazy(async () => { + if (process.platform === "darwin" && await isOsVersionGreaterThanOrEqualTo("10.12")) { + // noinspection SpellCheckingInspection + const wineDir = await getBinFromGithub("wine", "2.0.1-mac-10.12", "IvKwDml/Ob0vKfYVxcu92wxUzHu8lTQSjjb8OlCTQ6bdNpVkqw17OM14TPpzGMIgSxfVIrQZhZdCwpkxLyG3mg==") + return { + path: path.join(wineDir, "bin/wine"), + env: Object.assign({ + WINEDEBUG: "-all,err+all", + WINEDLLOVERRIDES: "winemenubuilder.exe=d", + WINEPREFIX: path.join(wineDir, "wine-home"), + DYLD_FALLBACK_LIBRARY_PATH: computeEnv(process.env.DYLD_FALLBACK_LIBRARY_PATH, [path.join(wineDir, "lib")]), + }) + } + } + + await checkWineVersion(exec("wine", ["--version"])) + return {path: "wine"} +}) + +export function execWine(file: string, args: Array, options: ExecOptions = EXEC_TIMEOUT): Promise { + if (process.platform === "win32") { + return exec(file, args, options) + } + else { + return wineExecutable.value + .then(wine => exec(wine.path, [file].concat(args), wine.env == null ? options : Object.assign({env: wine.env}, options))) + } +} + +export function prepareArgs(args: Array, exePath: string) { + if (process.platform !== "win32") { + args.unshift(exePath) + } + return args +} + +/** @private */ +export async function checkWineVersion(checkPromise: Promise) { + function wineError(prefix: string): string { + return `${prefix}, please see https://github.com/electron-userland/electron-builder/wiki/Multi-Platform-Build#${(process.platform === "linux" ? "linux" : "macos")}` + } + + let wineVersion: string + try { + wineVersion = (await checkPromise).trim() + } + catch (e) { + if (e.code === "ENOENT") { + throw new Error(wineError("wine is required")) + } + else { + throw new Error(`Cannot check wine version: ${e}`) + } + } + + if (wineVersion.startsWith("wine-")) { + wineVersion = wineVersion.substring("wine-".length) + } + + const spaceIndex = wineVersion.indexOf(" ") + if (spaceIndex > 0) { + wineVersion = wineVersion.substring(0, spaceIndex) + } + + const suffixIndex = wineVersion.indexOf("-") + if (suffixIndex > 0) { + wineVersion = wineVersion.substring(0, suffixIndex) + } + + if (wineVersion.split(".").length === 2) { + wineVersion += ".0" + } + + if (isVersionLessThan(wineVersion, "1.8.0")) { + throw new Error(wineError(`wine 1.8+ is required, but your version is ${wineVersion}`)) + } +} \ No newline at end of file diff --git a/packages/electron-builder/src/util/yarn.ts b/packages/electron-builder/src/util/yarn.ts index 0b85fda88bf..a67696d3f39 100644 --- a/packages/electron-builder/src/util/yarn.ts +++ b/packages/electron-builder/src/util/yarn.ts @@ -1,7 +1,6 @@ import BluebirdPromise from "bluebird-lst" -import { asArray, spawn } from "electron-builder-util" +import { asArray, log, spawn, warn } from "electron-builder-util" import { exists } from "electron-builder-util/out/fs" -import { log, warn } from "electron-builder-util/out/log" import { homedir } from "os" import * as path from "path" import { Config } from "../metadata" diff --git a/packages/electron-builder/src/winPackager.ts b/packages/electron-builder/src/winPackager.ts index 98066caf0ac..98de162f541 100644 --- a/packages/electron-builder/src/winPackager.ts +++ b/packages/electron-builder/src/winPackager.ts @@ -1,7 +1,6 @@ import BluebirdPromise from "bluebird-lst" import { parseDn } from "electron-builder-http/out/rfc2253Parser" -import { asArray, exec, Lazy, use } from "electron-builder-util" -import { log, warn } from "electron-builder-util/out/log" +import { asArray, exec, Lazy, log, use, warn } from "electron-builder-util" import { close, open, read, readFile, rename } from "fs-extra-p" import * as forge from "node-forge" import * as path from "path" @@ -14,6 +13,7 @@ import AppXTarget from "./targets/appx" import { AppPackageHelper, NsisTarget } from "./targets/nsis" import { createCommonTarget } from "./targets/targetFactory" import { WebInstallerTarget } from "./targets/WebInstallerTarget" +import { execWine } from "./util/wine" import { FileCodeSigningInfo, getSignVendorPath, sign, SignOptions } from "./windowsCodeSign" export class WinPackager extends PlatformPackager { @@ -257,13 +257,7 @@ export class WinPackager extends PlatformPackager { use(appInfo.companyName, it => args.push("--set-version-string", "CompanyName", it!)) use(this.platformSpecificBuildOptions.legalTrademarks, it => args.push("--set-version-string", "LegalTrademarks", it!)) use(await this.getIconPath(), it => args.push("--set-icon", it)) - - const rceditExecutable = path.join(await getSignVendorPath(), "rcedit.exe") - const isWin = process.platform === "win32" - if (!isWin) { - args.unshift(rceditExecutable) - } - await exec(isWin ? rceditExecutable : "wine", args) + await execWine(path.join(await getSignVendorPath(), "rcedit.exe"), args) await this.sign(file) } diff --git a/packages/electron-builder/src/windowsCodeSign.ts b/packages/electron-builder/src/windowsCodeSign.ts index 5452436a84f..2f0ff099c9d 100644 --- a/packages/electron-builder/src/windowsCodeSign.ts +++ b/packages/electron-builder/src/windowsCodeSign.ts @@ -1,15 +1,17 @@ -import { exec } from "electron-builder-util" +import { exec, warn } from "electron-builder-util" import { getBinFromGithub } from "electron-builder-util/out/binDownload" import { rename } from "fs-extra-p" import isCi from "is-ci" -import { release } from "os" +import * as os from "os" import * as path from "path" import { WinBuildOptions } from "./options/winOptions" +import { computeToolEnv, ToolInfo } from "./util/bundledTool" +import { isOsVersionGreaterThanOrEqualTo } from "./util/macosVersion" /** @internal */ export function getSignVendorPath() { //noinspection SpellCheckingInspection - return getBinFromGithub("winCodeSign", "1.8.0", "NWd9hH9MuAgJFzhVzW1bpPplDTBwwYfPUg2skeEri2zp4PFcibbUWPvqUTv+Xnyg0MCdpsrVF1GMIHZGT8wMRw==") + return getBinFromGithub("winCodeSign", "1.9.0", "cyhO9Mv5MTP2o9dwk/+qs0KvuO9CbDhjEJXA2ujpvhcsk5zmc+zY9iqiWXVzOuibTLYNC3qZiuFlJrrCT2kldw==") } /** @internal */ @@ -138,7 +140,11 @@ async function spawnSign(options: SignOptions, inputPath: string, outputPath: st args.push(inputPath) } - return await exec(await getToolPath(), args, {timeout: 120 * 1000}) + const toolInfo = await getToolPath() + return await exec(toolInfo.path, args, { + timeout: 120 * 1000, + env: toolInfo.env || process.env + }) } function getOutputPath(inputPath: string, hash: string) { @@ -148,14 +154,13 @@ function getOutputPath(inputPath: string, hash: string) { /** @internal */ export function isOldWin6() { - const winVersion = release() + const winVersion = os.release() return winVersion.startsWith("6.") && !winVersion.startsWith("6.3") } -/** @internal */ -export async function getToolPath(): Promise { +async function getToolPath(): Promise { if (process.env.USE_SYSTEM_SIGNCODE) { - return "osslsigncode" + return {path: "osslsigncode"} } const result = process.env.SIGNTOOL_PATH @@ -167,16 +172,33 @@ export async function getToolPath(): Promise { if (process.platform === "win32") { // use modern signtool on Windows Server 2012 R2 to be able to sign AppX if (isOldWin6()) { - return path.join(vendorPath, "windows-6", "signtool.exe") + return {path: path.join(vendorPath, "windows-6", "signtool.exe")} } else { - return path.join(vendorPath, "windows-10", process.arch, "signtool.exe") + return {path: path.join(vendorPath, "windows-10", process.arch, "signtool.exe")} } } - else if (process.platform === "darwin" && isCi) { - return path.join(vendorPath, process.platform, "ci", "osslsigncode") + else if (process.platform === "darwin") { + let suffix: string | null = null + try { + if (await isOsVersionGreaterThanOrEqualTo("10.12")) { + const toolDirPath = path.join(vendorPath, process.platform, "10.12") + return { + path: path.join(toolDirPath, "osslsigncode"), + env: computeToolEnv([path.join(toolDirPath, "lib")]), + } + } + else if (isCi) { + // not clear for what we do this instead of using version detection + suffix = "ci" + } + } + catch (e) { + warn(`${e.stack || e}`) + } + return {path: path.join(vendorPath, process.platform, `${suffix == null ? "" : `${suffix}/`}osslsigncode`)} } else { - return path.join(vendorPath, process.platform, "osslsigncode") + return {path: path.join(vendorPath, process.platform, "osslsigncode")} } } diff --git a/packages/electron-publish/src/BintrayPublisher.ts b/packages/electron-publish/src/BintrayPublisher.ts index c9279c4d3ff..f2d296f2b28 100644 --- a/packages/electron-publish/src/BintrayPublisher.ts +++ b/packages/electron-publish/src/BintrayPublisher.ts @@ -2,8 +2,7 @@ import BluebirdPromise from "bluebird-lst" import { configureRequestOptions, HttpError } from "electron-builder-http" import { BintrayClient, Version } from "electron-builder-http/out/bintray" import { BintrayOptions } from "electron-builder-http/out/publishOptions" -import { debug, isEmptyOrSpaces } from "electron-builder-util" -import { log } from "electron-builder-util/out/log" +import { debug, isEmptyOrSpaces, log } from "electron-builder-util" import { httpExecutor } from "electron-builder-util/out/nodeHttpExecutor" import { ClientRequest } from "http" import { HttpPublisher, PublishContext, PublishOptions } from "./publisher" diff --git a/packages/electron-publish/src/gitHubPublisher.ts b/packages/electron-publish/src/gitHubPublisher.ts index 56193f15982..843e990e295 100644 --- a/packages/electron-publish/src/gitHubPublisher.ts +++ b/packages/electron-publish/src/gitHubPublisher.ts @@ -1,8 +1,7 @@ import BluebirdPromise from "bluebird-lst" import { configureRequestOptions, HttpError } from "electron-builder-http" import { GithubOptions } from "electron-builder-http/out/publishOptions" -import { debug, isEmptyOrSpaces } from "electron-builder-util" -import { log, warn } from "electron-builder-util/out/log" +import { debug, isEmptyOrSpaces, log, warn } from "electron-builder-util" import { httpExecutor } from "electron-builder-util/out/nodeHttpExecutor" import { ClientRequest } from "http" import mime from "mime" diff --git a/packages/electron-publish/src/publisher.ts b/packages/electron-publish/src/publisher.ts index 348e50ee806..9aa50bd62d8 100644 --- a/packages/electron-publish/src/publisher.ts +++ b/packages/electron-publish/src/publisher.ts @@ -1,6 +1,6 @@ import { green } from "chalk" import { CancellationToken, ProgressCallbackTransform } from "electron-builder-http" -import { log } from "electron-builder-util/out/log" +import { log } from "electron-builder-util" import { createReadStream, stat, Stats } from "fs-extra-p" import { ClientRequest } from "http" import { basename } from "path" diff --git a/packages/electron-publisher-s3/package.json b/packages/electron-publisher-s3/package.json index 94c44c3351c..8da268221fd 100644 --- a/packages/electron-publisher-s3/package.json +++ b/packages/electron-publisher-s3/package.json @@ -12,7 +12,7 @@ ], "dependencies": { "fs-extra-p": "^4.3.0", - "aws-sdk": "^2.72.0", + "aws-sdk": "^2.73.0", "mime": "^1.3.6", "electron-publish": "~0.0.0-semantic-release", "electron-builder-util": "~0.0.0-semantic-release" diff --git a/test/create-bottle.sh b/test/create-bottle.sh deleted file mode 100755 index 393742624ef..00000000000 --- a/test/create-bottle.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env bash -set -e - -cd /usr/local/Cellar -brew cleanup -brew prune -rm -f ~/wine.7z -7za a -m0=lzma2 -mx=9 -mfb=64 -md=64m -ms=on -xr!man -xr!doc ~/wine.7z fontconfig gd gnutls jasper libgphoto2 libicns libtasn1 libusb libusb-compat little-cms2 nettle openssl sane-backends webp wine git-lfs gnu-tar dpkg xz - -SEC=`security find-generic-password -l BINTRAY_API_KEY -g 2>&1` -ACCOUNT=`echo "$SEC" | grep "acct" | cut -d \" -f 4` -API_KEY=`echo "$SEC" | grep "password" | cut -d \" -f 2` - -curl --progress-bar -T ~/wine.7z -u${ACCOUNT}:${API_KEY} 'https://api.bintray.com/content/develar/bin/electron-builder-mac-test-bottle/1.0/wine.7z?override=1&publish=1' > /dev/null \ No newline at end of file diff --git a/test/out/linux/__snapshots__/debTest.js.snap b/test/out/linux/__snapshots__/debTest.js.snap index 9607a950588..10d1e91ffd9 100644 --- a/test/out/linux/__snapshots__/debTest.js.snap +++ b/test/out/linux/__snapshots__/debTest.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`arm deb 1`] = ` +exports[`arm 1`] = ` Object { "linux": Array [ Object { @@ -11,7 +11,7 @@ Object { } `; -exports[`arm deb 2`] = ` +exports[`arm 2`] = ` Array [ "/", "/opt/", @@ -72,12 +72,12 @@ Array [ ] `; -exports[`arm deb 3`] = ` +exports[`arm 3`] = ` Object { "Architecture": "armv7l", "Depends": "gconf2, gconf-service, libnotify4, libappindicator1, libxtst6, libnss3, libxss1", "Description": " - Test Application (test quite “ #378)", + Test Application (test quite “ #378)", "Homepage": "http://foo.example.com", "License": "MIT", "Maintainer": "Foo Bar ", @@ -178,7 +178,7 @@ Object { "Architecture": "amd64", "Depends": "foo", "Description": " - Test Application (test quite “ #378)", + Test Application (test quite “ #378)", "Homepage": "http://foo.example.com", "License": "MIT", "Maintainer": "Foo Bar ", @@ -267,7 +267,7 @@ Object { "Architecture": "amd64", "Depends": "gconf2, gconf-service, libnotify4, libappindicator1, libxtst6, libnss3, libxss1", "Description": " - Test Application (test quite “ #378)", + Test Application (test quite “ #378)", "Homepage": "http://foo.example.com", "License": "MIT", "Maintainer": "Foo Bar ", diff --git a/test/out/mac/__snapshots__/macArchiveTest.js.snap b/test/out/mac/__snapshots__/macArchiveTest.js.snap index c9b688b13c9..6bba889a0ee 100644 --- a/test/out/mac/__snapshots__/macArchiveTest.js.snap +++ b/test/out/mac/__snapshots__/macArchiveTest.js.snap @@ -420,7 +420,6 @@ Object { "versStr": "1.1.0", }, Object { - "customLocation": "/Applications", "id": "org.electron-builder.testApp", "pkg-ref": Object { "id": "org.electron-builder.testApp", diff --git a/test/src/BuildTest.ts b/test/src/BuildTest.ts index fb9d4e10fb4..93b6c5b8e92 100644 --- a/test/src/BuildTest.ts +++ b/test/src/BuildTest.ts @@ -2,7 +2,7 @@ import BluebirdPromise from "bluebird-lst" import { Arch, createTargets, DIR_TARGET, Platform } from "electron-builder" import { walk } from "electron-builder-util/out/fs" import { readAsarJson } from "electron-builder/out/asar" -import { checkWineVersion } from "electron-builder/out/packager" +import { checkWineVersion } from "electron-builder/out/util/wine" import { move, outputJson, readJson } from "fs-extra-p" import * as path from "path" import { ELECTRON_VERSION } from "./helpers/config" diff --git a/test/src/helpers/packTester.ts b/test/src/helpers/packTester.ts index df3f8eb2f6a..4e478fab260 100644 --- a/test/src/helpers/packTester.ts +++ b/test/src/helpers/packTester.ts @@ -1,12 +1,13 @@ +import BluebirdPromise from "bluebird-lst" import DecompressZip from "decompress-zip" import { Arch, ArtifactCreated, DIR_TARGET, getArchSuffix, MacOsTargetName, Packager, PackagerOptions, Platform, Target } from "electron-builder" import { CancellationToken } from "electron-builder-http" import { convertVersion } from "electron-builder-squirrel-windows/out/squirrelPack" -import { addValue, exec, getTempName, spawn } from "electron-builder-util" +import { addValue, exec, getTempName, log, spawn, warn } from "electron-builder-util" import { copyDir, FileCopier } from "electron-builder-util/out/fs" -import { log, warn } from "electron-builder-util/out/log" import { PublishManager } from "electron-builder/out/publish/PublishManager" import { computeArchToTargetNamesMap } from "electron-builder/out/targets/targetFactory" +import { getLinuxToolsPath } from "electron-builder/out/util/bundledTool" import { emptyDir, mkdir, readFile, readJson, remove, writeJson } from "fs-extra-p" import * as path from "path" import pathSorter from "path-sort" @@ -227,7 +228,9 @@ async function checkLinuxResult(outDir: string, packager: Packager, arch: Arch, expect(await getContents(`${outDir}/TestApp_${appInfo.version}_i386.deb`)).toMatchSnapshot() } - const control = parseDebControl(await exec("dpkg", ["--info", packageFile])) + const control = parseDebControl(await execShell(`ar p '${packageFile}' control.tar.gz | ${await getTarExecutable()} zx --to-stdout ./control`, { + maxBuffer: 10 * 1024 * 1024, + })) delete control.Version expect(control).toMatchSnapshot() } @@ -332,9 +335,21 @@ async function checkWindowsResult(packager: Packager, checkOptions: AssertPackOp } } -async function getContents(path: string) { +const execShell: any = BluebirdPromise.promisify(require("child_process").exec) + +async function getTarExecutable() { + return process.platform === "darwin" ? path.join(await getLinuxToolsPath(), "bin", "gtar") : "tar" +} + +async function getContents(packageFile: string) { // without LC_CTYPE dpkg can returns encoded unicode symbols - const result = await exec("dpkg", ["--contents", path], {env: Object.assign({}, process.env, {LANG: "en_US.UTF-8", LC_CTYPE: "UTF-8"})}) + const result = await execShell(`ar p '${packageFile}' data.tar.gz | ${await getTarExecutable()} zt`, { + maxBuffer: 10 * 1024 * 1024, + env: Object.assign({}, process.env, { + LANG: "en_US.UTF-8", + LC_CTYPE: "UTF-8", + }) + }) return pathSorter(parseFileList(result, true) .filter(it => !(it.includes(`/locales/`) || it.includes(`/libgcrypt`))) ) diff --git a/test/src/linux/debTest.ts b/test/src/linux/debTest.ts index e20e67e08e5..79e725514c1 100644 --- a/test/src/linux/debTest.ts +++ b/test/src/linux/debTest.ts @@ -4,7 +4,7 @@ import { app } from "../helpers/packTester" test.ifNotWindows("deb", app({targets: Platform.LINUX.createTarget("deb")})) -test.ifNotWindows("arm deb", app({targets: Platform.LINUX.createTarget("deb", Arch.armv7l)})) +test.ifNotWindows("arm", app({targets: Platform.LINUX.createTarget("deb", Arch.armv7l)})) test.ifNotWindows("custom depends", app({ targets: Platform.LINUX.createTarget("deb"), diff --git a/test/src/windows/oneClickInstallerTest.ts b/test/src/windows/oneClickInstallerTest.ts index dcb573f88a0..d07941ad1d5 100644 --- a/test/src/windows/oneClickInstallerTest.ts +++ b/test/src/windows/oneClickInstallerTest.ts @@ -31,7 +31,7 @@ test("one-click", app({ } })) -test.ifAll("multi language license", app({ +test.ifAll.ifNotCiMac("multi language license", app({ targets: Platform.WINDOWS.createTarget("nsis"), config: { publish: null, @@ -123,7 +123,7 @@ test.ifDevOrLinuxCi("custom script", app({targets: nsisTarget}, { packed: context => assertThat(path.join(context.projectDir, "build", "customInstallerScript")).isFile(), })) -test.ifAll("menuCategory", app({ +test.ifAll.ifNotCiMac("menuCategory", app({ targets: Platform.WINDOWS.createTarget(["nsis"], Arch.ia32), config: { extraMetadata: { @@ -146,7 +146,7 @@ test.ifAll("menuCategory", app({ } })) -test.ifAll("string menuCategory", app({ +test.ifAll.ifNotCiMac("string menuCategory", app({ targets: Platform.WINDOWS.createTarget(["nsis"], Arch.ia32), config: { extraMetadata: { diff --git a/yarn.lock b/yarn.lock index 4fbab384c38..643bb3c2f47 100644 --- a/yarn.lock +++ b/yarn.lock @@ -26,9 +26,9 @@ version "1.3.29" resolved "https://registry.yarnpkg.com/@types/ini/-/ini-1.3.29.tgz#1325e981e047d40d13ce0359b821475b97741d2f" -"@types/jest@^20.0.0": - version "20.0.0" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-20.0.0.tgz#f7119f92891e150b33d67505cdd6d95585156133" +"@types/jest@^20.0.1": + version "20.0.1" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-20.0.1.tgz#8643a195d925a00f7bdee5257d12c3aac743f3b4" "@types/js-yaml@^3.5.31": version "3.5.31" @@ -39,8 +39,8 @@ resolved "https://registry.yarnpkg.com/@types/node-forge/-/node-forge-0.6.9.tgz#38e0e00de8e6f3ff0bb1f4cddcad43e7b580733a" "@types/node@*": - version "7.0.31" - resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.31.tgz#80ea4d175599b2a00149c29a10a4eb2dff592e86" + version "8.0.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.0.tgz#acaa89247afddc7967e9902fd11761dadea1a555" "@types/source-map-support@^0.4.0": version "0.4.0" @@ -128,18 +128,10 @@ ansi-escapes@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" -ansi-regex@^0.2.0, ansi-regex@^0.2.1: - version "0.2.1" - resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-0.2.1.tgz#0d8e946967a3d8143f93e24e298525fc1b2235f9" - ansi-regex@^2.0.0, ansi-regex@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" -ansi-styles@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.1.0.tgz#eaecbf66cd706882760b2f4691582b8f55d7a7de" - ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" @@ -275,9 +267,9 @@ asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" -aws-sdk@^2.72.0: - version "2.72.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.72.0.tgz#59021c14e354f34a4fb4f229ac10f8e36428f4d4" +aws-sdk@^2.73.0: + version "2.73.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.73.0.tgz#15e0bb31436ebe433aebb6751dd6c36447beebba" dependencies: buffer "5.0.6" crypto-browserify "1.0.9" @@ -707,16 +699,6 @@ chainsaw@~0.1.0: dependencies: traverse ">=0.3.0 <0.4" -chalk@0.5.1: - version "0.5.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.5.1.tgz#663b3a648b68b55d04690d49167aa837858f2174" - dependencies: - ansi-styles "^1.1.0" - escape-string-regexp "^1.0.0" - has-ansi "^0.1.0" - strip-ansi "^0.3.0" - supports-color "^0.2.0" - chalk@^1.0.0, chalk@^1.1.0, chalk@^1.1.1, chalk@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" @@ -821,10 +803,6 @@ command-line-usage@^4.0.0: table-layout "^0.4.0" typical "^2.6.0" -commander@2.6.0: - version "2.6.0" - resolved "https://registry.yarnpkg.com/commander/-/commander-2.6.0.tgz#9df7e52fb2a0cb0fb89058ee80c3104225f37e1d" - commander@^2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" @@ -852,19 +830,6 @@ concat-map@0.0.1: version "0.0.1" resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" -concurrently@^3.4.0: - version "3.4.0" - resolved "https://registry.yarnpkg.com/concurrently/-/concurrently-3.4.0.tgz#60662b3defde07375bae19aac0ab780ec748ba79" - dependencies: - chalk "0.5.1" - commander "2.6.0" - date-fns "^1.23.0" - lodash "^4.5.1" - rx "2.3.24" - spawn-command "^0.0.2-1" - supports-color "^3.2.3" - tree-kill "^1.1.0" - config-master@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/config-master/-/config-master-3.1.0.tgz#667663590505a283bf26a484d68489d74c5485da" @@ -969,10 +934,6 @@ dashdash@^1.12.0: dependencies: assert-plus "^1.0.0" -date-fns@^1.23.0: - version "1.28.5" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.28.5.tgz#257cfc45d322df45ef5658665967ee841cd73faf" - debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.6.1, debug@^2.6.3, debug@^2.6.6, debug@^2.6.8: version "2.6.8" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" @@ -1159,7 +1120,7 @@ error-ex@^1.2.0: dependencies: is-arrayish "^0.2.1" -escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.2, escape-string-regexp@~1.0.5: +escape-string-regexp@^1.0.2, escape-string-regexp@~1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" @@ -1496,12 +1457,6 @@ har-validator@~4.2.1: ajv "^4.9.1" har-schema "^1.0.5" -has-ansi@^0.1.0: - version "0.1.0" - resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-0.1.0.tgz#84f265aae8c0e6a88a12d7022894b7568894c62e" - dependencies: - ansi-regex "^0.2.0" - has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" @@ -1583,7 +1538,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@~2.0.1: +inherits@2, inherits@~2.0.1, inherits@~2.0.3: version "2.0.3" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" @@ -2488,8 +2443,8 @@ number-is-nan@^1.0.0: resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" "nwmatcher@>= 1.3.9 < 2.0.0": - version "1.4.0" - resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.0.tgz#b4389362170e7ef9798c3c7716d80ebc0106fccf" + version "1.4.1" + resolved "https://registry.yarnpkg.com/nwmatcher/-/nwmatcher-1.4.1.tgz#7ae9b07b0ea804db7e25f05cb5fe4097d4e4949f" oauth-sign@~0.8.1: version "0.8.2" @@ -2817,14 +2772,14 @@ readable-stream@^1.1.8, readable-stream@~1.1.9: string_decoder "~0.10.x" readable-stream@^2.0.0, readable-stream@^2.0.5: - version "2.2.11" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.11.tgz#0796b31f8d7688007ff0b93a8088d34aa17c0f72" + version "2.3.0" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.0.tgz#640f5dcda88c91a8dc60787145629170813a1ed2" dependencies: core-util-is "~1.0.0" - inherits "~2.0.1" + inherits "~2.0.3" isarray "~1.0.0" process-nextick-args "~1.0.6" - safe-buffer "~5.0.1" + safe-buffer "~5.1.0" string_decoder "~1.0.0" util-deprecate "~1.0.1" @@ -2974,11 +2929,7 @@ rimraf@^2.6.1: dependencies: glob "^7.0.5" -rx@2.3.24: - version "2.3.24" - resolved "https://registry.yarnpkg.com/rx/-/rx-2.3.24.tgz#14f950a4217d7e35daa71bbcbe58eff68ea4b2b7" - -safe-buffer@^5.0.1: +safe-buffer@^5.0.1, safe-buffer@~5.1.0: version "5.1.0" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.0.tgz#fe4c8460397f9eaaaa58e73be46273408a45e223" @@ -3086,10 +3037,6 @@ source-map@~0.2.0: dependencies: amdefine ">=0.0.4" -spawn-command@^0.0.2-1: - version "0.0.2" - resolved "https://registry.yarnpkg.com/spawn-command/-/spawn-command-0.0.2.tgz#9544e1a43ca045f8531aac1a48cb29bdae62338e" - spdx-correct@~1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" @@ -3185,12 +3132,6 @@ stringstream@~0.0.4: version "0.0.5" resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" -strip-ansi@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.3.0.tgz#25f48ea22ca79187f3174a4db8759347bb126220" - dependencies: - ansi-regex "^0.2.1" - strip-ansi@^3.0.0, strip-ansi@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" @@ -3227,15 +3168,11 @@ sumchecker@^2.0.2: dependencies: debug "^2.2.0" -supports-color@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-0.2.0.tgz#d92de2694eb3f67323973d7ae3d8b55b4c22190a" - supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" -supports-color@^3.1.2, supports-color@^3.2.3: +supports-color@^3.1.2: version "3.2.3" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" dependencies: @@ -3367,10 +3304,6 @@ tr46@~0.0.3: version "0.3.9" resolved "https://registry.yarnpkg.com/traverse/-/traverse-0.3.9.tgz#717b8f220cc0bb7b44e40514c22b2e8bbc70d8b9" -tree-kill@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/tree-kill/-/tree-kill-1.1.0.tgz#c963dcf03722892ec59cba569e940b71954d1729" - trim-newlines@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-1.0.0.tgz#5887966bb582a4503a41eb524f7d35011815a613" @@ -3652,10 +3585,14 @@ window-size@0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" -wordwrap@0.0.2, wordwrap@~0.0.2: +wordwrap@0.0.2: version "0.0.2" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + wordwrap@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb"