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.