diff --git a/.idea/dictionaries/develar.xml b/.idea/dictionaries/develar.xml
index 591cee5671d..bdebf788e4b 100644
--- a/.idea/dictionaries/develar.xml
+++ b/.idea/dictionaries/develar.xml
@@ -5,6 +5,7 @@
appveyorarchsaspx
+ atimeauthenticodeawaiterbintray
diff --git a/.idea/typescript-compiler.xml b/.idea/typescript-compiler.xml
index 88b88fe9a19..498a6a21392 100644
--- a/.idea/typescript-compiler.xml
+++ b/.idea/typescript-compiler.xml
@@ -4,6 +4,7 @@
+
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 73ab9ca57a4..249a2d3ea18 100755
--- a/.travis.yml
+++ b/.travis.yml
@@ -19,7 +19,7 @@ cache:
before_install:
- brew install --ignore-dependencies --force-bottle gnu-tar dpkg libicns graphicsmagick lzip freetype
- brew deps --skip-optional wine | grep -v -e freetype -e libtiff -e libpng -e libtool -e libicns -e jpeg -e gmp | xargs brew install --ignore-dependencies --force-bottle
- - brew install --ignore-dependencies --force-bottle wine mono
+ - brew install --ignore-dependencies --force-bottle wine
- mkdir -p /tmp/git-lfs && curl -L https://github.com/github/git-lfs/releases/download/v1.2.0/git-lfs-$([ "$TRAVIS_OS_NAME" == "linux" ] && echo "linux" || echo "darwin")-amd64-1.2.0.tar.gz | tar -xz -C /tmp/git-lfs --strip-components 1 && /tmp/git-lfs/git-lfs pull
install:
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index dc5902fd6d6..6a11370e375 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -12,7 +12,7 @@ This includes:
- log of the terminal output
- node version
- npm version
-- on which system do you want to create installers (OS X, Windows or Linux)
+- on which system do you want to create installers (MacOS, Windows or Linux)
# Pull Requests
To check that your contributions match the project coding style make sure `npm test` passes.
diff --git a/README.md b/README.md
index 0c01a9dae4b..6a0f56067cb 100755
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
# electron-builder [![npm version](https://img.shields.io/npm/v/electron-builder.svg)](https://npmjs.org/package/electron-builder)
-Complete solution to package and build ready for distribution and "auto update" Electron app for OS X, Windows and Linux.
+Complete solution to package and build ready for distribution and "auto update" Electron app for MacOS, Windows and Linux.
* NPM packages management:
* [Native application dependencies](http://electron.atom.io/docs/latest/tutorial/using-native-node-modules/) compilation (only if [two-package.json project structure](#two-packagejson-structure) used).
@@ -9,9 +9,9 @@ Complete solution to package and build ready for distribution and "auto update"
* [Build version management](https://github.com/electron-userland/electron-builder/wiki/Options#build-version-management).
* Numerous target formats:
* All platforms: `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`.
- * [OS X](https://github.com/electron-userland/electron-builder/wiki/Options#OsXBuildOptions-target): `dmg`, `mas`.
+ * [MacOS](https://github.com/electron-userland/electron-builder/wiki/Options#MacOptions-target): `dmg`, `mas`.
* [Linux](https://github.com/electron-userland/electron-builder/wiki/Options#LinuxBuildOptions-target): `deb`, `rpm`, `freebsd`, `pacman`, `p5p`, `apk`.
- * Windows: Squirrel.Windows. NSIS will be supported soon.
+ * [Windows](https://github.com/electron-userland/electron-builder/wiki/Options#WinBuildOptions-target): NSIS, Squirrel.Windows.
* [Publishing artifacts to GitHub Releases](https://github.com/electron-userland/electron-builder/wiki/Publishing-Artifacts).
[electron-packager](https://github.com/electron-userland/electron-packager) and
@@ -59,9 +59,9 @@ For a production app you need to sign your application, see [Where to buy code s
```
See [options](https://github.com/electron-userland/electron-builder/wiki/Options). This object will be used as a source of [electron-packager](https://www.npmjs.com/package/electron-packager#packageropts-callback) options. You can specify any other options here.
-3. Create directory `build` in the root of the project and put your `background.png` (OS X DMG background), `icon.icns` (OS X app icon) and `icon.ico` (Windows app icon).
+3. Create directory `build` in the root of the project and put your `background.png` (MacOS DMG background), `icon.icns` (MacOS app icon) and `icon.ico` (Windows app icon).
- Linux icon set will be generated automatically on the fly from the OS X `icns` file (or you can put them into the `build/icons` directory — filename must contains size (e.g. `32x32.png`)).
+ Linux icon set will be generated automatically on the fly from the MacOS `icns` file (or you can put them into the `build/icons` directory — filename must contains size (e.g. `32x32.png`)).
4. Add [scripts](https://docs.npmjs.com/cli/run-script) to the development `package.json`:
```json
@@ -80,7 +80,7 @@ Please note — packaged into an asar archive [by default](https://github.com/el
# Auto Update
`electron-builder` produces all required artifacts:
-* `.dmg`: OS X installer, required for OS X user to initial install.
+* `.dmg`: MacOS installer, required for MacOS user to initial install.
* `-mac.zip`: required for Squirrel.Mac.
* `.exe` and `-ia32.exe`: Windows installer, required for Windows user to initial install. Please note — [your app must handle Squirrel.Windows events](https://github.com/electronjs/windows-installer#handling-squirrel-events). See [real example](https://github.com/develar/onshape-desktop-shell/blob/master/src/WinSquirrelStartupEventHandler.ts).
* `.full-nupkg`: required for Squirrel.Windows.
@@ -95,7 +95,7 @@ For windows consider only [distributing 64-bit versions](https://github.com/elec
# CLI Usage
Execute `node_modules/.bin/build --help` to get actual CLI usage guide.
```
---osx, -o Build for OS X [array]
+--mac, -o Build for MacOS [array]
--linux, -l Build for Linux [array]
--win, -w, --windows Build for Windows [array]
--x64 Build for x64 [boolean]
@@ -103,9 +103,9 @@ Execute `node_modules/.bin/build --help` to get actual CLI usage guide.
--publish, -p Publish artifacts (to GitHub Releases), see
https://goo.gl/WMlr4n
[choices: "onTag", "onTagOrDraft", "always", "never"]
---platform The target platform (preferred to use --osx, --win or
+--platform The target platform (preferred to use --mac, --win or
--linux)
- [choices: "osx", "win", "linux", "darwin", "win32", "all"]
+ [choices: "mac", "win", "linux", "darwin", "win32", "all"]
--arch The target arch (preferred to use --x64 or --ia32)
[choices: "ia32", "x64", "all"]
--help Show help [boolean]
@@ -123,7 +123,7 @@ const Platform = builder.Platform
// Promise is returned
builder.build({
- targets: Platform.OSX.createTarget(),
+ targets: Platform.MAC.createTarget(),
devMetadata: {
"//": "build and other properties, see https://goo.gl/5jVxoO"
}
diff --git a/appveyor.yml b/appveyor.yml
index c582010bf51..15a52064e23 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -5,6 +5,7 @@ cache:
- node_modules
- '%APPDATA%\npm-cache'
- '%USERPROFILE%\.electron'
+ - '%USERPROFILE%\.cache\nsis'
install:
- ps: Install-Product node 6 x64
diff --git a/docker/6/Dockerfile b/docker/6/Dockerfile
index d1425c06a5b..0e85aa653d3 100644
--- a/docker/6/Dockerfile
+++ b/docker/6/Dockerfile
@@ -1,6 +1,6 @@
FROM electronuserland/electron-builder:base
-ENV NODE_VERSION 6.2.1
+ENV NODE_VERSION 6.2.2
# https://github.com/npm/npm/issues/4531
RUN curl -SLO "https://nodejs.org/dist/v$NODE_VERSION/node-v$NODE_VERSION-linux-x64.tar.xz" \
diff --git a/docs/Code Signing.md b/docs/Code Signing.md
index aec176ff327..738fe37549b 100644
--- a/docs/Code Signing.md
+++ b/docs/Code Signing.md
@@ -1,6 +1,6 @@
-OS X and Windows code signing is supported. Windows is dual code-signed (SHA1 & SHA256 hashing algorithms).
+MacOS and Windows code signing is supported. Windows is dual code-signed (SHA1 & SHA256 hashing algorithms).
-On a OS X development machine valid and appropriate identity from your keychain will be automatically used.
+On a MacOS development machine valid and appropriate identity from your keychain will be automatically used.
| Env name | Description
| -------------- | -----------
diff --git a/docs/Multi Platform Build.md b/docs/Multi Platform Build.md
index 0da48ac727d..549259f8415 100755
--- a/docs/Multi Platform Build.md
+++ b/docs/Multi Platform Build.md
@@ -3,33 +3,33 @@ Don't expect that you can build app for all platforms on one platform.
* If your app has native dependencies, it can be compiled only on the target platform.
[prebuild](https://www.npmjs.com/package/prebuild) is a solution, but most node modules [don't provide](https://github.com/atom/node-keytar/issues/27) prebuilt binaries.
-* OS Code Signing works only on OS X. [Cannot be fixed](http://stackoverflow.com/a/12156576).
+* OS Code Signing works only on MacOS. [Cannot be fixed](http://stackoverflow.com/a/12156576).
-Don't think that mentioned issues are major, you should use build servers — e.g. [AppVeyor](http://www.appveyor.com/) to build Windows app and [Travis](https://travis-ci.org) to build OS X/Linux apps.
+Don't think that mentioned issues are major, you should use build servers — e.g. [AppVeyor](http://www.appveyor.com/) to build Windows app and [Travis](https://travis-ci.org) to build MacOS/Linux apps.
See [sample appveyor.yml](https://github.com/develar/onshape-desktop-shell/blob/master/appveyor.yml) to build Electron app for Windows.
-And [sample .travis.yml](https://github.com/develar/onshape-desktop-shell/blob/master/.travis.yml) to build Electron app for OS X.
+And [sample .travis.yml](https://github.com/develar/onshape-desktop-shell/blob/master/.travis.yml) to build Electron app for MacOS.
By default build for current platform and current arch. Use CLI flags `--osx`, `--win`, `--linux` to specify platforms. And `--ia32`, `--x64` to specify arch.
-For example, to build app for OS X, Windows and Linux:
+For example, to build app for MacOS, Windows and Linux:
```
-npm run build -owl
+build -mwl
```
Build performed in parallel, so, it is highly recommended to not use npm task per platform (e.g. `npm run dist:osx && npm run dist:win32`), but specify multiple platforms/targets in one build command.
You don't need to clean dist output before build — output directory is cleaned automatically.
-## OS X
+## MacOS
Use [brew](http://brew.sh) to install required packages.
-To build app in distributable format for Windows on OS X:
+To build app in distributable format for Windows on MacOS:
```
brew install Caskroom/cask/xquartz wine mono
```
-To build app in distributable format for Linux on OS X:
+To build app in distributable format for Linux on MacOS:
```
brew install gnu-tar libicns graphicsmagick
```
diff --git a/docs/Options.md b/docs/Options.md
index a43a746bf4a..37d70372855 100644
--- a/docs/Options.md
+++ b/docs/Options.md
@@ -22,7 +22,7 @@ In the development `package.json` custom `build` field can be specified to custo
}
```
-As you can see, you need to customize OS X options only if you want to provide custom `x, y`.
+As you can see, you need to customize MacOS options only if you want to provide custom `x, y`.
Don't customize paths to background and icon, — just follow conventions.
Here documented only `electron-builder` specific options:
@@ -50,14 +50,15 @@ Here documented only `electron-builder` specific options:
## `.build`
| Name | Description
| --- | ---
-| appId |
The application id. Used as [CFBundleIdentifier](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102070) for OS X and as [Application User Model ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx) for Windows.
For windows only NSIS target supports it. Squirrel.Windows is not fixed yet.
Defaults to com.electron.${name}. It is strongly recommended that an explicit ID be set.
-| app-category-type |
*OS X-only.* The application category type, as shown in the Finder via *View -> Arrange by Application Category* when viewing the Applications directory.
For example, app-category-type=public.app-category.developer-tools will set the application category to *Developer Tools*.
Valid values are listed in [Apple’s documentation](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html#//apple_ref/doc/uid/TP40009250-SW8).
+| appId |
The application id. Used as [CFBundleIdentifier](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102070) for MacOS and as [Application User Model ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx) for Windows.
For windows only NSIS target supports it. Squirrel.Windows is not fixed yet.
Defaults to com.electron.${name}. It is strongly recommended that an explicit ID be set.
+| app-category-type |
*MacOS-only.* The application category type, as shown in the Finder via *View -> Arrange by Application Category* when viewing the Applications directory.
For example, app-category-type=public.app-category.developer-tools will set the application category to *Developer Tools*.
Valid values are listed in [Apple’s documentation](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html#//apple_ref/doc/uid/TP40009250-SW8).
| asar |
Whether to package the application’s source code into an archive, using [Electron’s archive format](https://github.com/electron/asar). Defaults to true. Reasons why you may want to disable this feature are described in [an application packaging tutorial in Electron’s documentation](http://electron.atom.io/docs/latest/tutorial/application-packaging/#limitations-on-node-api/).
Or you can pass object of any asar options.
| productName | See [AppMetadata.productName](#AppMetadata-productName).
-| files |
A [glob patterns](https://www.npmjs.com/package/glob#glob-primer) relative to the [app directory](#MetadataDirectories-app), which specifies which files to include when copying files to create the package. Defaults to \*\*\/\* (i.e. [hidden files are ignored by default](https://www.npmjs.com/package/glob#dots)).
Development dependencies are never copied in any case. You don’t need to ignore it explicitly.
[Multiple patterns](#multiple-glob-patterns) are supported. You can use ${os} (expanded to osx, linux or win according to current platform) and ${arch} in the pattern. If directory matched, all contents are copied. So, you can just specify foo to copy foo directory.
Remember that default pattern \*\*\/\* is not added to your custom, so, you have to add it explicitly — e.g. ["\*\*\/\*", "!ignoreMe${/\*}"].
May be specified in the platform options (e.g. in the build.osx).
-| extraResources |
A [glob patterns](https://www.npmjs.com/package/glob#glob-primer) relative to the project directory, when specified, copy the file or directory with matching names directly into the app’s resources directory (Contents/Resources for OS X, resources for Linux/Windows).
Glob rules the same as for [files](#BuildMetadata-files).
-| extraFiles | The same as [extraResources](#BuildMetadata-extraResources) but copy into the app's content directory (`Contents` for OS X, root directory for Linux/Windows).
-| osx | See [.build.osx](#OsXBuildOptions).
+| files |
A [glob patterns](https://www.npmjs.com/package/glob#glob-primer) relative to the [app directory](#MetadataDirectories-app), which specifies which files to include when copying files to create the package. Defaults to \*\*\/\* (i.e. [hidden files are ignored by default](https://www.npmjs.com/package/glob#dots)).
Development dependencies are never copied in any case. You don’t need to ignore it explicitly.
[Multiple patterns](#multiple-glob-patterns) are supported. You can use ${os} (expanded to mac, linux or win according to current platform) and ${arch} in the pattern. If directory matched, all contents are copied. So, you can just specify foo to copy foo directory.
Remember that default pattern \*\*\/\* is not added to your custom, so, you have to add it explicitly — e.g. ["\*\*\/\*", "!ignoreMe${/\*}"].
May be specified in the platform options (e.g. in the build.mac).
+| extraResources |
A [glob patterns](https://www.npmjs.com/package/glob#glob-primer) relative to the project directory, when specified, copy the file or directory with matching names directly into the app’s resources directory (Contents/Resources for MacOS, resources for Linux/Windows).
Glob rules the same as for [files](#BuildMetadata-files).
+| extraFiles | The same as [extraResources](#BuildMetadata-extraResources) but copy into the app's content directory (`Contents` for MacOS, root directory for Linux/Windows).
+| mac | See [.build.mac](#MacOptions).
+| dmg | See [.build.dmg](#DmgOptions).
| mas | See [.build.mas](#MasBuildOptions).
| win | See [.build.win](#LinuxBuildOptions).
| nsis | See [.build.nsis](#NsisOptions).
@@ -65,24 +66,34 @@ Here documented only `electron-builder` specific options:
| compression | The compression level, one of `store`, `normal`, `maximum` (default: `normal`). If you want to rapidly test build, `store` can reduce build time significantly.
| afterPack | *programmatic API only* The function to be run after pack (but before pack into distributable format and sign). Promise must be returned.
-
-### `.build.osx`
+
+### `.build.mac`
+
+MacOS specific build options.
+
+| Name | Description
+| --- | ---
+| target | Target package type: list of `default`, `dmg`, `mas`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`. 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/entitlements.osx.plist 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/entitlements.osx.inherit.plist 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.entitlements.darwin.inherit.plist).
This option only applies when signing with entitlements provided.
+
+
+### `.build.dmg`
+
+MacOS DMG specific options.
See all [appdmg options](https://www.npmjs.com/package/appdmg#json-specification).
| Name | Description
| --- | ---
-| icon | The path to DMG icon, which will be shown when mounted. Defaults to `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`, `mas`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`. 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/entitlements.osx.plist 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/entitlements.osx.inherit.plist 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.entitlements.darwin.inherit.plist).
This option only applies when signing with entitlements provided.
+| icon | The path to DMG icon, which will be shown when mounted. Defaults to `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).
### `.build.mas`
-MAS (Mac Application Store) specific options (in addition to `build.osx`).
+MAS (Mac Application Store) specific options (in addition to `build.mac`).
| Name | Description
| --- | ---
@@ -91,6 +102,9 @@ MAS (Mac Application Store) specific options (in addition to `build.osx`).
### `.build.win`
+
+Windows specific build options.
+
| Name | Description
| --- | ---
| target | Target package type: list of `squirrel`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`. Defaults to `squirrel`.
@@ -116,6 +130,9 @@ See [NSIS target notes](https://github.com/electron-userland/electron-builder/wi
### `.build.linux`
+
+Linux specific build options.
+
| Name | Description
| --- | ---
| description | As [description](#AppMetadata-description) from application package.json, but allows you to specify different for Linux.
@@ -157,4 +174,4 @@ Remember that `!doNotCopyMe/**/*` would match the files *in* the `doNotCopyMe` d
Solution — use macro `${/*}`, e.g. `!doNotCopyMe${/*}`.
# Build Version Management
-`CFBundleVersion` (OS X) and `FileVersion` (Windows) will be set automatically to `version`.`build_number` on CI server (Travis, AppVeyor and CircleCI supported).
\ No newline at end of file
+`CFBundleVersion` (MacOS) and `FileVersion` (Windows) will be set automatically to `version`.`build_number` on CI server (Travis, AppVeyor and CircleCI supported).
\ No newline at end of file
diff --git a/docs/Publishing Artifacts.md b/docs/Publishing Artifacts.md
index 2d1e09ba5de..636cfcfbc5c 100644
--- a/docs/Publishing Artifacts.md
+++ b/docs/Publishing Artifacts.md
@@ -1,4 +1,4 @@
-Travis and AppVeyor support publishing artifacts. But it requires additional configuration. For each CI (since AppVeyor can build only Windows and Travis only OS X / Linux).
+Travis and AppVeyor support publishing artifacts. But it requires additional configuration. For each CI (since AppVeyor can build only Windows and Travis only MacOS / Linux).
`electron-builder` allows you to just add `GH_TOKEN` environment variable and that's all.
diff --git a/docs/programmaticUsage.js b/docs/programmaticUsage.js
index 7927e99328d..d658d95d3ad 100644
--- a/docs/programmaticUsage.js
+++ b/docs/programmaticUsage.js
@@ -4,7 +4,7 @@ const builder = require("electron-builder")
// Promise is returned
builder.build({
- platform: [builder.Platform.OSX],
+ platform: [builder.Platform.MAC],
"//": "platform, arch and other properties, see PackagerOptions in the node_modules/electron-builder/out/electron-builder.d.ts",
devMetadata: {
"//": "build and other properties, see https://goo.gl/5jVxoO"
diff --git a/package.json b/package.json
index 2d674612b10..0a81d8d3f33 100644
--- a/package.json
+++ b/package.json
@@ -50,6 +50,7 @@
"setup",
"Windows",
"OS X",
+ "MacOS",
"Mac"
],
"author": "Stefan Judis",
@@ -74,6 +75,7 @@
"lodash.template": "^4.2.5",
"mime": "^1.3.4",
"minimatch": "^3.0.2",
+ "path-sort": "^0.1.0",
"pretty-ms": "^2.1.0",
"progress": "^1.1.8",
"progress-stream": "^1.2.0",
@@ -112,7 +114,6 @@
"diff": "^2.2.3",
"electron-download": "^2.1.2",
"json8": "^0.9.0",
- "path-sort": "^0.1.0",
"plist": "^1.2.0",
"pre-git": "^3.9.1",
"semantic-release": "^6.3.0",
@@ -120,7 +121,7 @@
"ts-babel": "^1.0.2",
"tsconfig-glob": "^0.4.3",
"tslint": "3.11.0-dev.0",
- "typescript": "^1.9.0-dev.20160617-1.0",
+ "typescript": "1.9.0-dev.20160620-1.0",
"whitespace": "^2.0.0"
},
"babel": {
@@ -135,7 +136,7 @@
"verbose": true,
"cache": false,
"files": [
- "test/out/*"
+ "test/out/*.js"
]
},
"typings": "./out/electron-builder.d.ts",
diff --git a/src/asarUtil.ts b/src/asarUtil.ts
index 614ace45f4c..ce0b6dfaad0 100644
--- a/src/asarUtil.ts
+++ b/src/asarUtil.ts
@@ -4,6 +4,7 @@ import { lstat, readdir } from "fs-extra-p"
import { Promise as BluebirdPromise } from "bluebird"
import * as path from "path"
import { Stats } from "fs"
+import pathSorter = require("path-sort")
//noinspection JSUnusedLocalSymbols
const __awaiter = require("./awaiter")
@@ -43,7 +44,8 @@ export async function createAsarArchive(src: string, resourcesPath: string, opti
},
filter)
- await BluebirdPromise.promisify(createPackageFromFiles)(src, path.join(resourcesPath, "app.asar"), files, metadata, options)
+ // sort files to minimize file change (i.e. asar file is not changed dramatically on small change)
+ await BluebirdPromise.promisify(createPackageFromFiles)(src, path.join(resourcesPath, "app.asar"), pathSorter(files), metadata, options)
}
export async function checkFileInPackage(asarFile: string, relativeFile: string) {
diff --git a/src/build-cli.ts b/src/build-cli.ts
index 42005243542..612d4f9bd5b 100644
--- a/src/build-cli.ts
+++ b/src/build-cli.ts
@@ -3,6 +3,23 @@
import { build, CliOptions } from "./builder"
import { printErrorAndExit } from "./promise"
import { createYargs } from "./cliOptions"
+import { readJson } from "fs-extra-p"
+import * as path from "path"
+
+import updateNotifier = require("update-notifier")
+import { warn } from "./log"
+
+if (process.env.CI == null && process.env.NO_UPDATE_NOTIFIER == null) {
+ readJson(path.join(__dirname, "..", "package.json"))
+ .then(it => {
+ updateNotifier({
+ pkg: it
+ }).notify()
+ })
+ .catch(e => {
+ warn(`Cannot check updates: ${e}`)
+ })
+}
build((createYargs().argv))
.catch(printErrorAndExit)
\ No newline at end of file
diff --git a/src/builder.ts b/src/builder.ts
index c425e24eacb..13e11d5a90b 100644
--- a/src/builder.ts
+++ b/src/builder.ts
@@ -31,7 +31,7 @@ export interface BuildOptions extends PackagerOptions, PublishOptions {
}
export interface CliOptions extends PackagerOptions, PublishOptions {
- osx?: Array
+ mac?: Array
linux?: Array
win?: Array
@@ -90,7 +90,7 @@ export function normalizeOptions(args: CliOptions): BuildOptions {
}
if (types.length === 0) {
- if (platform === Platform.OSX) {
+ if (platform === Platform.MAC) {
archToType.set(Arch.x64, [])
}
else {
@@ -103,7 +103,7 @@ export function normalizeOptions(args: CliOptions): BuildOptions {
for (let type of types) {
let arch: string
- if (platform === Platform.OSX) {
+ if (platform === Platform.MAC) {
arch = "x64"
addValue(archToType, Arch.x64, type)
}
@@ -121,8 +121,8 @@ export function normalizeOptions(args: CliOptions): BuildOptions {
}
}
- if (args.osx != null) {
- processTargets(Platform.OSX, args.osx)
+ if (args.mac != null) {
+ processTargets(Platform.MAC, args.mac)
}
if (args.linux != null) {
@@ -145,17 +145,19 @@ export function normalizeOptions(args: CliOptions): BuildOptions {
const result = Object.assign({}, args)
result.targets = targets
- delete result.osx
+ delete result.mac
delete result.linux
delete result.win
delete result.platform
delete result.arch
const r = result
+ delete r.m
delete r.o
delete r.l
delete r.w
delete r.windows
+ delete r.osx
delete r["$0"]
delete r._
delete r.version
@@ -169,7 +171,7 @@ export function normalizeOptions(args: CliOptions): BuildOptions {
export function createTargets(platforms: Array, type?: string | null, arch?: string | null): Map>> {
const targets = new Map>>()
for (let platform of platforms) {
- const archs = platform === Platform.OSX ? [Arch.x64] : (arch === "all" ? [Arch.x64, Arch.ia32] : [archFromString(arch == null ? process.arch : arch)])
+ const archs = platform === Platform.MAC ? [Arch.x64] : (arch === "all" ? [Arch.x64, Arch.ia32] : [archFromString(arch == null ? process.arch : arch)])
const archToType = new Map>()
targets.set(platform, archToType)
diff --git a/src/cliOptions.ts b/src/cliOptions.ts
index 2a68af543bb..a4f91f9b28d 100644
--- a/src/cliOptions.ts
+++ b/src/cliOptions.ts
@@ -1,56 +1,74 @@
import { underline } from "chalk"
import yargs = require("yargs")
+const publishGroup = "Publishing:"
+const buildGroup = "Building:"
+const deprecated = "Deprecated:"
+
export function createYargs(): any {
return yargs
- .option("osx", {
- alias: "o",
- describe: "Build for OS X",
+ .example("build -mwl", "build for MacOS, Windows and Linux")
+ .example("build --linux deb tar.xz", "build deb and tar.xz for Linux")
+ .example("build --win --ia32", "build for Windows ia32")
+ .option("mac", {
+ group: buildGroup,
+ alias: ["m", "o", "osx"],
+ describe: `Build for MacOS, accepts target list (see ${underline("https://goo.gl/HAnnq8")}).`,
type: "array",
})
.option("linux", {
+ group: buildGroup,
alias: "l",
- describe: "Build for Linux",
+ describe: `Build for Linux, accepts target list (see ${underline("https://goo.gl/O80IL2")})`,
type: "array",
})
.option("win", {
+ group: buildGroup,
alias: ["w", "windows"],
- describe: "Build for Windows",
+ describe: `Build for Windows, accepts target list (see ${underline("https://goo.gl/dL4i8i")})`,
type: "array",
})
.option("x64", {
+ group: buildGroup,
describe: "Build for x64",
type: "boolean",
})
.option("ia32", {
+ group: buildGroup,
describe: "Build for ia32",
type: "boolean",
})
.option("publish", {
+ group: publishGroup,
alias: "p",
describe: `Publish artifacts (to GitHub Releases), see ${underline("https://goo.gl/WMlr4n")}`,
choices: ["onTag", "onTagOrDraft", "always", "never"],
})
.option("draft", {
+ group: publishGroup,
describe: "Create a draft (unpublished) release",
type: "boolean",
default: undefined,
})
.option("prerelease", {
+ group: publishGroup,
describe: "Identify the release as a prerelease",
type: "boolean",
default: undefined,
})
.option("platform", {
- describe: "The target platform (preferred to use --osx, --win or --linux)",
- choices: ["osx", "win", "linux", "darwin", "win32", "all"],
+ group: deprecated,
+ describe: "The target platform (preferred to use --mac, --win or --linux)",
+ choices: ["mac", "osx", "win", "linux", "darwin", "win32", "all"],
})
.option("arch", {
+ group: deprecated,
describe: "The target arch (preferred to use --x64 or --ia32)",
choices: ["ia32", "x64", "all"],
})
.strict()
+ .group(["help", "version"], "Other:")
.help()
.version()
- .epilog(`Project home: ${underline("https://github.com/electron-userland/electron-builder")}`)
+ .epilog(`See the Wiki (${underline("https://github.com/electron-userland/electron-builder/wiki")}) for more documentation.`)
}
diff --git a/src/index.ts b/src/index.ts
index f01868354ef..10572c05cc4 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,5 +1,6 @@
export { Packager } from "./packager"
-export { PackagerOptions, ArtifactCreated, DIR_TARGET, BuildInfo } from "./platformPackager"
+export { PackagerOptions, ArtifactCreated, BuildInfo } from "./platformPackager"
+export { DIR_TARGET, DEFAULT_TARGET } from "./targets/targetFactory"
export { BuildOptions, build, createPublisher, CliOptions, createTargets } from "./builder"
export { PublishOptions, Publisher } from "./gitHubPublisher"
-export { AppMetadata, DevMetadata, Platform, Arch, archFromString, BuildMetadata, OsXBuildOptions, WinBuildOptions, LinuxBuildOptions, CompressionLevel } from "./metadata"
\ No newline at end of file
+export { AppMetadata, DevMetadata, Platform, Arch, archFromString, BuildMetadata, MacOptions, WinBuildOptions, LinuxBuildOptions, CompressionLevel } from "./metadata"
\ No newline at end of file
diff --git a/src/linuxPackager.ts b/src/linuxPackager.ts
index c666a94c64c..1aca5ddb16d 100755
--- a/src/linuxPackager.ts
+++ b/src/linuxPackager.ts
@@ -1,205 +1,80 @@
import * as path from "path"
import { Promise as BluebirdPromise } from "bluebird"
-import { PlatformPackager, BuildInfo, smarten } from "./platformPackager"
+import { PlatformPackager, BuildInfo, Target } from "./platformPackager"
import { Platform, LinuxBuildOptions, Arch } from "./metadata"
-import { exec, debug, use, getTempName } from "./util"
-import { outputFile, readFile, remove, readdir, emptyDir } from "fs-extra-p"
-import { downloadFpm } from "./util/binDownload"
-import { tmpdir } from "os"
-const template = require("lodash.template")
+import { FpmTarget } from "./targets/fpm"
+import { createCommonTarget, DEFAULT_TARGET } from "./targets/targetFactory"
//noinspection JSUnusedLocalSymbols
const __awaiter = require("./awaiter")
-const installPrefix = "/opt"
+export const installPrefix = "/opt"
export class LinuxPackager extends PlatformPackager {
- private readonly buildOptions: LinuxBuildOptions
-
- private readonly packageFiles: Promise>
- private readonly scriptFiles: Promise>
-
- private readonly fpmPath: Promise
-
- constructor(info: BuildInfo, cleanupTasks: Array<() => Promise>) {
+ constructor(info: BuildInfo) {
super(info)
+ }
- this.buildOptions = Object.assign({
- name: this.appInfo.name,
- description: this.appInfo.description,
- }, this.customBuildOptions)
+ normalizePlatformSpecificBuildOptions(options: LinuxBuildOptions | n): LinuxBuildOptions {
+ if (options != null && options.description != null) {
+ return options
+ }
+ else {
+ return Object.assign({
+ description: this.appInfo.description,
+ }, options)
+ }
+ }
- if (!this.hasOnlyDirTarget()) {
- 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)
+ createTargets(targets: Array, mapper: (name: string, factory: () => Target) => void, cleanupTasks: Array<() => Promise>): void {
+ for (let name of targets) {
+ if (name === "dir") {
+ continue
+ }
- if (process.platform === "win32" || process.env.USE_SYSTEM_FPM === "true") {
- this.fpmPath = BluebirdPromise.resolve("fpm")
+ if (name === DEFAULT_TARGET || name === "deb") {
+ mapper("deb", () => new FpmTarget("deb", this, cleanupTasks))
+ }
+ else if (name === "rpm" || name === "sh" || name === "freebsd" || name === "pacman" || name === "apk" || name === "p5p") {
+ mapper(name, () => new FpmTarget(name, this, cleanupTasks))
}
else {
- this.fpmPath = downloadFpm(process.platform === "darwin" ? "1.5.1-20150715-2.2.2" : "1.5.0-2.3.1", process.platform === "darwin" ? "osx" : `linux-x86${process.arch === "ia32" ? "" : "_64"}`)
+ mapper(name, () => createCommonTarget(name))
}
}
}
- get supportedTargets(): Array {
- return ["deb", "rpm", "sh", "freebsd", "pacman", "apk", "p5p"]
- }
-
get platform() {
return Platform.LINUX
}
- private async computePackageFiles(tempDirPromise: Promise): Promise> {
- const tempDir = await tempDirPromise
-
- const promises: Array>> = []
- if (this.customBuildOptions.desktop == null) {
- promises.push(this.computeDesktopIconPath(tempDir))
- }
-
- promises.push(this.computeDesktop(tempDir))
-
- return Array.prototype.concat.apply([], await BluebirdPromise.all(promises))
- }
-
- async pack(outDir: string, arch: Arch, targets: Array, postAsyncTasks: Array>): Promise {
+ async pack(outDir: string, arch: Arch, targets: Array, postAsyncTasks: Array>): Promise {
const appOutDir = this.computeAppOutDir(outDir, arch)
- await this.doPack(this.computePackOptions(outDir, appOutDir, arch), outDir, appOutDir, arch, this.customBuildOptions)
+ await this.doPack(await this.computePackOptions(outDir, appOutDir, arch), outDir, appOutDir, arch, this.platformSpecificBuildOptions)
postAsyncTasks.push(this.packageInDistributableFormat(outDir, appOutDir, arch, targets))
}
- private async computeDesktop(tempDir: string): Promise> {
- const tempFile = path.join(tempDir, this.appInfo.productName + ".desktop")
- await outputFile(tempFile, this.buildOptions.desktop || `[Desktop Entry]
-Name=${this.appInfo.productName}
-Comment=${this.buildOptions.description}
-Exec="${installPrefix}/${this.appInfo.productName}/${this.appInfo.productName}"
-Terminal=false
-Type=Application
-Icon=${this.appInfo.name}
-`)
- return [`${tempFile}=/usr/share/applications/${this.appInfo.productName}.desktop`]
- }
-
- // must be name without spaces and other special characters, but not product name used
- private async computeDesktopIconPath(tempDir: string): Promise> {
- try {
- const mappings: Array = []
- const pngIconsDir = path.join(this.buildResourcesDir, "icons")
- for (let file of (await readdir(pngIconsDir))) {
- if (file!.endsWith(".png") || file!.endsWith(".PNG")) {
- // If parseInt encounters a character that is not a numeral in the specified radix,
- // it returns the integer value parsed up to that point
- try {
- const size = parseInt(file!, 10)
- if (size > 0) {
- mappings.push(`${pngIconsDir}/${file}=/usr/share/icons/hicolor/${size}x${size}/apps/${this.appInfo.name}.png`)
- }
- }
- catch (e) {
- console.error(e)
- }
- }
- }
-
- return mappings
- }
- catch (e) {
- return this.createFromIcns(tempDir)
- }
- }
-
- private async createFromIcns(tempDir: string): Promise> {
- const output = await exec("icns2png", ["-x", "-o", tempDir, path.join(this.buildResourcesDir, "icon.icns")])
- debug(output)
-
- const imagePath = path.join(tempDir, "icon_256x256x32.png")
-
- function resize(size: number): BluebirdPromise {
- const sizeArg = `${size}x${size}`
- return exec("gm", ["convert", "-size", sizeArg, imagePath, "-resize", sizeArg, path.join(tempDir, `icon_${size}x${size}x32.png`)])
- }
-
- const promises: Array> = [resize(24), resize(96)]
- if (!output.includes("is32")) {
- promises.push(resize(16))
- }
- if (!output.includes("ih32")) {
- promises.push(resize(48))
- }
- if (!output.toString().includes("icp6")) {
- promises.push(resize(64))
- }
- if (!output.includes("it32")) {
- promises.push(resize(128))
- }
-
- await BluebirdPromise.all(promises)
-
- const appName = this.appInfo.name
-
- function createMapping(size: string) {
- return `${tempDir}/icon_${size}x${size}x32.png=/usr/share/icons/hicolor/${size}x${size}/apps/${appName}.png`
- }
-
- return [
- createMapping("16"),
- createMapping("24"),
- createMapping("32"),
- createMapping("48"),
- createMapping("64"),
- createMapping("96"),
- createMapping("128"),
- createMapping("256"),
- createMapping("512"),
- ]
- }
-
- private async createScripts(tempDirPromise: Promise): Promise> {
- const tempDir = await tempDirPromise
- const defaultTemplatesDir = path.join(__dirname, "..", "templates", "linux")
-
- const templateOptions = Object.assign({
- // old API compatibility
- executable: this.appInfo.productName,
- }, this.buildOptions)
-
- const afterInstallTemplate = this.buildOptions.afterInstall || path.join(defaultTemplatesDir, "after-install.tpl")
- const afterInstallFilePath = writeConfigFile(tempDir, afterInstallTemplate, templateOptions)
-
- const afterRemoveTemplate = this.buildOptions.afterRemove || path.join(defaultTemplatesDir, "after-remove.tpl")
- const afterRemoveFilePath = writeConfigFile(tempDir, afterRemoveTemplate, templateOptions)
-
- return await BluebirdPromise.all([afterInstallFilePath, afterRemoveFilePath])
- }
-
- protected async packageInDistributableFormat(outDir: string, appOutDir: string, arch: Arch, targets: Array): Promise {
+ protected async packageInDistributableFormat(outDir: string, appOutDir: string, arch: Arch, targets: Array): Promise {
// todo fix fpm - if run in parallel, get strange tar errors
- for (let target of targets) {
- target = target === "default" ? "deb" : target
- if (target !== "dir" && target !== "zip" && target !== "7z" && !target.startsWith("tar.")) {
+ for (let t of targets) {
+ if (t instanceof FpmTarget) {
+ const target = t.name
const destination = path.join(outDir, this.generateName(target, arch, true /* on Linux we use safe name — without space */))
- await this.buildPackage(destination, target, this.buildOptions, appOutDir, arch)
- this.dispatchArtifactCreated(destination, this.generateName(target, arch, true))
+ await t.build(destination, target, appOutDir, arch)
+ this.dispatchArtifactCreated(destination)
}
}
const promises: Array> = []
// https://github.com/electron-userland/electron-builder/issues/460
// for some reasons in parallel to fmp we cannot use tar
- for (let target of targets) {
+ for (let t of targets) {
+ const target = t.name
if (target === "zip" || target === "7z" || target.startsWith("tar.")) {
const destination = path.join(outDir, this.generateName(target, arch, true))
promises.push(this.archiveApp(target, appOutDir, destination)
- .then(() => this.dispatchArtifactCreated(destination, this.generateName(target, arch, true))))
+ .then(() => this.dispatchArtifactCreated(destination)))
}
}
@@ -207,86 +82,4 @@ Icon=${this.appInfo.name}
await BluebirdPromise.all(promises)
}
}
-
- private async buildPackage(destination: string, target: string, options: LinuxBuildOptions, appOutDir: string, arch: Arch): Promise {
- const scripts = await this.scriptFiles
-
- const projectUrl = await this.appInfo.computePackageUrl()
- if (projectUrl == null) {
- throw new Error("Please specify project homepage, see https://github.com/electron-userland/electron-builder/wiki/Options#AppMetadata-homepage")
- }
-
- const author = options.maintainer || `${this.metadata.author.name} <${this.metadata.author.email}>`
- const synopsis = options.synopsis
- const args = [
- "-s", "dir",
- "-t", target,
- "--architecture", arch === Arch.ia32 ? "i386" : "amd64",
- "--name", this.appInfo.name,
- "--force",
- "--after-install", scripts[0],
- "--after-remove", scripts[1],
- "--description", smarten(target === "rpm" ? this.buildOptions.description! : `${synopsis || ""}\n ${this.buildOptions.description}`),
- "--maintainer", author,
- "--vendor", options.vendor || author,
- "--version", this.appInfo.version,
- "--package", destination,
- "--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) {
- if (target === "deb") {
- depends = ["libappindicator1", "libnotify-bin"]
- }
- else {
- depends = []
- }
- }
- else if (!Array.isArray(depends)) {
- if (typeof depends === "string") {
- depends = [depends]
- }
- else {
- throw new Error(`depends must be Array or String, but specified as: ${depends}`)
- }
- }
-
- for (let dep of depends) {
- args.push("--depends", dep)
- }
-
- use(this.metadata.license || this.devMetadata.license, it => args.push("--license", it!))
- use(this.appInfo.buildNumber, it => args.push("--iteration", it!))
-
- use(options.fpm, it => args.push(...it))
-
- args.push(`${appOutDir}/=${installPrefix}/${this.appInfo.productName}`)
- args.push(...(await this.packageFiles)!)
- await exec(await this.fpmPath, args)
- }
-}
-
-async function writeConfigFile(tempDir: string, templatePath: string, options: any): Promise {
- const config = template(await readFile(templatePath, "utf8"),
- {
- // set interpolate explicitly to avoid troubles with templating of installer.nsi.tpl
- interpolate: /<%=([\s\S]+?)%>/g
- })(options)
-
- const outputPath = path.join(tempDir, path.basename(templatePath, ".tpl"))
- await outputFile(outputPath, config)
- return outputPath
-}
+}
\ No newline at end of file
diff --git a/src/metadata.ts b/src/metadata.ts
index f4fe50fcbf2..b606cd4cb82 100755
--- a/src/metadata.ts
+++ b/src/metadata.ts
@@ -82,7 +82,7 @@ export type CompressionLevel = "store" | "normal" | "maximum"
export interface BuildMetadata {
/*
The application id. Used as
- [CFBundleIdentifier](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102070) for OS X and as
+ [CFBundleIdentifier](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102070) for MacOS and as
[Application User Model ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx) for Windows.
For windows only NSIS target supports it. Squirrel.Windows is not fixed yet.
@@ -95,7 +95,7 @@ export interface BuildMetadata {
readonly "app-bundle-id"?: string | null
/*
- *OS X-only.* The application category type, as shown in the Finder via *View -> Arrange by Application Category* when viewing the Applications directory.
+ *MacOS-only.* The application category type, as shown in the Finder via *View -> Arrange by Application Category* when viewing the Applications directory.
For example, `app-category-type=public.app-category.developer-tools` will set the application category to *Developer Tools*.
@@ -124,31 +124,39 @@ export interface BuildMetadata {
Development dependencies are never copied in any case. You don't need to ignore it explicitly.
- [Multiple patterns](#multiple-glob-patterns) are supported. You can use `${os}` (expanded to osx, linux or win according to current platform) and `${arch}` in the pattern.
+ [Multiple patterns](#multiple-glob-patterns) are supported. You can use `${os}` (expanded to mac, linux or win according to current platform) and `${arch}` in the pattern.
If directory matched, all contents are copied. So, you can just specify `foo` to copy `foo` directory.
Remember that default pattern `\*\*\/\*` is not added to your custom, so, you have to add it explicitly — e.g. `["\*\*\/\*", "!ignoreMe${/\*}"]`.
- May be specified in the platform options (e.g. in the `build.osx`).
+ May be specified in the platform options (e.g. in the `build.mac`).
*/
readonly files?: Array | string | null
/**
- A [glob patterns](https://www.npmjs.com/package/glob#glob-primer) relative to the project directory, when specified, copy the file or directory with matching names directly into the app's resources directory (`Contents/Resources` for OS X, `resources` for Linux/Windows).
+ A [glob patterns](https://www.npmjs.com/package/glob#glob-primer) relative to the project directory, when specified, copy the file or directory with matching names directly into the app's resources directory (`Contents/Resources` for MacOS, `resources` for Linux/Windows).
Glob rules the same as for [files](#BuildMetadata-files).
*/
readonly extraResources?: Array | string | null
/**
- The same as [extraResources](#BuildMetadata-extraResources) but copy into the app's content directory (`Contents` for OS X, root directory for Linux/Windows).
+ The same as [extraResources](#BuildMetadata-extraResources) but copy into the app's content directory (`Contents` for MacOS, root directory for Linux/Windows).
*/
readonly extraFiles?: Array | string | null
/*
- See [.build.osx](#OsXBuildOptions).
+ See [.build.mac](#MacOptions).
*/
- readonly osx?: OsXBuildOptions | null
+ readonly mac?: MacOptions | null
+
+ /*
+ See [.build.dmg](#DmgOptions).
+ */
+ readonly dmg?: DmgOptions | null
+
+ // deprecated
+ readonly osx?: MacOptions | null
/*
See [.build.mas](#MasBuildOptions).
@@ -194,6 +202,8 @@ export interface BuildMetadata {
Whether to [rebuild](https://docs.npmjs.com/cli/rebuild) native dependencies (`npm rebuild`) before starting to package the app. Defaults to `true`.
*/
readonly npmRebuild?: boolean
+
+ readonly icon?: string | null
}
export interface AfterPackContext {
@@ -202,22 +212,11 @@ export interface AfterPackContext {
}
/*
- ### `.build.osx`
+ ### `.build.mac`
- See all [appdmg options](https://www.npmjs.com/package/appdmg#json-specification).
+ MacOS specific build options.
*/
-export interface OsXBuildOptions extends PlatformSpecificBuildOptions {
- /*
- The path to DMG icon, which will be shown when mounted. Defaults to `build/icon.icns`.
- */
- readonly icon?: string | null
-
- /*
- 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).
- */
- readonly background?: string | null
-
+export interface MacOptions extends PlatformSpecificBuildOptions {
/*
Target package type: list of `default`, `dmg`, `mas`, `7z`, `zip`, `tar.xz`, `tar.lz`, `tar.gz`, `tar.bz2`. Defaults to `default` (dmg and zip for Squirrel.Mac).
*/
@@ -244,12 +243,32 @@ export interface OsXBuildOptions extends PlatformSpecificBuildOptions {
readonly entitlementsInherit?: string | null
}
+/*
+ ### `.build.dmg`
+
+ MacOS DMG specific options.
+
+ See all [appdmg options](https://www.npmjs.com/package/appdmg#json-specification).
+ */
+export interface DmgOptions {
+ /*
+ The path to DMG icon, which will be shown when mounted. Defaults to `build/icon.icns`.
+ */
+ readonly icon?: string | null
+
+ /*
+ 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).
+ */
+ readonly background?: string | null
+}
+
/*
### `.build.mas`
- MAS (Mac Application Store) specific options (in addition to `build.osx`).
+ MAS (Mac Application Store) specific options (in addition to `build.mac`).
*/
-export interface MasBuildOptions extends OsXBuildOptions {
+export interface MasBuildOptions extends MacOptions {
/*
The path to entitlements file for signing the app. `build/entitlements.mas.plist` 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.entitlements.mas.plist).
@@ -265,6 +284,8 @@ export interface MasBuildOptions extends OsXBuildOptions {
/*
### `.build.win`
+
+ Windows specific build options.
*/
export interface WinBuildOptions extends PlatformSpecificBuildOptions {
readonly certificateFile?: string
@@ -341,36 +362,38 @@ export interface NsisOptions {
/*
### `.build.linux`
+
+ Linux specific build options.
*/
export interface LinuxBuildOptions extends PlatformSpecificBuildOptions {
/*
As [description](#AppMetadata-description) from application package.json, but allows you to specify different for Linux.
*/
- description?: string | null
+ readonly description?: string | null
/*
*deb-only.* The [short description](https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Description).
*/
- synopsis?: string | null
+ readonly synopsis?: string | null
/*
The maintainer. Defaults to [author](#AppMetadata-author).
*/
- maintainer?: string | null
+ readonly maintainer?: string | null
/*
The vendor. Defaults to [author](#AppMetadata-author).
*/
- vendor?: string | null
+ readonly vendor?: string | null
// should be not documented, only to experiment
- fpm?: Array | null
+ readonly fpm?: Array | null
//.desktop file template
- desktop?: string | null
+ readonly desktop?: string | null
- afterInstall?: string | null
- afterRemove?: string | null
+ readonly afterInstall?: string | null
+ readonly afterRemove?: string | null
/*
*deb-only.* The compression type, one of `gz`, `bzip2`, `xz`. Defaults to `xz`.
@@ -420,13 +443,19 @@ export interface PlatformSpecificBuildOptions {
readonly asar?: AsarOptions | boolean
readonly target?: Array | null
+
+ readonly icon?: string | null
}
export class Platform {
- static OSX = new Platform("osx", "osx", "darwin")
+ static MAC = new Platform("mac", "mac", "darwin")
static LINUX = new Platform("linux", "linux", "linux")
static WINDOWS = new Platform("windows", "win", "win32")
+ // deprecated
+ //noinspection JSUnusedGlobalSymbols
+ static OSX = Platform.MAC
+
constructor(public name: string, public buildConfigurationKey: string, public nodeName: string) {
}
@@ -440,7 +469,7 @@ export class Platform {
createTarget(type?: string | Array | null, ...archs: Array): Map>> {
const archToType = new Map()
- if (this === Platform.OSX) {
+ if (this === Platform.MAC) {
archs = [Arch.x64]
}
@@ -455,10 +484,12 @@ export class Platform {
}
static fromString(name: string): Platform {
+ name = name.toLowerCase()
switch (name) {
- case Platform.OSX.nodeName:
- case Platform.OSX.name:
- return Platform.OSX
+ case Platform.MAC.nodeName:
+ case Platform.MAC.name:
+ case "osx":
+ return Platform.MAC
case Platform.WINDOWS.nodeName:
case Platform.WINDOWS.name:
@@ -469,7 +500,7 @@ export class Platform {
return Platform.LINUX
}
- throw new Error("Unknown platform: " + name)
+ throw new Error(`Unknown platform: ${name}`)
}
}
diff --git a/src/osxPackager.ts b/src/osxPackager.ts
index bd68217a2ae..24764270604 100644
--- a/src/osxPackager.ts
+++ b/src/osxPackager.ts
@@ -1,17 +1,19 @@
-import { PlatformPackager, BuildInfo } from "./platformPackager"
-import { Platform, OsXBuildOptions, MasBuildOptions, Arch } from "./metadata"
+import { PlatformPackager, BuildInfo, Target } from "./platformPackager"
+import { Platform, MasBuildOptions, Arch, MacOptions } from "./metadata"
import * as path from "path"
import { Promise as BluebirdPromise } from "bluebird"
-import { debug, isEmptyOrSpaces } from "./util"
+import { isEmptyOrSpaces } from "./util"
import { log, warn, task } from "./log"
import { createKeychain, deleteKeychain, CodeSigningInfo, generateKeychainName, findIdentity, appleCertificatePrefixes, CertType } from "./codeSign"
import deepAssign = require("deep-assign")
import { signAsync, flatAsync, BaseSignOptions, SignOptions, FlatOptions } from "electron-osx-sign-tf"
+import { DmgTarget } from "./targets/dmg"
+import { createCommonTarget, DEFAULT_TARGET } from "./targets/targetFactory"
//noinspection JSUnusedLocalSymbols
const __awaiter = require("./awaiter")
-export default class OsXPackager extends PlatformPackager {
+export default class MacPackager extends PlatformPackager {
codeSigningInfo: Promise
constructor(info: BuildInfo, cleanupTasks: Array<() => Promise>) {
@@ -27,32 +29,66 @@ export default class OsXPackager extends PlatformPackager {
}
}
- get platform() {
- return Platform.OSX
+ async getIconPath(): Promise {
+ let iconPath = this.platformSpecificBuildOptions.icon || this.devMetadata.build.icon
+ if (iconPath != null && !iconPath.endsWith(".icns")) {
+ iconPath += ".icns"
+ }
+ return iconPath == null ? await this.getDefaultIcon("icns") : path.resolve(this.projectDir, iconPath)
}
- get supportedTargets(): Array {
- return ["dmg", "mas"]
+ normalizePlatformSpecificBuildOptions(options: MacOptions | n): MacOptions {
+ return super.normalizePlatformSpecificBuildOptions(options == null ? (this.info.devMetadata.build).osx : options)
}
- async pack(outDir: string, arch: Arch, targets: Array, postAsyncTasks: Array>): Promise {
- const packOptions = this.computePackOptions(outDir, this.computeAppOutDir(outDir, arch), arch)
+ createTargets(targets: Array, mapper: (name: string, factory: () => Target) => void, cleanupTasks: Array<() => Promise>): void {
+ for (let name of targets) {
+ if (name === "dir") {
+ continue
+ }
+
+ if (name === DEFAULT_TARGET) {
+ mapper("dmg", () => new DmgTarget(this))
+ mapper("zip", () => new Target("zip"))
+ }
+ else if (name === "dmg") {
+ mapper("dmg", () => new DmgTarget(this))
+ }
+ else {
+ mapper(name, () => name === "mas" ? new Target("mas") : createCommonTarget(name))
+ }
+ }
+ }
+
+ get platform() {
+ return Platform.MAC
+ }
+
+ async pack(outDir: string, arch: Arch, targets: Array, postAsyncTasks: Array>): Promise {
+ const packOptions = await this.computePackOptions(outDir, this.computeAppOutDir(outDir, arch), arch)
let nonMasPromise: Promise | null = null
- if (targets.length > 1 || targets[0] !== "mas") {
+
+ const hasMas = targets.length !== 0 && targets.some(it => it.name === "mas")
+
+ if (!hasMas || targets.length > 1) {
const appOutDir = this.computeAppOutDir(outDir, arch)
- nonMasPromise = this.doPack(packOptions, outDir, appOutDir, arch, this.customBuildOptions)
+ nonMasPromise = this.doPack(packOptions, outDir, appOutDir, arch, this.platformSpecificBuildOptions)
.then(() => this.sign(appOutDir, null))
.then(() => {
this.packageInDistributableFormat(appOutDir, targets, postAsyncTasks)
})
}
- if (targets.includes("mas")) {
+ if (hasMas) {
// osx-sign - disable warning
const appOutDir = path.join(outDir, "mas")
- const masBuildOptions = deepAssign({}, this.customBuildOptions, (this.devMetadata.build)["mas"])
+ const masBuildOptions = deepAssign({}, this.platformSpecificBuildOptions, (this.devMetadata.build)["mas"])
//noinspection JSUnusedGlobalSymbols
- await this.doPack(Object.assign({}, packOptions, {platform: "mas", "osx-sign": false, generateFinalBasename: function () { return "mas" }}), outDir, appOutDir, arch, masBuildOptions)
+ await this.doPack(Object.assign({}, packOptions, {
+ platform: "mas",
+ "osx-sign": false,
+ generateFinalBasename: function () { return "mas" }
+ }), outDir, appOutDir, arch, masBuildOptions)
await this.sign(appOutDir, masBuildOptions)
}
@@ -89,7 +125,7 @@ export default class OsXPackager extends PlatformPackager {
throw new Error("codeSigningInfo is null, but CSC_LINK defined")
}
- const identity = await OsXPackager.findIdentity(masOptions == null ? "Developer ID Application" : "3rd Party Mac Developer Application", this.customBuildOptions.identity)
+ const identity = await MacPackager.findIdentity(masOptions == null ? "Developer ID Application" : "3rd Party Mac Developer Application", this.platformSpecificBuildOptions.identity)
if (identity == null) {
const message = "App is not signed: CSC_LINK or CSC_NAME are not specified, and no valid identity in the keychain, see https://github.com/electron-userland/electron-builder/wiki/Code-Signing"
if (masOptions == null) {
@@ -102,7 +138,7 @@ export default class OsXPackager extends PlatformPackager {
}
if (masOptions != null) {
- const installerName = masOptions == null ? null : (await OsXPackager.findIdentity("3rd Party Mac Developer Installer", this.customBuildOptions.identity))
+ const installerName = masOptions == null ? null : (await MacPackager.findIdentity("3rd Party Mac Developer Installer", this.platformSpecificBuildOptions.identity))
if (installerName == null) {
throw new Error("Cannot find valid installer certificate: CSC_LINK or CSC_NAME are not specified, and no valid identity in the keychain, see https://github.com/electron-userland/electron-builder/wiki/Code-Signing")
}
@@ -142,7 +178,7 @@ export default class OsXPackager extends PlatformPackager {
const resourceList = await this.resourceList
- const customSignOptions = masOptions || this.customBuildOptions
+ const customSignOptions = masOptions || this.platformSpecificBuildOptions
if (customSignOptions.entitlements != null) {
signOptions.entitlements = customSignOptions.entitlements
}
@@ -175,99 +211,31 @@ export default class OsXPackager extends PlatformPackager {
}
}
+ //noinspection JSMethodCanBeStatic
protected async doSign(opts: SignOptions): Promise {
return signAsync(opts)
}
+ //noinspection JSMethodCanBeStatic
protected async doFlat(opts: FlatOptions): Promise {
return flatAsync(opts)
}
- protected async computeEffectiveDistOptions(appOutDir: string): Promise {
- const specification: appdmg.Specification = deepAssign({
- title: this.appInfo.productName,
- "icon-size": 80,
- contents: [
- {
- "x": 410, "y": 220, "type": "link", "path": "/Applications"
- },
- {
- "x": 130, "y": 220, "type": "file"
- }
- ],
- format: this.devMetadata.build.compression === "store" ? "UDRO" : "UDBZ",
- }, this.customBuildOptions)
-
- if (!("icon" in this.customBuildOptions)) {
- const resourceList = await this.resourceList
- if (resourceList.includes("icon.icns")) {
- specification.icon = path.join(this.buildResourcesDir, "icon.icns")
- }
- else {
- warn("Application icon is not set, default Electron icon will be used")
- }
- }
-
- if (!("background" in this.customBuildOptions)) {
- const resourceList = await this.resourceList
- if (resourceList.includes("background.png")) {
- specification.background = path.join(this.buildResourcesDir, "background.png")
- }
- }
-
- specification.contents[1].path = path.join(appOutDir, this.appInfo.productName + ".app")
- return specification
- }
-
- protected packageInDistributableFormat(appOutDir: string, targets: Array, promises: Array>): void {
- for (let target of targets) {
- if (target === "dir") {
- continue
- }
-
- if (target === "dmg" || target === "default") {
- promises.push(this.createDmg(appOutDir))
+ protected packageInDistributableFormat(appOutDir: string, targets: Array, promises: Array>): void {
+ for (let t of targets) {
+ const target = t.name
+ if (t instanceof DmgTarget) {
+ promises.push(t.build(appOutDir))
}
-
- if (target !== "mas" && target !== "dmg") {
- const format = target === "default" ? "zip" : target
- log(`Creating OS X ${format}`)
+ else if (target !== "mas") {
+ log(`Creating MacOS ${target}`)
// we use app name here - see https://github.com/electron-userland/electron-builder/pull/204
- const outFile = path.join(appOutDir, this.generateName2(format, "mac", false))
- promises.push(this.archiveApp(format, appOutDir, outFile)
- .then(() => this.dispatchArtifactCreated(outFile, this.generateName2(format, "mac", true))))
+ const outFile = path.join(appOutDir, this.generateName2(target, "mac", false))
+ promises.push(this.archiveApp(target, appOutDir, outFile)
+ .then(() => this.dispatchArtifactCreated(outFile, this.generateName2(target, "mac", true))))
}
}
}
-
- private async createDmg(appOutDir: string) {
- const artifactPath = path.join(appOutDir, `${this.appInfo.productName}-${this.appInfo.version}.dmg`)
- await new BluebirdPromise(async(resolve, reject) => {
- log("Creating DMG")
- const dmgOptions = {
- target: artifactPath,
- basepath: this.projectDir,
- specification: await this.computeEffectiveDistOptions(appOutDir),
- }
-
- if (debug.enabled) {
- debug(`appdmg: ${JSON.stringify(dmgOptions, null, 2)}`)
- }
-
- const emitter = require("appdmg")(dmgOptions)
- emitter.on("error", reject)
- emitter.on("finish", () => resolve())
- if (debug.enabled) {
- emitter.on("progress", (info: any) => {
- if (info.type === "step-begin") {
- debug(`appdmg: [${info.current}] ${info.title}`)
- }
- })
- }
- })
-
- this.dispatchArtifactCreated(artifactPath, `${this.appInfo.name}-${this.appInfo.version}.dmg`)
- }
}
function checkPrefix(name: string, prefix: string) {
diff --git a/src/packager.ts b/src/packager.ts
index d416808f8cc..8a0706996cd 100644
--- a/src/packager.ts
+++ b/src/packager.ts
@@ -7,8 +7,7 @@ import { all, executeFinally } from "./promise"
import { EventEmitter } from "events"
import { Promise as BluebirdPromise } from "bluebird"
import { AppMetadata, DevMetadata, Platform, Arch } from "./metadata"
-import { PackagerOptions, PlatformPackager, BuildInfo, ArtifactCreated, computeEffectiveTargets, commonTargets } from "./platformPackager"
-import OsXPackager from "./osxPackager"
+import { PackagerOptions, PlatformPackager, BuildInfo, ArtifactCreated, Target } from "./platformPackager"
import { WinPackager } from "./winPackager"
import * as errorMessages from "./errorMessages"
import * as util from "util"
@@ -16,6 +15,8 @@ import deepAssign = require("deep-assign")
import semver = require("semver")
import { warn, log } from "./log"
import { AppInfo } from "./appInfo"
+import MacPackager from "./osxPackager"
+import { createTargets } from "./targets/targetFactory"
//noinspection JSUnusedLocalSymbols
const __awaiter = require("./awaiter")
@@ -53,7 +54,7 @@ export class Packager implements BuildInfo {
return path.join(this.projectDir, "package.json")
}
- async build(): Promise {
+ async build(): Promise