diff --git a/.idea/dictionaries/develar.xml b/.idea/dictionaries/develar.xml index 113d026592c..77bbf8f6852 100644 --- a/.idea/dictionaries/develar.xml +++ b/.idea/dictionaries/develar.xml @@ -20,15 +20,19 @@ github globaldots globby + gnubin graphicsmagick hicolor icnsutils keyserver libappindicator + libexec libgcrypt libgnome libnotify + lzip lzma + lzop makedeb mkdirp mpass diff --git a/.travis.yml b/.travis.yml index b514f5a3ad8..a2c96c21c6d 100755 --- a/.travis.yml +++ b/.travis.yml @@ -7,6 +7,9 @@ osx_image: xcode7 dist: trusty sudo: required +services: + - docker + env: - NODE_VERSION=4 - NODE_VERSION=6 @@ -14,28 +17,16 @@ env: language: c cache: - apt: true - bundler: true directories: - node_modules - test/testApp/node_modules - $HOME/.electron - $HOME/.cache/fpm -addons: - apt: - sources: - - mono - packages: - - icnsutils - - graphicsmagick - - mono-devel - before_install: - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update ; fi - - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install gnu-tar dpkg libicns graphicsmagick git-lfs; fi + - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install gnu-tar dpkg libicns graphicsmagick git-lfs lzip; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then git lfs pull; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then test/install-linux-dependencies.sh; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then curl -L https://github.com/github/git-lfs/releases/download/v1.2.0/git-lfs-linux-amd64-1.2.0.tar.gz | tar -xz; fi - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then git-lfs-1.2.0/git-lfs pull; fi @@ -46,7 +37,8 @@ install: - npm prune script: -- npm run test +- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then npm run test ; fi +- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then docker run --rm -v ${PWD}:/project -v ~/.electron:/root/.electron electronuserland/electron-builder:wine /test.sh ; fi after_success: - node out/cleanup.js diff --git a/docker/Dockerfile b/docker/Dockerfile index 3aed0a6fa1d..97344e3dfc2 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -3,7 +3,7 @@ FROM buildpack-deps:xenial-curl # rpm is required for FPM to build rpm package RUN apt-get update -y && \ -apt-get install --no-install-recommends -y build-essential icnsutils graphicsmagick gcc-multilib g++-multilib libgnome-keyring-dev zip rpm && \ +apt-get install --no-install-recommends -y bsdtar build-essential autoconf libssl-dev icnsutils graphicsmagick gcc-multilib g++-multilib libgnome-keyring-dev zip lzip rpm && \ apt-get clean && \ rm -rf /var/lib/apt/lists/* @@ -42,4 +42,76 @@ COPY test.sh /test.sh WORKDIR /project ENV DEBUG_COLORS true -ENV FORCE_COLOR true \ No newline at end of file +ENV FORCE_COLOR true + +# copied from https://github.com/docker-library/ruby/blob/0b94677b368947b64dcdcb312cd81ba946df3676/2.3/Dockerfile + +# skip installing gem documentation +RUN mkdir -p /usr/local/etc \ + && { \ + echo 'install: --no-document'; \ + echo 'update: --no-document'; \ + } >> /usr/local/etc/gemrc + +ENV RUBY_MAJOR 2.3 +ENV RUBY_VERSION 2.3.1 +ENV RUBY_DOWNLOAD_SHA256 b87c738cb2032bf4920fef8e3864dc5cf8eae9d89d8d523ce0236945c5797dcd +ENV RUBYGEMS_VERSION 2.6.4 + +# some of ruby's build scripts are written in ruby +# we purge this later to make sure our final image uses what we just built +RUN set -ex \ + && buildDeps=' \ + bison \ + libgdbm-dev \ + ruby \ + ' \ + && apt-get update \ + && apt-get install -y --no-install-recommends $buildDeps \ + && rm -rf /var/lib/apt/lists/* \ + && curl -fSL -o ruby.tar.gz "http://cache.ruby-lang.org/pub/ruby/$RUBY_MAJOR/ruby-$RUBY_VERSION.tar.gz" \ + && echo "$RUBY_DOWNLOAD_SHA256 *ruby.tar.gz" | sha256sum -c - \ + && mkdir -p /usr/src/ruby \ + && tar -xzf ruby.tar.gz -C /usr/src/ruby --strip-components=1 \ + && rm ruby.tar.gz \ + && cd /usr/src/ruby \ + && { echo '#define ENABLE_PATH_CHECK 0'; echo; cat file.c; } > file.c.new && mv file.c.new file.c \ + && autoconf \ + && ./configure --disable-install-doc \ + && make -j"$(nproc)" \ + && make install \ + && apt-get purge -y --auto-remove $buildDeps \ + && gem update --system $RUBYGEMS_VERSION \ + && rm -r /usr/src/ruby + +ENV BUNDLER_VERSION 1.12.4 + +RUN gem install bundler --version "$BUNDLER_VERSION" + +# install things globally, for great justice +# and don't create ".bundle" in all our apps +ENV GEM_HOME /usr/local/bundle +ENV BUNDLE_PATH="$GEM_HOME" \ + BUNDLE_BIN="$GEM_HOME/bin" \ + BUNDLE_SILENCE_ROOT_WARNING=1 \ + BUNDLE_APP_CONFIG="$GEM_HOME" +ENV PATH $BUNDLE_BIN:$PATH +RUN mkdir -p "$GEM_HOME" "$BUNDLE_BIN" \ + && chmod 777 "$GEM_HOME" "$BUNDLE_BIN" \ + && mkdir /fpm && curl -L https://github.com/jordansissel/fpm/archive/6e2514df27664912826b4fcd89affa19df0e713b.tar.gz | tar -xz -C /fpm --strip-components 1 && cd /fpm && bundle install && make install && cd .. + +# use fpm commit https://github.com/jordansissel/fpm/commit/6e2514df27664912826b4fcd89affa19df0e713b because of some important unreleased fixes: +# https://github.com/jordansissel/fpm/commit/94be82c0a23c8cd641ab9e60f3eb4a8db445fff0 +# https://github.com/jordansissel/fpm/commit/77b95747b9cc01ca420ee24084a449b3ac19e6d5 + +# we don't use our bundled fpm because it is better to build ruby & tools for specific platform - not generic. And easy to maintain (update ruby and so on). + +ENV USE_SYSTEM_FPM true + +# fix error /usr/local/bundle/gems/fpm-1.5.0/lib/fpm/package/freebsd.rb:72:in `encode': "\xE2" from ASCII-8BIT to UTF-8 (Encoding::UndefinedConversionError) +# http://jaredmarkell.com/docker-and-locales/ +# http://askubuntu.com/a/601498 +RUN locale-gen en_US.UTF-8 +ENV LANG en_US.UTF-8 +ENV LANGUAGE en_US:en +ENV LC_ALL en_US.UTF-8 \ No newline at end of file diff --git a/docker/readme.md b/docker/readme.md index 423ce2b2da8..edf9c1dcb93 100644 --- a/docker/readme.md +++ b/docker/readme.md @@ -1,18 +1,21 @@ # Development machine +To build Linux: ```sh docker run --rm -ti -v `pwd`:/project -v `pwd`/node_modules/.linux:/project/node_modules -v ~/.electron:/root/.electron electronuserland/electron-builder ``` -Wine: +To build windows: ```sh docker run --rm -ti -v ${PWD}:/project -v ${PWD##*/}-node-modules:/project/node_modules -v ~/.electron:/root/.electron electronuserland/electron-builder:wine ``` +Consider using `/test.sh` to install npm dependencies and run tests. + # CI Server ```sh -docker run --rm -v ${PWD}:/project -v ~/.electron:/root/.electron -v ~/.cache:/root/.cache electronuserland/electron-builder:wine /test.sh +docker run --rm -v ${PWD}:/project -v ~/.electron:/root/.electron electronuserland/electron-builder:wine /test.sh ``` # Build @@ -22,6 +25,10 @@ docker build -t electronuserland/electron-builder docker docker build -t electronuserland/electron-builder:wine docker/wine ``` +Or just `npm run docker-images` + +# Notes + * We use [named data volume](https://madcoda.com/2016/03/docker-named-volume-explained/) instead of mounted host directory to store `node_modules` because NPM is unreliable and NPM team [doesn't want to fix it](https://github.com/npm/npm/issues/3565). `${PWD##*/}-node-modules` is used as name of data volume — it is your current directory name (e. g. `foo`) and suffix `-node-modules`. diff --git a/docs/Multi Platform Build.md b/docs/Multi Platform Build.md index fbc2991dd7f..44de072c4b0 100755 --- a/docs/Multi Platform Build.md +++ b/docs/Multi Platform Build.md @@ -25,19 +25,25 @@ To build app in distributable format for Linux on OS X: brew install gnu-tar libicns graphicsmagick ``` +To build rpm: `brew install rpm`. + ## Linux To build app in distributable format for Linux: ``` -sudo apt-get install icnsutils graphicsmagick xz-utils +sudo apt-get install --no-install-recommends -y icnsutils graphicsmagick xz-utils ``` +To build rpm: `sudo apt-get install --no-install-recommends -y rpm`. + +To build pacman: `sudo apt-get install --no-install-recommends -y bsdtar`. + To build app in distributable format for Windows on Linux: * Install Wine (1.8+ is required): ``` sudo add-apt-repository ppa:ubuntu-wine/ppa -y sudo apt-get update - sudo apt-get install wine1.8 -y + sudo apt-get install --no-install-recommends -y wine1.8 ``` * Install [Mono](http://www.mono-project.com/docs/getting-started/install/linux/#usage) (4.2+ is required): @@ -46,18 +52,18 @@ To build app in distributable format for Windows on Linux: sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 3FA7E0328081BFF6A14DA29AA6A19B38D3D831EF echo "deb http://download.mono-project.com/repo/debian wheezy main" | sudo tee /etc/apt/sources.list.d/mono-xamarin.list sudo apt-get update - sudo apt-get install mono-devel ca-certificates-mono -y + sudo apt-get install --no-install-recommends -y mono-devel ca-certificates-mono ``` * Install zip. ``` - apt-get install zip + apt-get install --no-install-recommends -y zip ``` To build app in 32 bit from a machine with 64 bit: ``` -sudo apt-get install -y gcc-multilib g++-multilib +sudo apt-get install --no-install-recommends -y gcc-multilib g++-multilib ``` ### Travis Linux diff --git a/docs/Options.md b/docs/Options.md index ece85f6f0b9..5f54f3f0508 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -71,7 +71,7 @@ See all [appdmg options](https://www.npmjs.com/package/appdmg#json-specification | --- | --- | icon | The path to icon, which will be shown when mounted (default: `build/icon.icns`). | background |

The path to background (default: build/background.png if exists). The resolution of this file determines the resolution of the installer window. If background is not specified, use window.size, see [specification](https://github.com/LinusU/node-appdmg#json-specification).

-| target | Target package type: list of `default`, `dmg`, `zip`, `mas`, `7z`. Defaults to `default` (dmg and zip for Squirrel.Mac). +| target | Target package type: list of `default`, `dmg`, `zip`, `mas`, `7z`, `tar.xz`, `tar.gz`, `tar.bz2`, `tar.7z`. Defaults to `default` (dmg and zip for Squirrel.Mac). | identity |

The name of certificate to use when signing. Consider using environment variables [CSC_LINK or CSC_NAME](https://github.com/electron-userland/electron-builder/wiki/Code-Signing). MAS installer identity is specified in the [.build.mas](#MasBuildOptions-identity).

| entitlements |

The path to entitlements file for signing the app. build/osx.entitlements will be used if exists (it is a recommended way to set). MAS entitlements is specified in the [.build.mas](#MasBuildOptions-entitlements).

| entitlementsInherit |

The path to child entitlements which inherit the security settings for signing frameworks and bundles of a distribution. build/osx.inherit.entitlements will be used if exists (it is a recommended way to set). Otherwise [default](https://github.com/electron-userland/electron-osx-sign/blob/master/default.darwin.inherit.entitlements).

This option only applies when signing with entitlements provided.

@@ -107,6 +107,7 @@ MAS (Mac Application Store) specific options (in addition to `build.osx`). | vendor | The vendor. Defaults to [author](#AppMetadata-author). | compression | *deb-only.* The compression type, one of `gz`, `bzip2`, `xz` (default: `xz`). | depends | Package dependencies. Defaults to `["libappindicator1", "libnotify-bin"]`. +| target |

Target package type: list of default, deb, rpm, freebsd, pacman, p5p, apk, 7z, zip, tar.xz, tar.lz, tar.gz, tar.bz2. Defaults to default (deb).

Only deb is tested. Feel free to file issues for rpm and other package formats.

## `.directories` diff --git a/package.json b/package.json index 9e98ff3ab9d..577da77fe52 100644 --- a/package.json +++ b/package.json @@ -14,13 +14,12 @@ "install-app-deps": "./out/install-app-deps.js" }, "scripts": { - "compile": "npm run compile-production && npm run compile-test", + "compile": "npm run whitespace && npm run compile-production && npm run compile-test", "compile-production": "tsconfig -i 2 && ts-babel", "compile-test": "tsconfig -i 2 test && ts-babel test", "lint": "tslint src/*.ts test/src/*.ts", "pretest": "npm run compile && npm run lint", "test": "node ./test/out/helpers/runTests.js", - "ci-test": "git-lfs pull && npm install && npm prune && npm run test", "semantic-release": "semantic-release pre && npm publish && semantic-release post", "//": "Update wiki if docs changed. Update only if functionalily are generally available (latest release, not next)", "update-wiki": "git subtree split -b wiki --prefix docs/ && git push wiki wiki:master", @@ -70,7 +69,7 @@ "electron-packager-tf": "~7.1.0", "electron-winstaller-fixed": "~2.8.3", "fs-extra-p": "^1.0.1", - "globby": "^4.0.0", + "globby": "^4.1.0", "hosted-git-info": "^2.1.5", "image-size": "^0.5.0", "lodash.template": "^4.2.5", @@ -79,11 +78,10 @@ "progress-stream": "^1.2.0", "read-package-json": "^2.0.4", "signcode-tf": "^0.6.3", - "source-map-support": "^0.4.0", - "tmp": "0.0.28" + "source-map-support": "^0.4.0" }, "optionalDependencies": { - "appdmg": "^0.4.3" + "appdmg": "^0.4.5" }, "config": { "pre-git": { @@ -105,11 +103,11 @@ "plist": "^1.2.0", "pre-git": "^3.8.4", "semantic-release": "^6.2.2", - "should": "^8.3.1", + "should": "^8.4.0", "ts-babel": "^0.8.6", "tsconfig-glob": "^0.4.3", - "tslint": "3.10.2", - "typescript": "1.9.0-dev.20160515", + "tslint": "3.10.0-dev.2", + "typescript": "1.9.0-dev.20160520-1.0", "whitespace": "^2.0.0" }, "babel": { diff --git a/src/fpmDownload.ts b/src/fpmDownload.ts index ece9d01d704..7f41c70f13e 100644 --- a/src/fpmDownload.ts +++ b/src/fpmDownload.ts @@ -1,4 +1,4 @@ -import { statOrNull, spawn, debug, debug7z } from "./util" +import { statOrNull, spawn, debug, debug7zArgs, getTempName } from "./util" import { writeFile, rename, remove, unlink, emptyDir } from "fs-extra-p" import { download } from "./httpRequest" import { path7za } from "7zip-bin" @@ -9,12 +9,6 @@ import { Promise as BluebirdPromise } from "bluebird" //noinspection JSUnusedLocalSymbols const __awaiter = require("./awaiter") -let tmpDirCounter = 0 - -function getTempName(prefix?: string | n): string { - return `${prefix == null ? "" : prefix + "-"}${process.pid}-${tmpDirCounter++}-${Date.now()}` -} - const versionToPromise = new Map>() // can be called in parallel, all calls for the same version will get the same promise - will be downloaded only once @@ -55,15 +49,7 @@ async function doDownloadFpm(version: string, osAndArch: string): Promise void) => void) => void>_tpmDir) const installPrefix = "/opt" export class LinuxPackager extends PlatformPackager { - private readonly debOptions: LinuxBuildOptions + private readonly buildOptions: LinuxBuildOptions private readonly packageFiles: Promise> private readonly scriptFiles: Promise> private readonly fpmPath: Promise - constructor(info: BuildInfo) { + constructor(info: BuildInfo, cleanupTasks: Array<() => Promise>) { super(info) - this.debOptions = Object.assign({ + this.buildOptions = Object.assign({ name: this.metadata.name, description: this.metadata.description, }, this.customBuildOptions) if (this.options.dist) { - const tempDir = tmpDir({ - unsafeCleanup: true, - prefix: "electron-builder-" - }) - this.packageFiles = this.computePackageFiles(tempDir) - this.scriptFiles = this.createScripts(tempDir) - - if (process.platform !== "win32" && process.env.USE_SYSTEM_FPM !== "true") { - this.fpmPath = downloadFpm(process.platform === "darwin" ? "1.5.0-1" : "1.5.0-2.3.1", process.platform === "darwin" ? "osx" : `linux-x86${process.arch === "ia32" ? "" : "_64"}`) + const tempDir = path.join(tmpdir(), getTempName("electron-builder-linux")) + const tempDirPromise = emptyDir(tempDir) + .then(() => { + cleanupTasks.push(() => remove(tempDir)) + return tempDir + }) + this.packageFiles = this.computePackageFiles(tempDirPromise) + this.scriptFiles = this.createScripts(tempDirPromise) + + if (process.platform === "win32" || process.env.USE_SYSTEM_FPM === "true") { + this.fpmPath = BluebirdPromise.resolve("fpm") } else { - this.fpmPath = BluebirdPromise.resolve("fpm") + this.fpmPath = downloadFpm(process.platform === "darwin" ? "1.5.0-1" : "1.5.0-2.3.1", process.platform === "darwin" ? "osx" : `linux-x86${process.arch === "ia32" ? "" : "_64"}`) } } } + protected get supportedTargets(): Array { + return ["deb", "rpm", "sh", "freebsd", "pacman", "apk", "p5p"] + } + get platform() { return Platform.LINUX } @@ -69,15 +74,23 @@ export class LinuxPackager extends PlatformPackager { await this.doPack(this.computePackOptions(outDir, arch), outDir, appOutDir, arch, this.customBuildOptions) if (this.options.dist) { + for (let target of this.targets) { + if (target === "zip" || target === "7z" || target.startsWith("tar.")) { + const destination = path.join(outDir, `${this.metadata.name}-${this.metadata.version}${archSuffix(arch)}.${target}`) + postAsyncTasks.push(this.archiveApp(target, appOutDir, destination) + .then(() => this.dispatchArtifactCreated(destination))) + } + } + postAsyncTasks.push(this.packageInDistributableFormat(outDir, appOutDir, arch)) } } private async computeDesktop(tempDir: string): Promise> { const tempFile = path.join(tempDir, this.appName + ".desktop") - await outputFile(tempFile, this.debOptions.desktop || `[Desktop Entry] + await outputFile(tempFile, this.buildOptions.desktop || `[Desktop Entry] Name=${this.appName} -Comment=${this.debOptions.description} +Comment=${this.buildOptions.description} Exec="${installPrefix}/${this.appName}/${this.appName}" Terminal=false Type=Application @@ -168,26 +181,30 @@ Icon=${this.metadata.name} const templateOptions = Object.assign({ // old API compatibility executable: this.appName, - }, this.debOptions) + }, this.buildOptions) - const afterInstallTemplate = this.debOptions.afterInstall || path.join(defaultTemplatesDir, "after-install.tpl") + const afterInstallTemplate = this.buildOptions.afterInstall || path.join(defaultTemplatesDir, "after-install.tpl") const afterInstallFilePath = writeConfigFile(tempDir, afterInstallTemplate, templateOptions) - const afterRemoveTemplate = this.debOptions.afterRemove || path.join(defaultTemplatesDir, "after-remove.tpl") + const afterRemoveTemplate = this.buildOptions.afterRemove || path.join(defaultTemplatesDir, "after-remove.tpl") const afterRemoveFilePath = writeConfigFile(tempDir, afterRemoveTemplate, templateOptions) return await BluebirdPromise.all([afterInstallFilePath, afterRemoveFilePath]) } - async packageInDistributableFormat(outDir: string, appOutDir: string, arch: string): Promise { - return await this.buildDeb(this.debOptions, outDir, appOutDir, arch) - .then(it => this.dispatchArtifactCreated(it)) + protected async packageInDistributableFormat(outDir: string, appOutDir: string, arch: string): Promise { + // todo fix fpm - if we run in parallel, get strange tar errors + for (let target of this.targets) { + target = target === "default" ? "deb" : target + if (target !== "zip" && target !== "7z" && !target.startsWith("tar.")) { + const destination = path.join(outDir, `${this.metadata.name}-${this.metadata.version}${archSuffix(arch)}.${target}`) + await this.buildPackage(destination, target, this.buildOptions, appOutDir, arch) + .then(() => this.dispatchArtifactCreated(destination)) + } + } } - private async buildDeb(options: LinuxBuildOptions, outDir: string, appOutDir: string, arch: string): Promise { - const archName = arch === "ia32" ? "i386" : "amd64" - const target = "deb" - const destination = path.join(outDir, `${this.metadata.name}-${this.metadata.version}-${archName}.${target}`) + private async buildPackage(destination: string, target: string, options: LinuxBuildOptions, appOutDir: string, arch: string): Promise { const scripts = await this.scriptFiles const projectUrl = await this.computePackageUrl() @@ -196,24 +213,35 @@ Icon=${this.metadata.name} } const author = options.maintainer || `${this.metadata.author.name} <${this.metadata.author.email}>` + const synopsis = options.synopsis const args = [ "-s", "dir", "-t", target, - "--architecture", archName, - "--rpm-os", "linux", + "--architecture", arch === "ia32" ? "i386" : "amd64", "--name", this.metadata.name, "--force", "--after-install", scripts[0], "--after-remove", scripts[1], - "--description", `${options.synopsis || ""}\n ${this.debOptions.description}`, + "--description", smarten(target === "rpm" ? this.buildOptions.description! : `${synopsis || ""}\n ${this.buildOptions.description}`), "--maintainer", author, "--vendor", options.vendor || author, "--version", this.metadata.version, "--package", destination, - "--deb-compression", options.compression || (this.devMetadata.build.compression === "store" ? "gz" : "xz"), "--url", projectUrl, ] + if (target === "deb") { + args.push("--deb-compression", options.compression || (this.devMetadata.build.compression === "store" ? "gz" : "xz")) + } + else if (target === "rpm") { + // args.push("--rpm-compression", options.compression || (this.devMetadata.build.compression === "store" ? "none" : "xz")) + args.push("--rpm-os", "linux") + + if (synopsis != null) { + args.push("--rpm-summary", smarten(synopsis)) + } + } + let depends = options.depends if (depends == null) { depends = ["libappindicator1", "libnotify-bin"] @@ -239,7 +267,6 @@ Icon=${this.metadata.name} args.push(`${appOutDir}/=${installPrefix}/${this.appName}`) args.push(...(await this.packageFiles)!) await exec(await this.fpmPath, args) - return destination } } diff --git a/src/metadata.ts b/src/metadata.ts index 81d1ef2cece..e9f4eaa482e 100755 --- a/src/metadata.ts +++ b/src/metadata.ts @@ -170,7 +170,7 @@ export interface OsXBuildOptions extends PlatformSpecificBuildOptions { readonly background?: string | null /* - Target package type: list of `default`, `dmg`, `zip`, `mas`, `7z`. Defaults to `default` (dmg and zip for Squirrel.Mac). + Target package type: list of `default`, `dmg`, `zip`, `mas`, `7z`, `tar.xz`, `tar.gz`, `tar.bz2`, `tar.7z`. Defaults to `default` (dmg and zip for Squirrel.Mac). */ readonly target?: Array | null @@ -261,7 +261,7 @@ export interface WinBuildOptions extends PlatformSpecificBuildOptions { /* ### `.build.linux` */ -export interface LinuxBuildOptions { +export interface LinuxBuildOptions extends PlatformSpecificBuildOptions { /* As [description](#AppMetadata-description) from application package.json, but allows you to specify different for Linux. */ @@ -300,6 +300,13 @@ export interface LinuxBuildOptions { Package dependencies. Defaults to `["libappindicator1", "libnotify-bin"]`. */ readonly depends?: string[] | null + + /* + Target package type: list of `default`, `deb`, `rpm`, `freebsd`, `pacman`, `p5p`, `apk`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`. Defaults to `default` (`deb`). + + Only `deb` is tested. Feel free to file issues for `rpm` and other package formats. + */ + readonly target?: Array | null } /* @@ -324,6 +331,8 @@ export interface MetadataDirectories { export interface PlatformSpecificBuildOptions { readonly extraResources?: Array | null + + readonly target?: Array | null } export class Platform { diff --git a/src/osxPackager.ts b/src/osxPackager.ts index 43c17c7894a..b5aa756933c 100644 --- a/src/osxPackager.ts +++ b/src/osxPackager.ts @@ -1,10 +1,9 @@ -import { PlatformPackager, BuildInfo, normalizeTargets } from "./platformPackager" +import { PlatformPackager, BuildInfo } from "./platformPackager" import { Platform, OsXBuildOptions, MasBuildOptions } from "./metadata" import * as path from "path" import { Promise as BluebirdPromise } from "bluebird" -import { log, debug, debug7z, spawn, statOrNull, warn } from "./util" +import { log, debug, statOrNull, warn } from "./util" import { createKeychain, deleteKeychain, CodeSigningInfo, generateKeychainName } from "./codeSign" -import { path7za } from "7zip-bin" import deepAssign = require("deep-assign") import { sign, flat, BaseSignOptions, SignOptions, FlatOptions } from "electron-osx-sign-tf" import { readdir } from "fs-extra-p" @@ -15,8 +14,6 @@ const __awaiter = require("./awaiter") export default class OsXPackager extends PlatformPackager { codeSigningInfo: Promise - readonly targets: Array - readonly resourceList: Promise> constructor(info: BuildInfo, cleanupTasks: Array<() => Promise>) { @@ -31,16 +28,6 @@ export default class OsXPackager extends PlatformPackager { this.codeSigningInfo = BluebirdPromise.resolve(null) } - const targets = normalizeTargets(this.customBuildOptions.target) - if (targets != null) { - for (let target of targets) { - if (target !== "default" && target !== "dmg" && target !== "zip" && target !== "mas" && target !== "7z") { - throw new Error("Unknown target: " + target) - } - } - } - this.targets = targets == null ? ["default"] : targets - this.resourceList = readdir(this.buildResourcesDir) } @@ -48,6 +35,10 @@ export default class OsXPackager extends PlatformPackager { return Platform.OSX } + protected get supportedTargets(): Array { + return ["dmg", "mas"] + } + async pack(outDir: string, arch: string, postAsyncTasks: Array>): Promise { const packOptions = this.computePackOptions(outDir, arch) let nonMasPromise: Promise | null = null @@ -217,46 +208,12 @@ export default class OsXPackager extends PlatformPackager { log("Creating OS X " + format) // for default we use mac to be compatible with Squirrel.Mac const classifier = target === "default" ? "mac" : "osx" - promises.push(this.archiveApp(appOutDir, format, classifier) - .then(it => this.dispatchArtifactCreated(it, `${this.metadata.name}-${this.metadata.version}-${classifier}.${format}`))) + // we use app name here - see https://github.com/electron-userland/electron-builder/pull/204 + const outFile = path.join(appOutDir, `${this.appName}-${this.metadata.version}-${classifier}.${format}`) + promises.push(this.archiveApp(format, appOutDir, outFile) + .then(() => this.dispatchArtifactCreated(outFile, `${this.metadata.name}-${this.metadata.version}-${classifier}.${format}`))) } } return BluebirdPromise.all(promises) } - - private archiveApp(outDir: string, format: string, classifier: string): Promise { - const args = ["a", "-bd"] - if (debug7z.enabled) { - args.push("-bb3") - } - else if (!debug.enabled) { - args.push("-bb0") - } - - const compression = this.devMetadata.build.compression - const storeOnly = compression === "store" - if (format === "zip" || storeOnly) { - args.push("-mm=" + (storeOnly ? "Copy" : "Deflate")) - } - if (compression === "maximum") { - // http://superuser.com/a/742034 - //noinspection SpellCheckingInspection - if (format === "zip") { - args.push("-mfb=258", "-mpass=15") - } - else if (format === "7z") { - args.push("-m0=lzma2", "-mx=9", "-mfb=64", "-md=32m", "-ms=on") - } - } - - // we use app name here - see https://github.com/electron-userland/electron-builder/pull/204 - const resultPath = `${this.appName}-${this.metadata.version}-${classifier}.${format}` - args.push(resultPath, this.appName + ".app") - - return spawn(path7za, args, { - cwd: outDir, - stdio: ["ignore", debug.enabled ? "inherit" : "ignore", "inherit"], - }) - .thenReturn(path.join(outDir, resultPath)) - } } \ No newline at end of file diff --git a/src/packager.ts b/src/packager.ts index 325cde45b3c..158fe2d7793 100644 --- a/src/packager.ts +++ b/src/packager.ts @@ -117,10 +117,10 @@ export class Packager implements BuildInfo { } case Platform.LINUX: - return new (require("./linuxPackager").LinuxPackager)(this) + return new (require("./linuxPackager").LinuxPackager)(this, cleanupTasks) default: - throw new Error("Unknown platform: " + platform) + throw new Error(`Unknown platform: ${platform}`) } } diff --git a/src/platformPackager.ts b/src/platformPackager.ts index 079adccc19e..2a3257111a9 100644 --- a/src/platformPackager.ts +++ b/src/platformPackager.ts @@ -5,18 +5,31 @@ import { Promise as BluebirdPromise } from "bluebird" import * as path from "path" import packager = require("electron-packager-tf") import globby = require("globby") -import { copy } from "fs-extra-p" -import { statOrNull, use } from "./util" +import { copy, unlink } from "fs-extra-p" +import { statOrNull, use, spawn, debug7zArgs, debug } from "./util" import { Packager } from "./packager" import deepAssign = require("deep-assign") import { listPackage, statFile } from "asar" import ElectronPackagerOptions = ElectronPackager.ElectronPackagerOptions +import { path7za } from "7zip-bin" //noinspection JSUnusedLocalSymbols const __awaiter = require("./awaiter") const pack = BluebirdPromise.promisify(packager) +class CompressionDescriptor { + constructor(public flag: string, public env: string, public minLevel: string, public maxLevel: string = "-9") { + } +} + +const extToCompressionDescriptor: { [key: string]: CompressionDescriptor; } = { + "tar.xz": new CompressionDescriptor("--xz", "XZ_OPT", "-0", "-9e"), + "tar.lz": new CompressionDescriptor("--lzip", "LZOP", "-0"), + "tar.gz": new CompressionDescriptor("--gz", "GZIP", "-1"), + "tar.bz2": new CompressionDescriptor("--bzip2", "BZIP2", "-1"), +} + export interface PackagerOptions { arch?: string | null @@ -76,6 +89,8 @@ export abstract class PlatformPackager readonly appName: string + readonly targets: Array + public abstract get platform(): Platform constructor(protected info: BuildInfo) { @@ -87,12 +102,25 @@ export abstract class PlatformPackager this.buildResourcesDir = path.resolve(this.projectDir, this.relativeBuildResourcesDirname) this.customBuildOptions = (info.devMetadata.build)[this.platform.buildConfigurationKey] || Object.create(null) this.appName = getProductName(this.metadata, this.devMetadata) + + const targets = normalizeTargets(this.customBuildOptions.target) + if (targets != null) { + const supportedTargets = this.supportedTargets.concat("default", "zip", "7z", "tar.xz", "tar.lz", "tar.gz", "tar.bz2") + for (let target of targets) { + if (!supportedTargets.includes(target)) { + throw new Error("Unknown target: " + target) + } + } + } + this.targets = targets == null ? ["default"] : targets } protected get relativeBuildResourcesDirname() { return use(this.devMetadata.directories, it => it!.buildResources) || "build" } + protected abstract get supportedTargets(): Array + protected computeAppOutDir(outDir: string, arch: string): string { return path.join(outDir, `${this.appName}-${this.platform.nodeName}-${arch}`) } @@ -136,7 +164,7 @@ export abstract class PlatformPackager tmpdir: false, "version-string": { CompanyName: this.metadata.author.name, - FileDescription: this.metadata.description, + FileDescription: smarten(this.metadata.description), ProductName: this.appName, InternalName: this.appName, } @@ -271,6 +299,74 @@ export abstract class PlatformPackager throw new Error(`Application entry file ${mainFile} could not be found in package. Seems like a wrong configuration.`) } } + + protected async archiveApp(format: string, appOutDir: string, outFile: string): Promise { + const compression = this.devMetadata.build.compression + const storeOnly = compression === "store" + + const fileToArchive = this.platform === Platform.OSX ? path.join(appOutDir, `${this.appName}.app`) : appOutDir + const baseDir = path.dirname(fileToArchive) + if (format.startsWith("tar.")) { + // we don't use 7z here - develar: I spent a lot of time making pipe working - but it works on OS X and often hangs on Linux (even if use pipe-io lib) + // and in any case it is better to use system tools (in the light of docker - it is not problem for user because we provide complete docker image). + const info = extToCompressionDescriptor[format] + let tarEnv = process.env + if (compression != null && compression !== "normal") { + tarEnv = Object.assign({}, process.env) + tarEnv[info.env] = storeOnly ? info.minLevel : info.maxLevel + } + + await spawn(process.platform === "darwin" ? "/usr/local/opt/gnu-tar/libexec/gnubin/tar" : "tar", [info.flag, "-cf", outFile, fileToArchive], { + cwd: baseDir, + stdio: ["ignore", debug.enabled ? "inherit" : "ignore", "inherit"], + env: tarEnv + }) + return + } + + const args = debug7zArgs("a") + if (compression === "maximum") { + if (format === "7z" || format.endsWith(".7z")) { + args.push("-mx=9", "-mfb=64", "-md=32m", "-ms=on") + } + else if (format === "zip") { + // http://superuser.com/a/742034 + //noinspection SpellCheckingInspection + args.push("-mfb=258", "-mpass=15") + } + else { + args.push("-mx=9") + } + } + else if (storeOnly) { + if (format !== "zip") { + args.push("-mx=1") + } + } + + // remove file before - 7z doesn't overwrite file, but update + try { + await unlink(outFile) + } + catch (e) { + // ignore + } + + if (format === "zip" || storeOnly) { + args.push("-mm=" + (storeOnly ? "Copy" : "Deflate")) + } + + args.push(outFile, fileToArchive) + + await spawn(path7za, args, { + cwd: baseDir, + stdio: ["ignore", debug.enabled ? "inherit" : "ignore", "inherit"], + }) + } +} + +export function archSuffix(arch: string) { + return arch === "x64" ? "" : `-${arch}` } export interface ArtifactCreated { @@ -288,3 +384,17 @@ export function normalizeTargets(targets: Array | string | null | undefi return (Array.isArray(targets) ? targets : [targets]).map(it => it.toLowerCase().trim()) } } + +// fpm bug - rpm build --description is not escaped, well... decided to replace quite to smart quote +// http://leancrew.com/all-this/2010/11/smart-quotes-in-javascript/ +export function smarten(s: string): string { + // opening singles + s = s.replace(/(^|[-\u2014\s(\["])'/g, "$1\u2018") + // closing singles & apostrophes + s = s.replace(/'/g, "\u2019") + // opening doubles + s = s.replace(/(^|[-\u2014/\[(\u2018\s])"/g, "$1\u201c") + // closing doubles + s = s.replace(/"/g, "\u201d") + return s +} \ No newline at end of file diff --git a/src/util.ts b/src/util.ts index 9e869470d9b..3352847bd89 100644 --- a/src/util.ts +++ b/src/util.ts @@ -92,18 +92,33 @@ export function exec(file: string, args?: Array | null, options?: ExecOp }) } -export function spawn(command: string, args?: Array | null, options?: SpawnOptions, processConsumer?: (it: ChildProcess, reject: (error: Error) => void) => void): BluebirdPromise { - const notNullArgs = args || [] +export function doSpawn(command: string, args: Array, options?: SpawnOptions): ChildProcess { if (debug.enabled) { - debug(`Spawning ${command} ${notNullArgs.join(" ")}`) + debug(`Spawning ${command} ${args.join(" ")}`) } + return _spawn(command, args, options) +} +export function spawn(command: string, args?: Array | null, options?: SpawnOptions): BluebirdPromise { return new BluebirdPromise((resolve, reject) => { - const p = _spawn(command, notNullArgs, options) - p.on("error", reject) - p.on("close", (code: number) => code === 0 ? resolve() : reject(new Error(command + " exited with code " + code))) - if (processConsumer != null) { - processConsumer(p, reject) + const notNullArgs = args || [] + const childProcess = doSpawn(command, notNullArgs, options) + handleProcess("close", childProcess, command, resolve, reject) + }) +} + +export function handleProcess(event: string, childProcess: ChildProcess, command: string, resolve: ((value?: any) => void) | null, reject: (reason?: any) => void) { + childProcess.on("error", reject) + childProcess.on(event, (code: number) => { + if (debug.enabled) { + debug(`${command} (${childProcess.pid}) exited with code ${code}`) + } + + if (code !== 0) { + reject(new Error(`${command} exited with code ${code}`)) + } + else if (resolve != null) { + resolve() } }) } @@ -172,4 +187,21 @@ export async function computeDefaultAppDirectory(projectDir: string, userAppDir: export function use(value: T | null, task: (it: T) => R): R | null { return value == null ? null : task(value) +} + +export function debug7zArgs(command: "a" | "x"): Array { + const args = [command, "-bd"] + if (debug7z.enabled) { + args.push("-bb3") + } + else if (!debug.enabled) { + args.push("-bb0") + } + return args +} + +let tmpDirCounter = 0 + +export function getTempName(prefix?: string | n): string { + return `${prefix == null ? "" : prefix + "-"}${process.pid}-${tmpDirCounter++}-${Date.now()}` } \ No newline at end of file diff --git a/src/winPackager.ts b/src/winPackager.ts index 5e0070b950e..dbbcc200d19 100644 --- a/src/winPackager.ts +++ b/src/winPackager.ts @@ -1,6 +1,6 @@ import { downloadCertificate } from "./codeSign" import { Promise as BluebirdPromise } from "bluebird" -import { PlatformPackager, BuildInfo } from "./platformPackager" +import { PlatformPackager, BuildInfo, smarten, archSuffix } from "./platformPackager" import { Platform, WinBuildOptions } from "./metadata" import * as path from "path" import { log, statOrNull, warn } from "./util" @@ -45,6 +45,10 @@ export class WinPackager extends PlatformPackager { return Platform.WINDOWS } + protected get supportedTargets(): Array { + return [] + } + private async getValidIconPath(): Promise { const iconPath = path.join(this.buildResourcesDir, "icon.ico") await checkIcon(iconPath) @@ -137,7 +141,7 @@ export class WinPackager extends PlatformPackager { appDirectory: appOutDir, outputDirectory: installerOutDir, version: this.metadata.version, - description: this.metadata.description, + description: smarten(this.metadata.description), authors: this.metadata.author.name, iconUrl: iconUrl, setupIcon: await this.iconPath, @@ -235,7 +239,7 @@ function isIco(buffer: Buffer): boolean { } export function computeDistOut(outDir: string, arch: string): string { - return path.join(outDir, `win${arch === "x64" ? "" : `-${arch}` }`) + return path.join(outDir, `win${archSuffix(arch)}`) } function checkConflictingOptions(options: any) { diff --git a/test/fixtures/test-app-one/index.js b/test/fixtures/test-app-one/index.js index 11a4e82d04c..dd2fbe001c6 100644 --- a/test/fixtures/test-app-one/index.js +++ b/test/fixtures/test-app-one/index.js @@ -1,6 +1,6 @@ 'use strict' -const app = require('app') +const app = require('electron').app // this should be placed at top of main.js to handle setup events quickly if (handleSquirrelEvent()) { diff --git a/test/install-linux-dependencies.sh b/test/install-linux-dependencies.sh deleted file mode 100755 index 2544d643b20..00000000000 --- a/test/install-linux-dependencies.sh +++ /dev/null @@ -1,6 +0,0 @@ -wget -q -O - https://dl.google.com/linux/linux_signing_key.pub | sudo apt-key add - - -sudo dpkg --add-architecture i386 -sudo add-apt-repository ppa:ubuntu-wine/ppa -y -sudo apt-get update -sudo apt-get install wine1.8 ca-certificates-mono -y \ No newline at end of file diff --git a/test/src/helpers/avaEx.ts b/test/src/helpers/avaEx.ts index b3e88200e48..e5caa3b3166 100644 --- a/test/src/helpers/avaEx.ts +++ b/test/src/helpers/avaEx.ts @@ -7,6 +7,8 @@ declare module "ava-tf" { export const ifNotCi: typeof test; export const ifNotCiOsx: typeof test; export const ifDevOrWinCi: typeof test; + export const ifWinCi: typeof test; + export const ifDevOrLinuxCi: typeof test; export const ifNotTravis: typeof test; } @@ -45,6 +47,16 @@ Object.defineProperties(test, { get: function () { return !process.env.CI || process.platform === "win32" ? this : this.skip } + }, + "ifDevOrLinuxCi": { + get: function () { + return !process.env.CI || process.platform === "linux" ? this : this.skip + } + }, + "ifWinCi": { + get: function () { + return process.env.CI && process.platform === "win32" ? this : this.skip + } } }) diff --git a/test/src/helpers/packTester.ts b/test/src/helpers/packTester.ts index 1b35ca82341..30830490734 100755 --- a/test/src/helpers/packTester.ts +++ b/test/src/helpers/packTester.ts @@ -106,7 +106,7 @@ async function packAndCheck(projectDir: string, packagerOptions: PackagerOptions await checkOsXResult(packager, packagerOptions, checkOptions, artifacts.get(Platform.OSX)) } else if (platform === Platform.LINUX) { - await checkLinuxResult(projectDir, packager, packagerOptions, checkOptions) + await checkLinuxResult(projectDir, packager, packagerOptions, checkOptions, artifacts.get(Platform.LINUX)) } else if (platform === Platform.WINDOWS) { await checkWindowsResult(packager, packagerOptions, checkOptions, artifacts.get(Platform.WINDOWS)) @@ -114,7 +114,24 @@ async function packAndCheck(projectDir: string, packagerOptions: PackagerOptions } } -async function checkLinuxResult(projectDir: string, packager: Packager, packagerOptions: PackagerOptions, checkOptions: AssertPackOptions) { +async function checkLinuxResult(projectDir: string, packager: Packager, packagerOptions: PackagerOptions, checkOptions: AssertPackOptions, artifacts: Array) { + const customBuildOptions = packager.devMetadata.build.linux + const targets = customBuildOptions == null || customBuildOptions.target == null ? ["default"] : customBuildOptions.target + + function getExpected(): Array { + const result: Array = [] + for (let target of targets) { + result.push(`TestApp-1.1.0.${target === "default" ? "deb" : target}`) + } + return result + } + + assertThat(getFileNames(artifacts)).deepEqual((checkOptions == null || checkOptions.expectedArtifacts == null ? getExpected() : checkOptions.expectedArtifacts.slice()).sort()) + + if (!targets.includes("deb") || !targets.includes("default")) { + return + } + const productName = getProductName(packager.metadata, packager.devMetadata) const expectedContents = expectedLinuxContents.map(it => { if (it === "/opt/TestApp/TestApp") { @@ -143,7 +160,7 @@ async function checkLinuxResult(projectDir: string, packager: Packager, packager Maintainer: "Foo Bar ", Vendor: "Foo Bar ", Package: "testapp", - Description: " \n Test Application (test quite \" #378)", + Description: " \n Test Application (test quite “ #378)", Depends: checkOptions == null || checkOptions.expectedDepends == null ? "libappindicator1, libnotify-bin" : checkOptions.expectedDepends, }) } @@ -200,31 +217,36 @@ async function checkOsXResult(packager: Packager, packagerOptions: PackagerOptio } } +function getFileNames(list: Array): Array { + return list.map(it => path.basename(it.file)).sort() +} + async function checkWindowsResult(packager: Packager, packagerOptions: PackagerOptions, checkOptions: AssertPackOptions, artifacts: Array) { const productName = getProductName(packager.metadata, packager.devMetadata) - function getWinExpected(archSuffix: string) { - return [ + function getExpectedFileNames(archSuffix: string) { + const result = [ `RELEASES`, `${productName} Setup 1.1.0${archSuffix}.exe`, - `TestApp-1.1.0${archSuffix}-full.nupkg`, + `TestApp-1.1.0-full.nupkg`, ] + const buildOptions = packager.devMetadata.build.win + if (buildOptions != null && buildOptions.remoteReleases != null) { + result.push(`${productName}-1.1.0-delta.nupkg`) + } + return result } - const archSuffix = (packagerOptions.arch || process.arch) === "x64" ? "" : "-ia32" - const expected = checkOptions == null || checkOptions.expectedArtifacts == null ? (archSuffix == "" ? getWinExpected(archSuffix) : getWinExpected(archSuffix).concat(getWinExpected(""))) : checkOptions.expectedArtifacts - const filenames = artifacts.map(it => path.basename(it.file)) - assertThat(filenames.slice().sort()).deepEqual(expected.slice().sort()) + const archSuffix = (packagerOptions.arch || process.arch) === "x64" ? "" : "-ia32" + assertThat(getFileNames(artifacts)).deepEqual((checkOptions == null || checkOptions.expectedArtifacts == null ? getExpectedFileNames(archSuffix) : checkOptions.expectedArtifacts.slice()).sort()) if (checkOptions != null && checkOptions.expectedArtifacts != null) { return } - const expectedArtifactNames = expected.slice() - expectedArtifactNames[1] = `TestAppSetup-1.1.0${archSuffix}.exe` assertThat(artifacts.map(it => it.artifactName).filter(it => it != null)).deepEqual([`TestApp-Setup-1.1.0${archSuffix}.exe`]) - const packageFile = path.join(path.dirname(artifacts[0].file), `TestApp-1.1.0${archSuffix}-full.nupkg`) + const packageFile = path.join(path.dirname(artifacts[0].file), `TestApp-1.1.0-full.nupkg`) const unZipper = new DecompressZip(packageFile) const fileDescriptors = await unZipper.getFiles() @@ -257,7 +279,7 @@ async function checkWindowsResult(packager: Packager, packagerOptions: PackagerO Foo Bar https://raw.githubusercontent.com/szwacz/electron-boilerplate/master/resources/windows/icon.ico false - Test Application (test quite \" #378) + Test Application (test quite “ #378) Copyright © ${new Date().getFullYear()} Foo Bar http://foo.example.com diff --git a/test/src/linuxPackagerTest.ts b/test/src/linuxPackagerTest.ts index 1d853c86880..f97f55c116e 100755 --- a/test/src/linuxPackagerTest.ts +++ b/test/src/linuxPackagerTest.ts @@ -7,7 +7,42 @@ import { Platform } from "out" //noinspection JSUnusedLocalSymbols const __awaiter = require("out/awaiter") -test.ifNotWindows("linux", () => assertPack("test-app-one", platform(Platform.LINUX))) +test.ifNotWindows("deb", () => assertPack("test-app-one", platform(Platform.LINUX))) + +test.ifDevOrLinuxCi("rpm", () => assertPack("test-app-one", { + platform: [Platform.LINUX], + devMetadata: { + build: { + linux: { + target: ["rpm"] + } + } + } +})) + +test.ifDevOrLinuxCi("targets", () => assertPack("test-app-one", { + platform: [Platform.LINUX], + devMetadata: { + build: { + linux: { + // "apk" is very slow, don't test for now + target: ["sh", "freebsd", "pacman", "zip", "7z"], + } + } + } +})) + +test.ifDevOrLinuxCi("tar", () => assertPack("test-app-one", { + platform: [Platform.LINUX], + devMetadata: { + build: { + linux: { + // "apk" is very slow, don't test for now + target: ["tar.xz", "tar.lz", "tar.gz", "tar.bz2"], + } + } + } +})) test.ifNotWindows("icons from ICNS", () => assertPack("test-app-one", { platform: [Platform.LINUX], diff --git a/test/src/winPackagerTest.ts b/test/src/winPackagerTest.ts index 307a97122ec..a6e21b7da13 100755 --- a/test/src/winPackagerTest.ts +++ b/test/src/winPackagerTest.ts @@ -15,17 +15,11 @@ const __awaiter = require("out/awaiter") test.ifNotCiOsx("win", () => assertPack("test-app-one", signed({ platform: [Platform.WINDOWS], arch: "x64", - }), - { - expectedArtifacts: [ - "RELEASES", - "TestApp Setup 1.1.0.exe", - "TestApp-1.1.0-full.nupkg" - ], - } + }) )) -test.ifDevOrWinCi("delta", () => assertPack("test-app-one", { +// very slow +test.ifWinCi("delta", () => assertPack("test-app-one", { platform: [Platform.WINDOWS], arch: "ia32", devMetadata: { @@ -35,14 +29,6 @@ test.ifDevOrWinCi("delta", () => assertPack("test-app-one", { } } }, - }, - { - expectedArtifacts: [ - "RELEASES", - "TestApp Setup 1.1.0-ia32.exe", - "TestApp-1.1.0-delta.nupkg", - "TestApp-1.1.0-full.nupkg" - ], } )) diff --git a/test/tsconfig.json b/test/tsconfig.json index 5ce8a55cbd4..e332f4df41b 100755 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -39,7 +39,6 @@ "../typings/lib.es2016.array.include.d.ts", "../typings/main/ambient/mime/mime.d.ts", "../typings/main/ambient/progress/progress.d.ts", - "../typings/main/ambient/tmp/tmp.d.ts", "../typings/main/definitions/chalk/index.d.ts", "../typings/main/definitions/debug/index.d.ts", "../typings/main/definitions/source-map-support/source-map-support.d.ts", diff --git a/tsconfig.json b/tsconfig.json index 92150df1651..e9723562e68 100755 --- a/tsconfig.json +++ b/tsconfig.json @@ -44,7 +44,6 @@ "typings/lib.es2016.array.include.d.ts", "typings/main/ambient/mime/mime.d.ts", "typings/main/ambient/progress/progress.d.ts", - "typings/main/ambient/tmp/tmp.d.ts", "typings/main/definitions/chalk/index.d.ts", "typings/main/definitions/debug/index.d.ts", "typings/main/definitions/source-map-support/source-map-support.d.ts", diff --git a/typings.json b/typings.json index 15bc2a0c3f9..8afa16b4457 100755 --- a/typings.json +++ b/typings.json @@ -1,8 +1,7 @@ { "ambientDependencies": { "mime": "github:DefinitelyTyped/DefinitelyTyped/mime/mime.d.ts#cb5206a8ac1c9a3ddfd126f5ecea6729b2361452", - "progress": "github:DefinitelyTyped/DefinitelyTyped/progress/progress.d.ts#d54b18e0ac3277376700b6026ef9e9e3f380df50", - "tmp": "github:DefinitelyTyped/DefinitelyTyped/tmp/tmp.d.ts#48f20e97bfaf70fc1a9537b38aed98e9749be0ae" + "progress": "github:DefinitelyTyped/DefinitelyTyped/progress/progress.d.ts#d54b18e0ac3277376700b6026ef9e9e3f380df50" }, "dependencies": { "source-map-support": "github:typed-typings/npm-source-map-support#900ed4180a22285bce4bbabc0760427e71a59eca" diff --git a/typings/main/ambient/tmp/tmp.d.ts b/typings/main/ambient/tmp/tmp.d.ts deleted file mode 100644 index c957a40a585..00000000000 --- a/typings/main/ambient/tmp/tmp.d.ts +++ /dev/null @@ -1,46 +0,0 @@ -// Compiled using typings@0.6.8 -// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/48f20e97bfaf70fc1a9537b38aed98e9749be0ae/tmp/tmp.d.ts -// Type definitions for tmp v0.0.28 -// Project: https://www.npmjs.com/package/tmp -// Definitions by: Jared Klopper -// Definitions: https://github.com/borisyankov/DefinitelyTyped - -declare module "tmp" { - export interface TmpFileOptions extends TmpOptions { - mode?: number; - } - - export interface TmpOptions { - prefix?: string; - postfix?: string; - - template?: string; - dir?: string; - tries?: number; - keep?: boolean; - unsafeCleanup?: boolean; - } - - interface SynchrounousResult { - name: string; - fd: number; - removeCallback: () => void; - } - - function file(callback: (err: any, path: string, fd: number, cleanupCallback: () => void) => void): void; - function file(config: TmpFileOptions, callback?: (err: any, path: string, fd: number, cleanupCallback: () => void) => void): void; - - function fileSync(config?: TmpFileOptions): SynchrounousResult; - - export function dir(callback: (err: any, path: string, cleanupCallback: () => void) => void): void; - export function dir(config: TmpFileOptions, callback?: (err: any, path: string, cleanupCallback: () => void) => void): void; - - function dirSync(config?: TmpFileOptions): SynchrounousResult; - - function tmpName(callback: (err: any, path: string) => void): void; - function tmpName(config: TmpOptions, callback?: (err: any, path: string) => void): void; - - function tmpNameSync(config?: TmpOptions): string; - - function setGracefulCleanup(): void; -} \ No newline at end of file diff --git a/typings/node.d.ts b/typings/node.d.ts index 1b24c768aa5..e0e87196746 100644 --- a/typings/node.d.ts +++ b/typings/node.d.ts @@ -5,17 +5,6 @@ // Definitions by: Microsoft TypeScript , DefinitelyTyped // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped -/************************************************ -* * -* Node.js v4.x API * -* * -************************************************/ - -interface Error { - stack?: string; -} - - // compat for TypeScript 1.8 // if you use with --target es3 or --target es5 and use below definitions, // use the lib.es6.d.ts that is bundled with TypeScript 1.8.