diff --git a/docs/Options.md b/docs/Options.md
index 625ae43c233..af9be8f4e04 100644
--- a/docs/Options.md
+++ b/docs/Options.md
@@ -49,7 +49,6 @@ Don't customize paths to background and icon, — just follow conventions.
| 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 MacOS and as [Application User Model ID](https://msdn.microsoft.com/en-us/library/windows/desktop/dd378459(v=vs.85).aspx) for Windows (NSIS target only, Squirrel.Windows not supported).
Defaults to com.electron.${name}
. It is strongly recommended that an explicit ID be set.
-| category | *macOS-only.* The application category type, as shown in the Finder via *View -> Arrange by Application Category* when viewing the Applications directory.
For example, "category": "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).
| copyright | The human-readable copyright line for the app. Defaults to `Copyright © year author`.
| 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.
Node modules, that must be unpacked, will be detected automatically, you don’t need to explicitly set asar.unpackDir
- please file issue if this doesn’t work.
| productName | See [AppMetadata.productName](#AppMetadata-productName).
@@ -76,12 +75,14 @@ MacOS specific build options.
| Name | Description
| --- | ---
+| category | The application category type, as shown in the Finder via *View -> Arrange by Application Category* when viewing the Applications directory.
For example, "category": "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).
| 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).
| icon | The path to application icon. Defaults to `build/icon.icns` (consider using this convention instead of complicating your configuration).
| entitlements | The path to entitlements file for signing the app. build/entitlements.mac.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.mac.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.
| bundleVersion | The `CFBundleVersion`. Do not use it unless [you need to](see (https://github.com/electron-userland/electron-builder/issues/565#issuecomment-230678643)).
+| helperBundleId | The bundle identifier to use in the application helper's plist. Defaults to `${appBundleIdentifier}.helper`.
### `.build.dmg`
@@ -142,7 +143,7 @@ See [NSIS target notes](https://github.com/electron-userland/electron-builder/wi
| installerHeaderIcon | *one-click installer only.* The path to header icon (above the progress bar), relative to the project directory. Defaults to `build/installerHeaderIcon.ico` or application icon.
| include | The path to NSIS include script to customize installer. Defaults to `build/installer.nsh`. See [Custom NSIS script](https://github.com/electron-userland/electron-builder/wiki/NSIS#custom-nsis-script).
| script | The path to NSIS script to customize installer. Defaults to `build/installer.nsi`. See [Custom NSIS script](https://github.com/electron-userland/electron-builder/wiki/NSIS#custom-nsis-script).
-| language | * LCID Dec, defaults to `1033`(`English - United States`, see https://msdn.microsoft.com/en-au/goglobal/bb964664.aspx?f=255&MSPPError=-2147217396).
+| language | * [LCID Dec](https://msdn.microsoft.com/en-au/goglobal/bb964664.aspx), defaults to `1033`(`English - United States`).
### `.build.linux`
@@ -151,11 +152,14 @@ Linux specific build options.
| Name | Description
| --- | ---
+| category | The [application category](https://specifications.freedesktop.org/menu-spec/latest/apa.html#main-category-registry).
+| packageCategory | The [package category](https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Section). Not applicable for AppImage.
| description | As [description](#AppMetadata-description) from application package.json, but allows you to specify different for Linux.
| target | Target package type: list of AppImage
, deb
, rpm
, freebsd
, pacman
, p5p
, apk
, 7z
, zip
, tar.xz
, tar.lz
, tar.gz
, tar.bz2
. Defaults to AppImage
.
The most effective [xz](https://en.wikipedia.org/wiki/Xz) compression format used by default.
Only deb
and AppImage
is tested. Feel free to file issues for rpm
and other package formats.
| synopsis | *deb-only.* The [short description](https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Description).
| maintainer | The maintainer. Defaults to [author](#AppMetadata-author).
| vendor | The vendor. Defaults to [author](#AppMetadata-author).
+| desktop | The [Desktop file](https://developer.gnome.org/integration-guide/stable/desktop-files.html.en) entries.
| compression | *deb-only.* The compression type, one of `gz`, `bzip2`, `xz`. Defaults to `xz`.
| depends | Package dependencies. Defaults to `["libappindicator1", "libnotify-bin"]`.
diff --git a/src/appInfo.ts b/src/appInfo.ts
index 92ca7239b51..289224d1b4c 100644
--- a/src/appInfo.ts
+++ b/src/appInfo.ts
@@ -61,15 +61,6 @@ export class AppInfo {
return this.metadata.name
}
- get category() {
- const metadata = this.devMetadata.build
- const old = (metadata)["app-category-type"]
- if (old != null) {
- warn('"app-category-type" is deprecated — please use "category" instead')
- }
- return metadata.category || old
- }
-
get copyright(): string {
const metadata = this.devMetadata.build
const old = (metadata)["app-copyright"]
diff --git a/src/linuxPackager.ts b/src/linuxPackager.ts
index 0a437937e34..68a55105b2e 100755
--- a/src/linuxPackager.ts
+++ b/src/linuxPackager.ts
@@ -61,7 +61,7 @@ export class LinuxPackager extends PlatformPackager {
async pack(outDir: string, arch: Arch, targets: Array, postAsyncTasks: Array>): Promise {
const appOutDir = this.computeAppOutDir(outDir, arch)
- await this.doPack(await this.computePackOptions(), outDir, appOutDir, this.platform.nodeName, arch, this.platformSpecificBuildOptions)
+ await this.doPack(outDir, appOutDir, this.platform.nodeName, arch, this.platformSpecificBuildOptions)
postAsyncTasks.push(this.packageInDistributableFormat(outDir, appOutDir, arch, targets))
}
diff --git a/src/macPackager.ts b/src/macPackager.ts
index 8a3c311a839..8412ed72e01 100644
--- a/src/macPackager.ts
+++ b/src/macPackager.ts
@@ -67,14 +67,13 @@ export default class MacPackager extends PlatformPackager {
}
async pack(outDir: string, arch: Arch, targets: Array, postAsyncTasks: Array>): Promise {
- const packOptions = await this.computePackOptions()
let nonMasPromise: Promise | null = null
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, this.platform.nodeName, arch, this.platformSpecificBuildOptions)
+ nonMasPromise = this.doPack(outDir, appOutDir, this.platform.nodeName, arch, this.platformSpecificBuildOptions)
.then(() => this.sign(appOutDir, null))
.then(() => {
this.packageInDistributableFormat(appOutDir, targets, postAsyncTasks)
@@ -86,7 +85,7 @@ export default class MacPackager extends PlatformPackager {
const appOutDir = path.join(outDir, "mas")
const masBuildOptions = deepAssign({}, this.platformSpecificBuildOptions, (this.devMetadata.build).mas)
//noinspection JSUnusedGlobalSymbols
- await this.doPack(packOptions, outDir, appOutDir, "mas", arch, masBuildOptions)
+ await this.doPack(outDir, appOutDir, "mas", arch, masBuildOptions)
await this.sign(appOutDir, masBuildOptions)
}
diff --git a/src/metadata.ts b/src/metadata.ts
index 1c9c7c72bde..88d1ae2a413 100755
--- a/src/metadata.ts
+++ b/src/metadata.ts
@@ -1,5 +1,5 @@
import { AsarOptions } from "asar-electron-builder"
-import { ElectronPackagerOptions } from "./packager/dirPackager"
+import { PlatformPackager } from "./platformPackager"
export interface Metadata {
readonly repository?: string | RepositoryInfo | null
@@ -91,15 +91,6 @@ export interface BuildMetadata {
*/
readonly appId?: string | null
- /*
- *macOS-only.* The application category type, as shown in the Finder via *View -> Arrange by Application Category* when viewing the Applications directory.
-
- For example, `"category": "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).
- */
- readonly category?: string | null
-
/*
The human-readable copyright line for the app. Defaults to `Copyright © year author`.
*/
@@ -219,7 +210,11 @@ export interface BuildMetadata {
export interface AfterPackContext {
readonly appOutDir: string
- readonly options: ElectronPackagerOptions
+
+ // deprecated
+ readonly options: any
+
+ readonly packager: PlatformPackager
}
/*
@@ -228,6 +223,15 @@ export interface AfterPackContext {
MacOS specific build options.
*/
export interface MacOptions extends PlatformSpecificBuildOptions {
+ /*
+ The application category type, as shown in the Finder via *View -> Arrange by Application Category* when viewing the Applications directory.
+
+ For example, `"category": "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).
+ */
+ readonly category?: string | null
+
/*
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).
*/
@@ -262,6 +266,11 @@ export interface MacOptions extends PlatformSpecificBuildOptions {
The `CFBundleVersion`. Do not use it unless [you need to](see (https://github.com/electron-userland/electron-builder/issues/565#issuecomment-230678643)).
*/
readonly bundleVersion?: string | null
+
+ /*
+ The bundle identifier to use in the application helper's plist. Defaults to `${appBundleIdentifier}.helper`.
+ */
+ readonly helperBundleId?: string | null
}
/*
@@ -432,7 +441,7 @@ export interface NsisOptions {
readonly script?: string | null
/*
- * LCID Dec, defaults to `1033`(`English - United States`, see https://msdn.microsoft.com/en-au/goglobal/bb964664.aspx?f=255&MSPPError=-2147217396).
+ * [LCID Dec](https://msdn.microsoft.com/en-au/goglobal/bb964664.aspx), defaults to `1033`(`English - United States`).
*/
readonly language?: string | null
}
@@ -443,6 +452,16 @@ export interface NsisOptions {
Linux specific build options.
*/
export interface LinuxBuildOptions extends PlatformSpecificBuildOptions {
+ /*
+ The [application category](https://specifications.freedesktop.org/menu-spec/latest/apa.html#main-category-registry).
+ */
+ readonly category?: string | null
+
+ /*
+ The [package category](https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-Section). Not applicable for AppImage.
+ */
+ readonly packageCategory?: string | null
+
/*
As [description](#AppMetadata-description) from application package.json, but allows you to specify different for Linux.
*/
@@ -475,8 +494,10 @@ export interface LinuxBuildOptions extends PlatformSpecificBuildOptions {
// should be not documented, only to experiment
readonly fpm?: Array | null
- //.desktop file template
- readonly desktop?: string | null
+ /**
+ The [Desktop file](https://developer.gnome.org/integration-guide/stable/desktop-files.html.en) entries.
+ */
+ readonly desktop?: { [key: string]: string; } | null
readonly afterInstall?: string | null
readonly afterRemove?: string | null
diff --git a/src/packager/dirPackager.ts b/src/packager/dirPackager.ts
index b80bc220b12..6493e52907f 100644
--- a/src/packager/dirPackager.ts
+++ b/src/packager/dirPackager.ts
@@ -1,7 +1,6 @@
import { Promise as BluebirdPromise } from "bluebird"
import { emptyDir } from "fs-extra-p"
import { warn } from "../util/log"
-import { AppInfo } from "../appInfo"
import { PlatformPackager } from "../platformPackager"
const downloadElectron: (options: any) => Promise = BluebirdPromise.promisify(require("electron-download"))
@@ -10,17 +9,6 @@ const extract: any = BluebirdPromise.promisify(require("extract-zip"))
//noinspection JSUnusedLocalSymbols
const __awaiter = require("../util/awaiter")
-export interface ElectronPackagerOptions {
- "extend-info"?: string
-
- appInfo: AppInfo
- platformPackager: PlatformPackager
-
- "helper-bundle-id"?: string | null
-
- ignore?: any
-}
-
function createDownloadOpts(opts: any, platform: string, arch: string, electronVersion: string) {
const downloadOpts = Object.assign({
cache: opts.cache,
@@ -40,15 +28,15 @@ function subOptionWarning (properties: any, optionName: any, parameter: any, val
properties[parameter] = value
}
-export async function pack(opts: ElectronPackagerOptions, out: string, platform: string, arch: string, electronVersion: string, initializeApp: () => Promise) {
+export async function pack(packager: PlatformPackager, out: string, platform: string, arch: string, electronVersion: string, initializeApp: () => Promise) {
const zipPath = (await BluebirdPromise.all([
- downloadElectron(createDownloadOpts(opts, platform, arch, electronVersion)),
+ downloadElectron(createDownloadOpts(packager.devMetadata.build, platform, arch, electronVersion)),
emptyDir(out)
]))[0]
await extract(zipPath, {dir: out})
if (platform === "darwin" || platform === "mas") {
- await(require("./mac")).createApp(opts, out, initializeApp)
+ await(require("./mac")).createApp(packager, out, initializeApp)
}
else {
await initializeApp()
diff --git a/src/packager/mac.ts b/src/packager/mac.ts
index 118756e4b1a..3da9f61bcf0 100644
--- a/src/packager/mac.ts
+++ b/src/packager/mac.ts
@@ -1,11 +1,10 @@
-import { ElectronPackagerOptions } from "./dirPackager"
import { rename, readFile, writeFile, copy, unlink } from "fs-extra-p"
import * as path from "path"
import { parse as parsePlist, build as buildPlist } from "plist"
import { Promise as BluebirdPromise } from "bluebird"
import { use, asArray } from "../util/util"
-import { normalizeExt } from "../platformPackager"
-import { FileAssociation } from "../metadata"
+import { normalizeExt, PlatformPackager } from "../platformPackager"
+import { warn } from "../util/log"
//noinspection JSUnusedLocalSymbols
const __awaiter = require("../util/awaiter")
@@ -28,8 +27,8 @@ function filterCFBundleIdentifier(identifier: string) {
return identifier.replace(/ /g, "-").replace(/[^a-zA-Z0-9.-]/g, "")
}
-export async function createApp(opts: ElectronPackagerOptions, appOutDir: string, initializeApp: () => Promise) {
- const appInfo = opts.appInfo
+export async function createApp(packager: PlatformPackager, appOutDir: string, initializeApp: () => Promise) {
+ const appInfo = packager.appInfo
const appFilename = appInfo.productFilename
const contentsPath = path.join(appOutDir, "Electron.app", "Contents")
@@ -40,9 +39,11 @@ export async function createApp(opts: ElectronPackagerOptions, appOutDir: string
const helperEHPlistFilename = path.join(frameworksPath, "Electron Helper EH.app", "Contents", "Info.plist")
const helperNPPlistFilename = path.join(frameworksPath, "Electron Helper NP.app", "Contents", "Info.plist")
+ const buildMetadata = packager.devMetadata.build!
+
const result = await BluebirdPromise.all([
initializeApp(),
- BluebirdPromise.map([appPlistFilename, helperPlistFilename, helperEHPlistFilename, helperNPPlistFilename, opts["extend-info"]], it => it == null ? it : readFile(it, "utf8"))
+ BluebirdPromise.map([appPlistFilename, helperPlistFilename, helperEHPlistFilename, helperNPPlistFilename, (buildMetadata)["extend-info"]], it => it == null ? it : readFile(it, "utf8"))
])
const fileContents: Array = result[1]!
const appPlist = parsePlist(fileContents[0])
@@ -56,9 +57,13 @@ export async function createApp(opts: ElectronPackagerOptions, appOutDir: string
}
const appBundleIdentifier = filterCFBundleIdentifier(appInfo.id)
- const helperBundleIdentifier = filterCFBundleIdentifier(opts["helper-bundle-id"] || `${appBundleIdentifier}.helper`)
- const packager = opts.platformPackager
+ const oldHelperBundleId = (buildMetadata)["helper-bundle-id"]
+ if (oldHelperBundleId != null) {
+ warn("build.helper-bundle-id is deprecated, please set as build.mac.helperBundleId")
+ }
+ const helperBundleIdentifier = filterCFBundleIdentifier(packager.platformSpecificBuildOptions.helperBundleId || oldHelperBundleId || `${appBundleIdentifier}.helper`)
+
const icon = await packager.getIconPath()
const oldIcon = appPlist.CFBundleIconFile
if (icon != null) {
@@ -88,7 +93,7 @@ export async function createApp(opts: ElectronPackagerOptions, appOutDir: string
})
use(appInfo.buildVersion, it => appPlist.CFBundleVersion = it)
- const protocols = asArray(packager.devMetadata.build.protocols).concat(asArray(packager.platformSpecificBuildOptions.protocols))
+ const protocols = asArray(buildMetadata.protocols).concat(asArray(packager.platformSpecificBuildOptions.protocols))
if (protocols.length > 0) {
appPlist.CFBundleURLTypes = protocols.map(protocol => {
const schemes = asArray(protocol.schemes)
@@ -104,7 +109,7 @@ export async function createApp(opts: ElectronPackagerOptions, appOutDir: string
const fileAssociations = packager.getFileAssociations()
if (fileAssociations.length > 0) {
- appPlist.CFBundleDocumentTypes = await BluebirdPromise.map(fileAssociations, async fileAssociation => {
+ appPlist.CFBundleDocumentTypes = await BluebirdPromise.map(fileAssociations, async fileAssociation => {
const extensions = asArray(fileAssociation.ext).map(normalizeExt)
const customIcon = await packager.getResource(fileAssociation.icon, `${extensions[0]}.icns`)
// todo rename electron.icns
@@ -117,7 +122,13 @@ export async function createApp(opts: ElectronPackagerOptions, appOutDir: string
})
}
- use(appInfo.category, it => appPlist.LSApplicationCategoryType = it)
+ const oldCategory = (buildMetadata)["app-category-type"]
+ if (oldCategory != null) {
+ warn("app-category-type is deprecated, please set as build.mac.category")
+ }
+
+ let category = packager.platformSpecificBuildOptions.category || (buildMetadata).category || oldCategory
+ use(category || oldCategory, it => appPlist.LSApplicationCategoryType = it)
use(appInfo.copyright, it => appPlist.NSHumanReadableCopyright = it)
const promises: Array> = [
diff --git a/src/platformPackager.ts b/src/platformPackager.ts
index fcbce357b1c..abc54ceba52 100644
--- a/src/platformPackager.ts
+++ b/src/platformPackager.ts
@@ -12,7 +12,7 @@ import { checkFileInArchive, createAsarArchive } from "./asarUtil"
import { warn, log, task } from "./util/log"
import { AppInfo } from "./appInfo"
import { copyFiltered, devDependencies } from "./util/filter"
-import { ElectronPackagerOptions, pack } from "./packager/dirPackager"
+import { pack } from "./packager/dirPackager"
import { TmpDir } from "./util/tmp"
import { FileMatchOptions, FileMatcher, FilePattern, deprecatedUserIgnoreFilter } from "./fileMatcher"
import { BuildOptions } from "./builder"
@@ -164,7 +164,7 @@ export abstract class PlatformPackager
return this.getFileMatchers(isResources ? "extraResources" : "extraFiles", this.projectDir, base, true, fileMatchOptions, customBuildOptions)
}
- protected async doPack(options: ElectronPackagerOptions, outDir: string, appOutDir: string, platformName: string, arch: Arch, platformSpecificBuildOptions: DC) {
+ protected async doPack(outDir: string, appOutDir: string, platformName: string, arch: Arch, platformSpecificBuildOptions: DC) {
const asarOptions = this.computeAsarOptions(platformSpecificBuildOptions)
const fileMatchOptions: FileMatchOptions = {
arch: Arch[arch],
@@ -176,7 +176,7 @@ export abstract class PlatformPackager
const resourcesPath = this.platform === Platform.MAC ? path.join(appOutDir, "Electron.app", "Contents", "Resources") : path.join(appOutDir, "resources")
- const p = pack(options, appOutDir, platformName, Arch[arch], this.info.electronVersion, async() => {
+ const p = pack(this, appOutDir, platformName, Arch[arch], this.info.electronVersion, async() => {
const ignoreFiles = new Set([path.resolve(this.info.appDir, outDir), path.resolve(this.info.appDir, this.buildResourcesDir)])
if (!this.info.isTwoPackageJsonProjectLayoutUsed) {
const result = await devDependencies(this.info.appDir)
@@ -242,7 +242,8 @@ export abstract class PlatformPackager
if (afterPack != null) {
await afterPack({
appOutDir: appOutDir,
- options: options,
+ options: this.devMetadata.build,
+ packager: this,
})
}
@@ -253,20 +254,6 @@ export abstract class PlatformPackager
return BluebirdPromise.resolve(null)
}
- protected async computePackOptions(): Promise {
- //noinspection JSUnusedGlobalSymbols
- const appInfo = this.appInfo
- const options: any = Object.assign({
- appInfo: appInfo,
- platformPackager: this,
- }, this.devMetadata.build)
-
- delete options.osx
- delete options.win
- delete options.linux
- return options
- }
-
async getIconPath(): Promise {
return null
}
diff --git a/src/targets/LinuxTargetHelper.ts b/src/targets/LinuxTargetHelper.ts
index b452f936aa6..fa95a46dce5 100644
--- a/src/targets/LinuxTargetHelper.ts
+++ b/src/targets/LinuxTargetHelper.ts
@@ -1,6 +1,6 @@
import { readdir, outputFile, ensureDir } from "fs-extra-p"
import * as path from "path"
-import { exec, debug } from "../util/util"
+import { exec, debug, isEmptyOrSpaces } from "../util/util"
import { PlatformPackager } from "../platformPackager"
import { Promise as BluebirdPromise } from "bluebird"
import { LinuxBuildOptions } from "../metadata"
@@ -66,24 +66,34 @@ export class LinuxTargetHelper {
return iconPath == null ? await this.packager.getDefaultIcon("icns") : path.resolve(this.packager.projectDir, iconPath)
}
- async computeDesktopEntry(exec?: string, extra?: string): Promise {
+ async computeDesktopEntry(platformSpecificBuildOptions: LinuxBuildOptions, exec?: string, extra?: { [key: string]: string; }): Promise {
const appInfo = this.packager.appInfo
- const custom = this.packager.platformSpecificBuildOptions.desktop
- if (custom != null) {
- return custom
- }
-
const productFilename = appInfo.productFilename
const tempFile = await this.packager.getTempFile(`${productFilename}.desktop`)
- await outputFile(tempFile, this.packager.platformSpecificBuildOptions.desktop || `[Desktop Entry]
-Name=${appInfo.productName}
-Comment=${this.packager.platformSpecificBuildOptions.description || appInfo.description}
-Exec=${(exec == null ? `"${installPrefix}/${productFilename}/${productFilename}"` : exec)}
-Terminal=false
-Type=Application
-Icon=${appInfo.name}
-${extra == null ? "" : `${extra}\n`}`)
+
+ const desktopMeta: any = Object.assign({
+ Name: appInfo.productName,
+ Comment: platformSpecificBuildOptions.description || appInfo.description,
+ Exec: exec == null ? `"${installPrefix}/${productFilename}/${productFilename}"` : exec,
+ Terminal: "false",
+ Type: "Application",
+ Icon: appInfo.name,
+ }, extra, platformSpecificBuildOptions.desktop)
+
+ const category = platformSpecificBuildOptions.category
+ if (!isEmptyOrSpaces(category)) {
+ desktopMeta.Categories = category
+ }
+
+ let data = `[Desktop Entry]`
+ for (let name of Object.keys(desktopMeta)) {
+ const value = desktopMeta[name]
+ data += `\n${name}=${value}`
+ }
+ data += "\n"
+
+ await outputFile(tempFile, data)
return tempFile
}
diff --git a/src/targets/appImage.ts b/src/targets/appImage.ts
index 1a2b9a487a6..be81b00f2a7 100644
--- a/src/targets/appImage.ts
+++ b/src/targets/appImage.ts
@@ -6,6 +6,7 @@ import { open, write, createReadStream, createWriteStream, close, chmod } from "
import { LinuxTargetHelper } from "./LinuxTargetHelper"
import { getBin } from "../util/binDownload"
import { Promise as BluebirdPromise } from "bluebird"
+import { v1 as uuid1 } from "uuid-1345"
//noinspection JSUnusedLocalSymbols
const __awaiter = require("../util/awaiter")
@@ -17,12 +18,18 @@ const appImageSha256 = process.platform === "darwin" ? "5d4a954876654403698a01ef
const appImagePathPromise = getBin("AppImage", appImageVersion, `https://dl.bintray.com/electron-userland/bin/${appImageVersion}.7z`, appImageSha256)
export default class AppImageTarget extends TargetEx {
+ private readonly options = Object.assign({}, this.packager.platformSpecificBuildOptions, (this.packager.devMetadata.build)[this.name])
private readonly desktopEntry: Promise
constructor(private packager: PlatformPackager, private helper: LinuxTargetHelper, private outDir: string) {
super("appImage")
- this.desktopEntry = helper.computeDesktopEntry("AppRun", `X-AppImage-Version=${packager.appInfo.buildVersion}`)
+ // we add X-AppImage-BuildId to ensure that new desktop file will be installed
+ this.desktopEntry = BluebirdPromise.promisify(uuid1)({mac: false})
+ .then(uuid => helper.computeDesktopEntry(this.options, "AppRun", {
+ "X-AppImage-Version": `${packager.appInfo.buildVersion}`,
+ "X-AppImage-BuildId": uuid,
+ }))
}
async build(appOutDir: string, arch: Arch): Promise {
diff --git a/src/targets/fpm.ts b/src/targets/fpm.ts
index 7b39ee21931..f464957cef8 100644
--- a/src/targets/fpm.ts
+++ b/src/targets/fpm.ts
@@ -28,7 +28,7 @@ export default class FpmTarget extends TargetEx {
super(name)
this.scriptFiles = this.createScripts()
- this.desktopEntry = helper.computeDesktopEntry()
+ this.desktopEntry = helper.computeDesktopEntry(this.options)
}
private async createScripts(): Promise> {
@@ -93,6 +93,11 @@ export default class FpmTarget extends TargetEx {
"--url", projectUrl,
]
+ const packageCategory = options.packageCategory
+ if (packageCategory != null && packageCategory !== null) {
+ args.push("--category", packageCategory)
+ }
+
if (target === "deb") {
args.push("--deb-compression", options.compression || (packager.devMetadata.build.compression === "store" ? "gz" : "xz"))
}
diff --git a/src/winPackager.ts b/src/winPackager.ts
index f56a8f37402..e83c86577ad 100644
--- a/src/winPackager.ts
+++ b/src/winPackager.ts
@@ -112,7 +112,7 @@ export class WinPackager extends PlatformPackager {
async pack(outDir: string, arch: Arch, targets: Array, postAsyncTasks: Array>): Promise {
const appOutDir = this.computeAppOutDir(outDir, arch)
- await this.doPack(await this.computePackOptions(), outDir, appOutDir, this.platform.nodeName, arch, this.platformSpecificBuildOptions)
+ await this.doPack(outDir, appOutDir, this.platform.nodeName, arch, this.platformSpecificBuildOptions)
this.packageInDistributableFormat(outDir, appOutDir, arch, targets, postAsyncTasks)
}
diff --git a/templates/linux/AppRun.sh b/templates/linux/AppRun.sh
index de2f610ad26..9437a259316 100755
--- a/templates/linux/AppRun.sh
+++ b/templates/linux/AppRun.sh
@@ -147,8 +147,8 @@ fi
# Check if the desktop file is already there
# and if so, whether it points to the same AppImage
if [ -e "$DESTINATION_DIR_DESKTOP/$VENDORPREFIX-$DESKTOP_FILE_NAME" ] ; then
- INSTALLED_APP_VERSION=$(grep "^X-AppImage-Version=" "$DESTINATION_DIR_DESKTOP/$VENDORPREFIX-$DESKTOP_FILE_NAME" | head -n 1 | cut -d " " -f 1)
- APP_VERSION=$(grep "^X-AppImage-Version=" "$DESKTOP_FILE" | head -n 1 | cut -d " " -f 1)
+ INSTALLED_APP_VERSION=$(grep "^X-AppImage-BuildId=" "$DESTINATION_DIR_DESKTOP/$VENDORPREFIX-$DESKTOP_FILE_NAME" | head -n 1 | cut -d " " -f 1)
+ APP_VERSION=$(grep "^X-AppImage-BuildId=" "$DESKTOP_FILE" | head -n 1 | cut -d " " -f 1)
echo "installed: $INSTALLED_APP_VERSION image: $APP_VERSION"
if [ "$INSTALLED_APP_VERSION" == "$APP_VERSION" ] ; then
exit 0
@@ -157,7 +157,7 @@ fi
# We ask the user only if we have found no reason to skip until here
if [ -z "$SKIP" ] ; then
- yesno "Install" "Should a desktop file for $APPIMAGE be installed?"
+ yesno "Install" "Would you like to integrate $APPIMAGE with your system?\n\nThis will add it to your applications menu and install icons.\nIf you don't do this you can still launch the application by double-clicking on the AppImage."
fi
# If the user has agreed, rewrite and install the desktop file, and the MIME information
diff --git a/test/fixtures/test-app-one/package.json b/test/fixtures/test-app-one/package.json
index d97d234fdb5..a836f156630 100755
--- a/test/fixtures/test-app-one/package.json
+++ b/test/fixtures/test-app-one/package.json
@@ -10,8 +10,14 @@
"build": {
"electronVersion": "1.3.5",
"appId": "org.electron-builder.testApp",
- "category": "your.app.category.type",
"iconUrl": "https://raw.githubusercontent.com/szwacz/electron-boilerplate/master/resources/windows/icon.ico",
- "compression": "store"
+ "compression": "store",
+ "mac": {
+ "category": "your.app.category.type"
+ },
+ "linux": {
+ "category": "Development",
+ "packageCategory": "devel"
+ }
}
}
\ No newline at end of file
diff --git a/test/src/helpers/packTester.ts b/test/src/helpers/packTester.ts
index 684abbffa65..6c541542588 100755
--- a/test/src/helpers/packTester.ts
+++ b/test/src/helpers/packTester.ts
@@ -231,6 +231,7 @@ async function checkLinuxResult(outDir: string, packager: Packager, checkOptions
Package: "testapp",
Description: " \n Test Application (test quite “ #378)",
Depends: checkOptions == null || checkOptions.expectedDepends == null ? "libappindicator1, libnotify-bin" : checkOptions.expectedDepends,
+ Section: "devel",
})
}
diff --git a/test/src/linuxPackagerTest.ts b/test/src/linuxPackagerTest.ts
index 95d5e3f6a27..49a64bac37b 100755
--- a/test/src/linuxPackagerTest.ts
+++ b/test/src/linuxPackagerTest.ts
@@ -1,5 +1,5 @@
import test from "./helpers/avaEx"
-import { assertPack, platform, modifyPackageJson, app, appThrows } from "./helpers/packTester"
+import { modifyPackageJson, app, appThrows } from "./helpers/packTester"
import { remove } from "fs-extra-p"
import * as path from "path"
import { Platform } from "out"
@@ -7,24 +7,16 @@ import { Platform } from "out"
//noinspection JSUnusedLocalSymbols
const __awaiter = require("out/util/awaiter")
-test.ifNotWindows("deb", () => assertPack("test-app-one", platform(Platform.LINUX)))
+test.ifNotWindows("deb", app({targets: Platform.LINUX.createTarget("deb")}))
-test.ifDevOrLinuxCi("AppImage", () => assertPack("test-app-one", {
- targets: Platform.LINUX.createTarget("appimage"),
- }
-))
+test.ifDevOrLinuxCi("AppImage", app({targets: Platform.LINUX.createTarget()}))
-test.ifDevOrLinuxCi("AppImage - default icon", () => assertPack("test-app-one", {
- targets: Platform.LINUX.createTarget("appimage"),
- }, {
+test.ifDevOrLinuxCi("AppImage - default icon", app({targets: Platform.LINUX.createTarget("appimage")}, {
projectDirCreated: projectDir => remove(path.join(projectDir, "build"))
- },
-))
+}))
// "apk" is very slow, don't test for now
-test.ifDevOrLinuxCi("targets", () => assertPack("test-app-one", {
- targets: Platform.LINUX.createTarget(["sh", "freebsd", "pacman", "zip", "7z"]),
-}))
+test.ifDevOrLinuxCi("targets", app({targets: Platform.LINUX.createTarget(["sh", "freebsd", "pacman", "zip", "7z"])}))
test.ifDevOrLinuxCi("tar", app({targets: Platform.LINUX.createTarget(["tar.xz", "tar.lz", "tar.bz2"])}))
@@ -36,7 +28,7 @@ test.ifNotWindows("icons from ICNS", app({targets: Platform.LINUX.createTarget()
projectDirCreated: it => remove(path.join(it, "build", "icons"))
}))
-test.ifNotWindows("custom depends", () => assertPack("test-app-one", {
+test.ifNotWindows("custom depends", app({
targets: Platform.LINUX.createTarget("deb"),
devMetadata: {
build: {
diff --git a/test/src/macPackagerTest.ts b/test/src/macPackagerTest.ts
index 4753f5b22a5..cb015707e05 100644
--- a/test/src/macPackagerTest.ts
+++ b/test/src/macPackagerTest.ts
@@ -6,7 +6,6 @@ import * as path from "path"
import { BuildInfo } from "out/platformPackager"
import { Promise as BluebirdPromise } from "bluebird"
import { assertThat } from "./helpers/fileAssert"
-import { ElectronPackagerOptions } from "out/packager/dirPackager"
import { Platform, MacOptions, createTargets } from "out"
import { SignOptions, FlatOptions } from "electron-osx-sign"
import { Arch } from "out"
@@ -207,7 +206,6 @@ test.ifOsx("disable dmg icon, bundleVersion", () => {
class CheckingMacPackager extends OsXPackager {
effectiveDistOptions: any
- effectivePackOptions: ElectronPackagerOptions
effectiveSignOptions: SignOptions
effectiveFlatOptions: FlatOptions
@@ -226,8 +224,8 @@ class CheckingMacPackager extends OsXPackager {
return await super.pack(outDir, arch, targets, postAsyncTasks)
}
- async doPack(options: ElectronPackagerOptions, outDir: string, appOutDir: string, platformName: string, arch: Arch, customBuildOptions: MacOptions, postAsyncTasks: Array> = null) {
- this.effectivePackOptions = options
+ async doPack(outDir: string, appOutDir: string, platformName: string, arch: Arch, customBuildOptions: MacOptions, postAsyncTasks: Array> = null) {
+ // skip
}
async doSign(opts: SignOptions): Promise {
diff --git a/test/src/winPackagerTest.ts b/test/src/winPackagerTest.ts
index 3c21a768f10..5a2c14c1b01 100755
--- a/test/src/winPackagerTest.ts
+++ b/test/src/winPackagerTest.ts
@@ -9,7 +9,6 @@ import { assertThat } from "./helpers/fileAssert"
import { SignOptions } from "out/windowsCodeSign"
import SquirrelWindowsTarget from "out/targets/squirrelWindows"
import { Target } from "out/platformPackager"
-import { ElectronPackagerOptions } from "out/packager/dirPackager"
//noinspection JSUnusedLocalSymbols
const __awaiter = require("out/util/awaiter")
@@ -125,16 +124,12 @@ class CheckingWinPackager extends WinPackager {
effectiveDistOptions: any
signOptions: SignOptions | null
- effectivePackOptions: ElectronPackagerOptions
-
constructor(info: BuildInfo) {
super(info)
}
async pack(outDir: string, arch: Arch, targets: Array, postAsyncTasks: Array>): Promise {
// skip pack
- this.effectivePackOptions = await this.computePackOptions()
-
const helperClass: typeof SquirrelWindowsTarget = require("out/targets/squirrelWindows").default
this.effectiveDistOptions = await (new helperClass(this).computeEffectiveDistOptions())
diff --git a/typings/uuid-1345.d.ts b/typings/uuid-1345.d.ts
index fa9c206d4a2..2ddb4519d79 100644
--- a/typings/uuid-1345.d.ts
+++ b/typings/uuid-1345.d.ts
@@ -4,5 +4,11 @@ declare module "uuid-1345" {
name: string
}
+ interface TimeBasedUuidOptions {
+ mac: boolean
+ }
+
export function v5(options: NameUuidOptions, callback: (error: Error, result: string) => void): void
+ export function v4(callback: (error: Error, result: string) => void): void
+ export function v1(options: TimeBasedUuidOptions, callback: (error: Error, result: string) => void): void
}
\ No newline at end of file