diff --git a/.idea/electron-builder.iml b/.idea/electron-builder.iml
index 248596ee632..0174957a41c 100644
--- a/.idea/electron-builder.iml
+++ b/.idea/electron-builder.iml
@@ -5,6 +5,7 @@
+
diff --git a/.npmignore b/.npmignore
index d21a1ff3671..93c5ee5b05e 100644
--- a/.npmignore
+++ b/.npmignore
@@ -4,7 +4,7 @@ example-app
typings/
src/
tsconfig.json
-tsd.json
+typings.json
npm-debug.log
test/
docs/
\ No newline at end of file
diff --git a/README.md b/README.md
index 3d320292dcf..53a9f6bc418 100644
--- a/README.md
+++ b/README.md
@@ -1,241 +1,133 @@
-[](https://travis-ci.org/loopline-systems/electron-builder) [](https://www.npmjs.org/package/electron-builder) [](https://www.npmjs.org/package/electron-builder) [](http://greenkeeper.io/)
+Complete solution to build ready for distribution and "auto update" installers of your app for OS X, Windows and Linux.
+* [Native application dependencies](http://electron.atom.io/docs/latest/tutorial/using-native-node-modules/) compilation (only if two-package.json project layout used).
+* [Auto Update](#auto-update) ready application packaging.
+* [Code Signing](#code-signing) on a CI server or development machine.
+* [Build version management](#build-version-management).
+* [Publishing artifacts to GitHub Releases](./docs/deployment.md).
-# electron-builder
+[electron-packager](/~https://github.com/maxogden/electron-packager),
+[appdmg](/~https://github.com/LinusU/node-appdmg) and
+[windows-installer](/~https://github.com/electronjs/windows-installer) are used under the hood.
-The electron-builder project is used to create installers for the platforms Windows, OS X and Linux.
-It's built to work together with [electron-packager](/~https://github.com/maxogden/electron-packager).
+Real project example — [onshape-desktop-shell](/~https://github.com/develar/onshape-desktop-shell).
-If you are looking for a complete set up on how to use [electron-packager](/~https://github.com/maxogden/electron-packager) and [electron-builder](/~https://github.com/loopline-systems/electron-builder), check the ["How we use it"](/~https://github.com/loopline-systems/electron-builder#how-we-use-it-so-far) section below.
+# Configuration
+## In short
+1. Ensure that required fields are specified in the application `package.json`:
-The project has been tested successfully on OS X, Windows and Linux (Debian-based) machines.
+ Standard `name`, `description`, `version` and `author`.
-## Install
-
-You can go the global installation route. ;)
-
-```
-$ npm install -g electron-builder electron-packager
-```
-
-**Oooooor...** You can wrap `electron-builder` with `npm scripts` to not have a global dependency.
-
-```
-# install electron builder and electron-packager as dependencies of your project
-$ npm install --save-dev electron-builder electron-packager
-```
-
-After that, you can easily use the `electron-builder` binary in your `package.json`:
-
-```json
-{
- "scripts" : {
- "pack:osx": "electron-packager . MyApp --platform=darwin --arch=x64 --version=0.36.7 --icon=assets/MyApp.icns --out=dist --ignore=dist",
- "build:osx": "npm run pack:osx && electron-builder dist/osx/MyApp.app --platform=osx --out=\"dist/osx\" --config=config.json"
+ Custom `build` field must be specified:
+ ```json
+ "build": {
+ "app-bundle-id": "your.id",
+ "app-category-type": "your.app.category.type",
+ "iconUrl": "(windows only) A URL to an ICO file to use as the application icon, see details below"
}
-}
-```
-
-**Note:** Executables with spaces in their name **must** be written as `\"My App\"`.
-
-## Pre-requisites
-
-- Node.js 0.12 or higher. You can check by running:
-
-```
-$ node --version
-v0.12.0
-```
-
-- [electron-packager](/~https://github.com/maxogden/electron-packager)
-
-### Creating Installers
-
-For further documentation depending on the target please check the details sites:
-
-- [Create installers for Windows](./docs/win.md)
-- [Create installers for OS X](./docs/osx.md)
-- [Create installers for Linux](./docs/linux.md)
-
-## Parameters
-
-```
-Usage
- $ electron-builder --platform= --config= --out=
-
- Required options:
- platform: win, osx, linux
-
- Optional options:
- config: path to config file
- -> if not provided `builder` property in `package.json`
- in current working directory will be read
- out: path to output the installer (must exist)
-```
+ ```
+ 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.
+
+2. 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).
+ Linux icon set will be generated automatically on the fly from the OS X `icns` file.
+
+3. Add [scripts](https://docs.npmjs.com/cli/run-script) to the development `package.json`:
+ ```json
+ "scripts": {
+ "postinstall": "install-app-deps",
+ "pack": "build",
+ "dist": "build"
+ }
+ ```
+ And then you can run `npm run pack` or `npm run dist` (to package in a distributable format (e.g. DMG, windows installer, NuGet package)).
-Here's an example of what your `config.json` might look like:
+4. Install [required system packages](./docs/multi-platform-build.md).
-**Note**: `nsiTemplate` and `fileAssociation` are completely optional.
+## iconUrl
+Please note — [local icon file url is not accepted](/~https://github.com/atom/grunt-electron-installer/issues/73), must be https/http.
+* If you don't plan to build windows installer, you can omit it.
+* If your project repository is public on GitHub, it will be `https://raw.githubusercontent.com/${info.user}/${info.project}/master/build/icon.ico` by default.
+## Distributable Format Configuration
+In the development `package.json` custom `build` field can be specified to customize distributable format:
```json
-{
- "osx" : {
- "title": "Loopline Systems",
- "background": "assets/osx/installer.png",
- "icon": "assets/osx/mount.icns",
+"build": {
+ "osx": {
+ "title": "computed name from app package.js, you can overwrite",
+ "icon": "build/icon.icns",
"icon-size": 80,
+ "background": "build/background.png",
"contents": [
- { "x": 438, "y": 344, "type": "link", "path": "/Applications" },
- { "x": 192, "y": 344, "type": "file" }
+ {
+ "x": 410,
+ "y": 220,
+ "type": "link",
+ "path": "/Applications"
+ },
+ {
+ "x": 130,
+ "y": 220,
+ "type": "file",
+ "path": "computed path to artifact, do not specify it - will be overwritten"
+ }
]
},
- "win" : {
- "title" : "Loopline Systems",
- "version" : "x.x.x.x",
- "publisher": "Publisher Info",
- "icon" : "assets/win/icon.ico",
- "verbosity": 1,
- "nsiTemplate" : "path/to/custom/installer.nsi.tpl",
- "fileAssociation": {
- "extension": ".loop",
- "fileType": "Loopline Systems File"
- }
- },
- "linux" : {
- "arch" : 64,
- "target" : "deb",
- "version" : "x.x.x.x",
- "title" : "Loopline Systems",
- "comment" : "This is a comment",
- "executable" : "myExec",
- "maintainer": "Dummy Maintainer "
- }
+ "win": "see /~https://github.com/electronjs/windows-installer#usage"
}
```
-Or what your `package.json` might look like:
-
-```json
-{
- "name": "Loopline App",
- "version": "2.6.0",
- "builder": {
- "osx" : {
- "title": "Loopline Systems",
- "background": "assets/osx/installer.png",
- "icon": "assets/osx/mount.icns",
- "icon-size": 80,
- "contents": [
- { "x": 438, "y": 344, "type": "link", "path": "/Applications" },
- { "x": 192, "y": 344, "type": "file" }
- ]
- },
- "win" : {
- "title" : "Loopline Systems",
- "version" : "x.x.x.x",
- "publisher": "Publisher Info",
- "icon" : "assets/win/icon.ico",
- "verbosity": 1,
- "nsiTemplate" : "path/to/custom/installer.nsi.tpl",
- "fileAssociation": {
- "extension": ".loop",
- "fileType": "Loopline Systems File"
- }
- },
- "linux" : {
- "arch" : 64,
- "target" : "deb",
- "version" : "x.x.x.x",
- "title" : "Loopline Systems",
- "comment" : "This is a comment",
- "executable" : "myExec",
- "maintainer": "Dummy Maintainer "
- }
- }
-}
-```
+As you can see, you need to customize OS X options only if you want to provide custom `x, y`.
+Don't customize paths to background and icon, — just follow conventions (if you don't want to use `build` as directory of resources — please create issue to ask ability to customize it).
-**Note:** Need to add something that might have value for others? Consider a [Pull Request](/~https://github.com/loopline-systems/electron-builder/pulls)! ;)
+See [OS X options](https://www.npmjs.com/package/appdmg#json-specification) and [Windows options](/~https://github.com/electronjs/windows-installer#usage).
+# Auto Update
+`electron-builder` produces all required artifacts:
-## How we use it so far
+* `.dmg`: OS X installer, required for OS X user to initial install.
+* `-mac.zip`: required for Squirrel.Mac.
+* `.exe` and `-x64.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.
+* `-amd64.deb` and `-i386.deb`: Linux Debian package. Please note — by default the most effective [xz](https://en.wikipedia.org/wiki/Xz) compression format used.
-When you run `npm run pack`, it will create executables for the Windows and OS X platforms inside of the `dist` directory. It grabs the generated executables afterwards to create the installers out of it.
+You need to deploy somewhere [releases/downloads server](/~https://github.com/GitbookIO/nuts).
+In general, there is a possibility to setup it as a service for all (it is boring to setup own if cloud service is possible).
+May be it will be soon (feel free to file an issue to track progress).
+It is safe since you should sign your app in any case (so, even if server will be compromised, users will not be affected because OS X will just block unsigned/unidentified app).
-directory structure
+# Code signing
+OS X and Windows code singing is supported.
+On a development machine set environment variable `CSC_NAME` to your identity (recommended). Or pass `--sign` parameter.
```
-desktop
- |-- app // actual electron application
- |
- |-- assets // build related assets
- |-- osx // build assets for OS X
- |-- installer.png // -> referenced in builder.json ( dmg background )
- |-- mount.icns // -> use by electron-packager ( actual app icon )
- |-- loopline.icns // -> referenced in builder.json ( dmg background )
- |-- win // build assets for Windows
- |-- icon.ico // -> referenced in builder.json
- |
- |-- dist // out put folder
- |-- osx // generated executables for OS X
- |-- Loopline Systems.app
- |-- Loopline Systems.dmg
- |-- win // generated executables for Windows
- |-- Loopline Systems-win32
- |-- Loopline Systems Setup.exe
- |-- package.json
- |-- config.json
+export CSC_NAME="Developer ID Application: Your Name (code)"
```
-`package.json`:
-
-```json
-{
- "name": "loopline-desktop",
- "version": "1.0.0",
- "description": "",
- "main": "index.js",
- "scripts": {
- "dev": "electron ./app",
-
- "clean": "rm -rf ./dist",
- "clean:osx": "rm -rf ./dist/osx",
- "clean:win": "rm -rf ./dist/win",
-
- "pack": "npm run clean && npm run pack:osx && npm run pack:win",
- "pack:osx": "npm run clean:osx && electron-packager ./app \"Loopline Systems\" --out=dist/osx --platform=darwin --arch=x64 --version=0.36.1 --icon=assets/osx/loopline.icns",
- "pack:win": "npm run clean:win && electron-packager ./app \"Loopline Systems\" --out=dist/win --platform=win32 --arch=ia32 --version=0.36.1 --icon=assets/win/icon.ico",
-
- "build": "npm run build:osx && npm run build:win",
- "build:osx": "npm run pack:osx && electron-builder \"dist/osx/Loopline Systems.app\" --platform=osx --out=\"dist/osx\" --config=builder.json",
- "build:win": "npm run pack:win && electron-builder \"dist/win/Loopline Systems-win32\" --platform=win --out=\"dist/win\" --config=builder.json"
- },
- "dependencies": {
- "electron-packager": "^4.0.2",
- "electron-prebuilt": "^0.36.7",
- "electron-builder": "^2.7.2"
- }
-}
+## Travis, AppVeyor and other CI servers
+To sign app on build server:
+1. [Export](https://developer.apple.com/library/ios/documentation/IDEs/Conceptual/AppDistributionGuide/MaintainingCertificates/MaintainingCertificates.html#//apple_ref/doc/uid/TP40012582-CH31-SW7) certificate.
+ [Strong password](http://security.stackexchange.com/a/54773) must be used. Consider to not use special characters (for bash) because “*values are not escaped when your builds are executed*”.
+2. Upload `*.p12` file (e.g. on [Google Drive](http://www.syncwithtech.org/p/direct-download-link-generator.html)).
+3. Set ([Travis](https://docs.travis-ci.com/user/environment-variables/#Encrypted-Variables) or [AppVeyor](https://ci.appveyor.com/tools/encrypt)) `CSC_LINK` and `CSC_KEY_PASSWORD` environment variables:
+```
+travis encrypt "CSC_LINK='https://drive.google.com/uc?export=download&id=***'" --add
+travis encrypt 'CSC_KEY_PASSWORD=beAwareAboutBashEscaping!!!' --add
```
-**Important note for Windows users:** *If the build process throws an error like `"rm" is not recognized as an internal or external command,
-operable program or batch file.` you may want to use windows counter part `rmdir` or `rimraf` (cross platform) to clean up the distribution folder.*
-
-
-## Contribution
-
-You want to help out and have ideas to make it better? Great!
-
-Create an [issue](/~https://github.com/loopline-systems/electron-builder/issues) and we will tackle it.
-
-If you decide to propose a pull request (even better) make sure `npm test` is succeeding.
-
-## Releases
+# 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).
-For releases, we like to give release names via [adj-noun](/~https://github.com/btford/adj-noun).
-You'll find proper release notes [here](/~https://github.com/loopline-systems/electron-builder/releases).
+# CLI usage
+Execute `node_modules/.bin/build --help` to get actual CLI usage guide.
+In most cases you should not explicitly pass flags, so, we don't want to promote it here ([npm lifecycle](https://docs.npmjs.com/misc/scripts#current-lifecycle-event) is supported and script name is taken in account).
+Want more — please file issue.
-## Related packages
+# Programmatic usage
+See `node_modules/electron-builder/out/electron-builder.d.ts`. [Typings](/~https://github.com/Microsoft/TypeScript/wiki/Typings-for-npm-packages) is supported.
-[grunt-electron-builder-wrapper](https://www.npmjs.com/package/grunt-electron-builder-wrapper) - grunt plugin for electron-builder.
+# Old API (< 2.8)
+Old API is deprecated, but not dropped. You can use it as before. Please note — new API by default produces Squirrel.Windows installer, set `target` to build NSIS:
+ ```
+ build --target=nsis
+ ```
\ No newline at end of file
diff --git a/cli.js b/cli.js
index 5220b9d9867..09629350469 100755
--- a/cli.js
+++ b/cli.js
@@ -14,7 +14,8 @@ var meow = require( 'meow' );
var path = require( 'path' );
var builder = ( require( './' ) ).init();
-var usage = fs.readFileSync( path.join( __dirname, 'usage.txt' ) ).toString();
+var usage = fs.readFileSync(
+ path.join( __dirname, 'docs', 'deprecated-usage.txt' ), 'utf8' );
var cli = meow( usage, {
help : usage,
diff --git a/docs/deployment.md b/docs/deployment.md
new file mode 100644
index 00000000000..a5d6582f98f
--- /dev/null
+++ b/docs/deployment.md
@@ -0,0 +1,34 @@
+# Publishing artifacts
+
+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).
+
+`electron-builder` allows you to just add `GH_TOKEN` environment variable and that's all.
+
+Currently, only GitHub Releases is supported.
+
+`publish` option values:
+
+| Value | Description
+| -------------- | -----------
+| `onTag` | on tag push only
+| `onTagOrDraft` | on tag push or if draft release exists
+| `always` | always publish
+| `never` | never publish
+
+But please consider to use automatic rules and don't specify `publish` explicitly:
+
+* If CI server detected, — `onTagOrDraft`.
+
+ What does it means? [Draft a new release](https://help.github.com/articles/creating-releases/) (version (`v1.0`) must be equals to version (`1.0`) in the application `package.json`) and each CI build will update artifacts. It allows you to get latest artifacts in any time and publish release once it is ready.
+
+* If CI server reports that tag was pushed, — `onTag`.
+
+ Release will be drafted (if doesn't exists) and artifacts published only and only if tag was pushed.
+
+* If [npm script](https://docs.npmjs.com/misc/scripts) named `release`, — `always`.
+
+ Add to `scripts` in the development `package.json`:
+ ```json
+"release": "build"
+```
+ and if you run `npm run release`, release will be drafted (if doesn't exists) and artifacts published.
\ No newline at end of file
diff --git a/usage.txt b/docs/deprecated-usage.txt
similarity index 100%
rename from usage.txt
rename to docs/deprecated-usage.txt
diff --git a/docs/multi-platform-build.md b/docs/multi-platform-build.md
new file mode 100644
index 00000000000..a137944b6d7
--- /dev/null
+++ b/docs/multi-platform-build.md
@@ -0,0 +1,33 @@
+# Multi-platform build
+
+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 OS X. [Cannot be fixed](http://stackoverflow.com/a/12156576).
+* Windows Code Signing works only on Windows. We are going [to fix it](https://developer.mozilla.org/en/docs/Signing_an_executable_with_Authenticode) soon.
+
+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.
+
+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.
+
+## OS X
+
+Use [brew](http://brew.sh) to install required packages.
+
+To build app in distributable format for Windows on OS X:
+```
+brew install Caskroom/cask/xquartz wine mono
+```
+
+To build app in distributable format for Linux on OS X:
+```
+brew install ruby gnu-tar libicns
+gem install fpm
+```
+
+Please note — Windows codesign supported currently only on Windows.
+
+Linux and Windows: not documented yet.
\ No newline at end of file
diff --git a/package.json b/package.json
index 917382c895a..bf5c1bf98dc 100644
--- a/package.json
+++ b/package.json
@@ -11,7 +11,8 @@
"test-win": "npm run pretest && ava",
"test-build": "result=\"$(tape cli.spec.js)\"; echo \"$result\" | tap-spec; echo \"$result\" | tnyan;",
"publish-please": "publish-please",
- "release": "npm prune && npm test && npm run publish-please"
+ "declaration": "dts-generator --name electron-builder --project . --out out/electron-builder.d.ts --indent=' '",
+ "release": "npm prune && npm test && npm run declaration && npm run publish-please"
},
"repository": {
"type": "git",
@@ -75,6 +76,7 @@
"ava-tf": "^0.11.2-beta.0",
"babel-plugin-array-includes": "^2.0.3",
"babel-plugin-transform-es2015-parameters": "^6.5.0",
+ "dts-generator-tf": "^1.7.0-beta.0",
"eslint": "^2.1.0",
"path-sort": "^0.1.0",
"plist": "^1.2.0",
@@ -98,5 +100,6 @@
},
"ava": {
"verbose": true
- }
+ },
+ "typings": "./out/electron-builder.d.ts"
}
diff --git a/src/build-cli.ts b/src/build-cli.ts
index 5649ef31337..4b3a855594b 100644
--- a/src/build-cli.ts
+++ b/src/build-cli.ts
@@ -7,6 +7,8 @@ import { commonArgs } from "./util"
import { printErrorAndExit } from "./promise"
import { tsAwaiter } from "./awaiter"
import cla = require("command-line-args")
+import { readFileSync } from "fs"
+import * as path from "path"
const __awaiter = tsAwaiter
Array.isArray(__awaiter)
@@ -16,19 +18,23 @@ interface CliOptions extends PackagerOptions, PublishOptions {
}
const cli = cla(commonArgs.concat(
- {name: "arch", type: String, description: "ia32, x64 or all (by default)."},
{name: "dist", type: Boolean, alias: "d", description: "Whether to package in a distributable format (e.g. DMG, windows installer, NuGet package)."},
{name: "publish", type: String, alias: "p", description: "Publish artifacts (to GitHub Releases): onTag (on tag push only) or onTagOrDraft (on tag push or if draft release exists)."},
- {name: "sign", type: String},
{name: "platform", type: String, multiple: true, description: "darwin, linux, win32 or all. Current platform (" + process.platform + ") by default."},
- {name: "target", type: String, multiple: true, description: "Installer or package type. For win32 - squirrel (default) or nsis."},
- {name: "help", alias: "h", type: Boolean}
+ {name: "arch", type: String, description: "ia32, x64 or all (by default)."},
+ {name: "target", type: String, multiple: true, description: "Installer or package type. For win32: squirrel (default) or nsis (deprecated)."},
+ {name: "sign", type: String},
+ {name: "help", alias: "h", type: Boolean, description: "Display this usage guide."}
))
const args: CliOptions = cli.parse()
if (args.help) {
- console.log(cli.getUsage())
+ const version = process.env.npm_package_version || JSON.parse(readFileSync(path.join(__dirname, "..", "package.json"), "utf8")).version
+ console.log(cli.getUsage({
+ title: "electron-builder " + version,
+ footer: "Project home: [underline]{/~https://github.com/loopline-systems/electron-builder}"
+ }))
}
else {
build(args)
diff --git a/src/errorMessages.ts b/src/errorMessages.ts
new file mode 100644
index 00000000000..dc2f2145d5d
--- /dev/null
+++ b/src/errorMessages.ts
@@ -0,0 +1,11 @@
+export const buildIsMissed = `Please specify 'build' configuration in the application package.json ('%s'), at least
+
+ build: {
+ "app-bundle-id": "your.id",
+ "app-category-type": "your.app.category.type",
+ "iconUrl": "see /~https://github.com/develar/electron-builder#in-short",
+ }
+}
+
+is required.
+`
\ No newline at end of file
diff --git a/src/linuxPackager.ts b/src/linuxPackager.ts
index 12f74e0f86e..1df823ad9f4 100644
--- a/src/linuxPackager.ts
+++ b/src/linuxPackager.ts
@@ -13,7 +13,7 @@ Array.isArray(__awaiter)
const buildDeb = BluebirdPromise.promisify(init().build)
const tmpDir = BluebirdPromise.promisify(<(config: TmpOptions, callback: (error: Error, path: string, cleanupCallback: () => void) => void) => void>_tpmDir)
-export default class LinuxPackager extends PlatformPackager {
+export class LinuxPackager extends PlatformPackager {
desktopIcons: Promise>
constructor(info: BuildInfo) {
@@ -63,13 +63,13 @@ export default class LinuxPackager extends PlatformPackager {
return "linux"
}
- async packageInDistributableFormat(outDir: string, arch: string): Promise {
+ async packageInDistributableFormat(outDir: string, appOutDir: string): Promise {
const specification: DebOptions = {
version: this.metadata.version,
title: this.metadata.name,
comment: this.metadata.description,
maintainer: this.metadata.author,
- arch: arch === "ia32" ? 32 : 64,
+ arch: this.currentArch === "ia32" ? 32 : 64,
target: "deb",
executable: this.metadata.name,
desktop: `[Desktop Entry]
@@ -88,8 +88,8 @@ export default class LinuxPackager extends PlatformPackager {
}
return await buildDeb({
log: function emptyLog() {/* ignore out */},
- appPath: outDir,
- out: path.dirname(outDir),
+ appPath: appOutDir,
+ out: outDir,
config: {
linux: specification
}
@@ -98,7 +98,7 @@ export default class LinuxPackager extends PlatformPackager {
}
}
-interface DebOptions {
+export interface DebOptions {
title: string
comment: string
diff --git a/src/macPackager.ts b/src/macPackager.ts
index 12dbbb23ab9..128e7c84d07 100644
--- a/src/macPackager.ts
+++ b/src/macPackager.ts
@@ -28,10 +28,10 @@ export default class MacPackager extends PlatformPackager
return "osx"
}
- async pack(platform: string, arch: string, outDir: string): Promise {
- await super.pack(platform, arch, outDir)
+ async pack(platform: string, outDir: string, appOutDir: string): Promise {
+ await super.pack(platform, outDir, appOutDir)
let codeSigningInfo = await this.codeSigningInfo
- return await this.signMac(path.join(outDir, this.metadata.name + ".app"), codeSigningInfo)
+ return await this.signMac(path.join(appOutDir, this.metadata.name + ".app"), codeSigningInfo)
}
private signMac(distPath: string, codeSigningInfo: CodeSigningInfo): Promise {
@@ -49,7 +49,7 @@ export default class MacPackager extends PlatformPackager
}
}
- packageInDistributableFormat(outDir: string, arch: string): Promise {
+ packageInDistributableFormat(outDir: string, appOutDir: string): Promise {
const artifactPath = path.join(outDir, this.metadata.name + "-" + this.metadata.version + ".dmg")
return BluebirdPromise.all([
new BluebirdPromise((resolve, reject) => {
@@ -78,7 +78,7 @@ export default class MacPackager extends PlatformPackager
specification.title = this.metadata.name
}
- specification.contents[1].path = path.join(outDir, this.metadata.name + ".app")
+ specification.contents[1].path = path.join(appOutDir, this.metadata.name + ".app")
const appDmg = require("appdmg")
const emitter = appDmg({
@@ -91,7 +91,7 @@ export default class MacPackager extends PlatformPackager
})
.then(() => this.dispatchArtifactCreated(artifactPath)),
- this.zipMacApp(outDir)
+ this.zipMacApp(appOutDir)
.then(it => this.dispatchArtifactCreated(it))
])
}
diff --git a/src/packager.ts b/src/packager.ts
index 4c88d4e52df..58be17be730 100644
--- a/src/packager.ts
+++ b/src/packager.ts
@@ -10,7 +10,8 @@ import { AppMetadata, InfoRetriever } from "./repositoryInfo"
import { PackagerOptions, PlatformPackager, BuildInfo, DevMetadata } from "./platformPackager"
import MacPackager from "./macPackager"
import WinPackager from "./winPackager"
-import LinuxPackager from "./linuxPackager"
+import * as errorMessages from "./errorMessages"
+import * as util from "util"
const __awaiter = tsAwaiter
Array.isArray(__awaiter)
@@ -72,10 +73,12 @@ export class Packager implements BuildInfo {
for (let arch of archs) {
await this.installAppDependencies(arch)
- const outDir = path.join(this.projectDir, "dist", this.metadata.name + "-" + platform + "-" + arch)
- await helper.pack(platform, arch, outDir)
+ helper.currentArch = arch
+ const outDir = path.join(this.projectDir, "dist")
+ const appOutDir = path.join(outDir, this.metadata.name + "-" + platform + "-" + arch)
+ await helper.pack(platform, outDir, appOutDir)
if (this.options.dist) {
- distTasks.push(helper.packageInDistributableFormat(outDir, arch))
+ distTasks.push(helper.packageInDistributableFormat(outDir, appOutDir))
}
}
}
@@ -101,10 +104,7 @@ export class Packager implements BuildInfo {
}
case "linux":
- {
- const helperClass: typeof LinuxPackager = require("./linuxPackager").default
- return new helperClass(this)
- }
+ return new (require("./linuxPackager").LinuxPackager)(this)
default:
throw new Error("Unsupported platform: " + platform)
@@ -120,7 +120,7 @@ export class Packager implements BuildInfo {
required = false
}
- let absoluteAppPath = path.join(this.projectDir, customAppPath)
+ const absoluteAppPath = path.join(this.projectDir, customAppPath)
try {
fs.accessSync(absoluteAppPath)
}
@@ -152,14 +152,7 @@ export class Packager implements BuildInfo {
reportError("version")
}
else if (metadata.build == null) {
- throw new Error("Please specify 'build' configuration in the application package.json ('" + appPackageFile + "'), at least\n\n" +
- JSON.stringify({
- build: {
- "app-bundle-id": "your.id",
- "app-category-type": "your.app.category.type",
- "iconUrl": "see /~https://github.com/develar/electron-complete-builder#in-short",
- }
- }, null, " ") + "\n\n is required.\n")
+ throw new Error(util.format(errorMessages.buildIsMissed, appPackageFile))
}
else if (metadata.author == null) {
reportError("author")
@@ -172,7 +165,7 @@ export class Packager implements BuildInfo {
}
else {
log("Skipping app dependencies installation because dev and app dependencies are not separated")
- return Promise.resolve(null)
+ return BluebirdPromise.resolve(null)
}
}
}
diff --git a/src/platformPackager.ts b/src/platformPackager.ts
index 9ad4c48256b..4df0b31a0b5 100644
--- a/src/platformPackager.ts
+++ b/src/platformPackager.ts
@@ -8,6 +8,8 @@ import packager = require("electron-packager-tf")
const __awaiter = tsAwaiter
Array.isArray(__awaiter)
+const pack = BluebirdPromise.promisify(packager)
+
export interface DevMetadata extends Metadata {
build: DevBuildMetadata
}
@@ -61,6 +63,8 @@ export abstract class PlatformPackager implements ProjectMetadataProvider {
customDistOptions: DC
+ currentArch: string
+
protected abstract getBuildConfigurationKey(): string
constructor(protected info: BuildInfo) {
@@ -79,42 +83,40 @@ export abstract class PlatformPackager implements ProjectMetadataProvider {
this.info.eventEmitter.emit("artifactCreated", path)
}
- pack(platform: string, arch: string, outDir: string): Promise {
- return new BluebirdPromise((resolve, reject) => {
- const version = this.metadata.version
- let buildVersion = version
- const buildNumber = process.env.TRAVIS_BUILD_NUMBER || process.env.APPVEYOR_BUILD_NUMBER || process.env.CIRCLE_BUILD_NUM
- if (buildNumber != null) {
- buildVersion += "." + buildNumber
+ pack(platform: string, outDir: string, appOutDir: string): Promise {
+ const version = this.metadata.version
+ let buildVersion = version
+ const buildNumber = process.env.TRAVIS_BUILD_NUMBER || process.env.APPVEYOR_BUILD_NUMBER || process.env.CIRCLE_BUILD_NUM
+ if (buildNumber != null) {
+ buildVersion += "." + buildNumber
+ }
+
+ const options = Object.assign({
+ dir: this.info.appDir,
+ out: outDir,
+ name: this.metadata.name,
+ platform: platform,
+ arch: this.currentArch,
+ version: this.info.electronVersion,
+ icon: path.join(this.projectDir, "build", "icon"),
+ asar: true,
+ overwrite: true,
+ "app-version": version,
+ "build-version": buildVersion,
+ "version-string": {
+ CompanyName: this.metadata.author,
+ FileDescription: this.metadata.description,
+ ProductVersion: version,
+ FileVersion: buildVersion,
+ ProductName: this.metadata.name,
+ InternalName: this.metadata.name,
}
+ }, this.metadata.build, {"tmpdir": false})
- const options = Object.assign({
- dir: this.info.appDir,
- out: path.dirname(outDir),
- name: this.metadata.name,
- platform: platform,
- arch: arch,
- version: this.info.electronVersion,
- icon: path.join(this.projectDir, "build", "icon"),
- asar: true,
- overwrite: true,
- "app-version": version,
- "build-version": buildVersion,
- "version-string": {
- CompanyName: this.metadata.author,
- FileDescription: this.metadata.description,
- ProductVersion: version,
- FileVersion: buildVersion,
- ProductName: this.metadata.name,
- InternalName: this.metadata.name,
- }
- }, this.metadata.build, {"tmpdir": false})
-
- // this option only for windows-installer
- delete options.iconUrl
- packager(options, error => error == null ? resolve(null) : reject(error))
- })
+ // this option only for windows-installer
+ delete options.iconUrl
+ return pack(options)
}
- abstract packageInDistributableFormat(outDir: string, arch: string): Promise
+ abstract packageInDistributableFormat(outDir: string, appOutDir: string): Promise
}
\ No newline at end of file
diff --git a/src/repositoryInfo.ts b/src/repositoryInfo.ts
index 397d447e6a7..97e9c478089 100644
--- a/src/repositoryInfo.ts
+++ b/src/repositoryInfo.ts
@@ -6,7 +6,7 @@ import * as path from "path"
const __awaiter = tsAwaiter
Array.isArray(__awaiter)
-interface RepositoryInfo {
+export interface RepositoryInfo {
url: string
}
diff --git a/src/util.ts b/src/util.ts
index dce100b6ff8..9d385166abc 100644
--- a/src/util.ts
+++ b/src/util.ts
@@ -49,13 +49,13 @@ export function installDependencies(appDir: string, arch: string, electronVersio
})
}
-interface BaseExecOptions {
+export interface BaseExecOptions {
cwd?: string
env?: any
stdio?: any
}
-interface ExecOptions extends BaseExecOptions {
+export interface ExecOptions extends BaseExecOptions {
customFds?: any
encoding?: string
timeout?: number
@@ -63,7 +63,7 @@ interface ExecOptions extends BaseExecOptions {
killSignal?: string
}
-interface SpawnOptions extends BaseExecOptions {
+export interface SpawnOptions extends BaseExecOptions {
custom?: any
detached?: boolean
}
diff --git a/src/winPackager.ts b/src/winPackager.ts
index 7730417c530..27a36c517b8 100644
--- a/src/winPackager.ts
+++ b/src/winPackager.ts
@@ -49,21 +49,25 @@ export default class WinPackager extends PlatformPackager {
return "win"
}
- pack(platform: string, arch: string, outDir: string): Promise {
+ pack(platform: string, outDir: string, appOutDir: string): Promise {
if (this.options.dist && !this.isNsis) {
- const installerOut = outDir + "-installer"
+ const installerOut = this.computeDistOut(outDir)
log("Removing %s", installerOut)
return BluebirdPromise.all([
- super.pack(platform, arch, outDir),
+ super.pack(platform, outDir, appOutDir),
emptyDir(installerOut)
])
}
else {
- return super.pack(platform, arch, outDir)
+ return super.pack(platform, outDir, appOutDir)
}
}
- async packageInDistributableFormat(outDir: string, arch: string): Promise {
+ private computeDistOut(outDir: string): string {
+ return path.join(outDir, (this.isNsis ? "nsis" : "win") + (this.currentArch === "x64" ? "-x64" : ""))
+ }
+
+ async packageInDistributableFormat(outDir: string, appOutDir: string): Promise {
let iconUrl = this.metadata.build.iconUrl
if (!iconUrl) {
if (this.customDistOptions != null) {
@@ -85,14 +89,14 @@ export default class WinPackager extends PlatformPackager {
const certificateFile = await this.certFilePromise
const version = this.metadata.version
- const outputDirectory = outDir + "-" + (this.isNsis ? "nsis" : "installer")
+ const installerOutDir = this.computeDistOut(outDir)
const appName = this.metadata.name
- const archSuffix = arch === "x64" ? "-x64" : ""
- const installerExePath = path.join(outputDirectory, appName + "Setup-" + version + archSuffix + ".exe")
+ const archSuffix = this.currentArch === "x64" ? "-x64" : ""
+ const installerExePath = path.join(installerOutDir, appName + "Setup-" + version + archSuffix + ".exe")
const options = Object.assign({
name: this.metadata.name,
- appDirectory: outDir,
- outputDirectory: outputDirectory,
+ appDirectory: appOutDir,
+ outputDirectory: installerOutDir,
productName: appName,
version: version,
description: this.metadata.description,
@@ -108,9 +112,8 @@ export default class WinPackager extends PlatformPackager {
}
try {
- await new BluebirdPromise((resolve, reject) => {
- require("electron-winstaller-temp-fork").build(options, (error: Error) => error == null ? resolve(null) : reject(error))
- })
+ const build = <(options: any, callback: (error: Error) => void) => void>require("electron-winstaller-temp-fork").build
+ await BluebirdPromise.promisify(build)(options)
}
catch (e) {
if (!e.message.includes("Unable to set icon")) {
@@ -132,18 +135,18 @@ export default class WinPackager extends PlatformPackager {
}
return await BluebirdPromise.all([
- renameFile(path.join(outputDirectory, appName + "Setup.exe"), installerExePath)
+ renameFile(path.join(installerOutDir, appName + "Setup.exe"), installerExePath)
.then(it => this.dispatchArtifactCreated(it)),
- renameFile(path.join(outputDirectory, appName + "-" + version + "-full.nupkg"), path.join(outputDirectory, appName + "-" + version + archSuffix + "-full.nupkg"))
+ renameFile(path.join(installerOutDir, appName + "-" + version + "-full.nupkg"), path.join(installerOutDir, appName + "-" + version + archSuffix + "-full.nupkg"))
.then(it => this.dispatchArtifactCreated(it))
])
}
private async nsis(options: any, installerFile: string) {
- const nsisBuild = <(options: any, callback: (error: Error) => void) => void>require("../lib/win").init().build
+ const build = <(options: any, callback: (error: Error) => void) => void>require("../lib/win").init().build
// nsis cannot create dir
await emptyDir(options.outputDirectory)
- return await BluebirdPromise.promisify(nsisBuild)(Object.assign(options, {
+ return await BluebirdPromise.promisify(build)(Object.assign(options, {
log: console.log,
appPath: options.appDirectory,
out: options.outputDirectory,
diff --git a/tsconfig.json b/tsconfig.json
index 921c8cb7944..6a9a0ab4c4a 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -47,6 +47,7 @@
"src/build-cli.ts",
"src/builder.ts",
"src/codeSign.ts",
+ "src/errorMessages.ts",
"src/gitHubPublisher.ts",
"src/gitHubRequest.ts",
"src/httpRequest.ts",
diff --git a/typings/command-line-args.d.ts b/typings/command-line-args.d.ts
index ba806231347..40829248b38 100644
--- a/typings/command-line-args.d.ts
+++ b/typings/command-line-args.d.ts
@@ -6,7 +6,10 @@ declare module "command-line-args" {
}
interface UsageOptions {
- hide: Array
+ hide?: Array
+
+ title?: string
+ footer?: string
}
function describe(options: Array): Options
diff --git a/typings/json-parse-helpfulerror.d.ts b/typings/json-parse-helpfulerror.d.ts
index 773f1cf7152..814303a6818 100644
--- a/typings/json-parse-helpfulerror.d.ts
+++ b/typings/json-parse-helpfulerror.d.ts
@@ -1,3 +1,3 @@
declare module "json-parse-helpfulerror" {
- export function parse(data: string): any
+ function parse(data: string): any
}
\ No newline at end of file