Skip to content

Commit

Permalink
feat: use productName from app/package.json if present #204
Browse files Browse the repository at this point in the history
Closes #204, #223
  • Loading branch information
develar committed Mar 9, 2016
1 parent 26d6ddc commit 5d376e1
Show file tree
Hide file tree
Showing 29 changed files with 395 additions and 225 deletions.
8 changes: 8 additions & 0 deletions .idea/runConfigurations/linuxPackagerTest.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/runConfigurations/winPackagerTest.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 0 additions & 5 deletions lib/linux.d.ts

This file was deleted.

2 changes: 1 addition & 1 deletion lib/linux.js
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ function _buildPackage( options, scripts, tmpFolder, destination, callback ) {
'-t', linux.target,
'--architecture', linux.archName,
'--rpm-os', 'linux',
'--name', linux.title,
'--name', linux.name || linux.title,
'--force',
'--after-install', scripts[0],
'--after-remove', scripts[1],
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@
"bluebird": "^3.3.4",
"command-line-args": "^2.1.6",
"electron-packager-tf": "^5.2.3",
"electron-winstaller-fixed": "^2.0.5-beta.4",
"electron-winstaller-fixed": "^2.0.5-beta.7",
"fs-extra": "^0.26.5",
"fs-extra-p": "^0.1.0",
"gm": "^1.21.1",
Expand All @@ -73,7 +73,7 @@
"devDependencies": {
"ava-tf": "^0.12.4-beta.6",
"babel-plugin-array-includes": "^2.0.3",
"babel-plugin-transform-es2015-parameters": "^6.6.5",
"babel-plugin-transform-es2015-parameters": "^6.7.0",
"electron-download": "^2.0.0",
"eslint": "^2.3.0",
"eslint-plugin-ava": "sindresorhus/eslint-plugin-ava",
Expand Down
15 changes: 8 additions & 7 deletions src/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export async function createPublisher(packager: Packager, options: BuildOptions,
export interface BuildOptions extends PackagerOptions, PublishOptions {
}

export function build(options: BuildOptions = {}): Promise<any> {
export async function build(options: BuildOptions = {}): Promise<void> {
if (options.cscLink == null) {
options.cscLink = process.env.CSC_LINK
}
Expand Down Expand Up @@ -83,15 +83,16 @@ export function build(options: BuildOptions = {}): Promise<any> {
}
})
}
return executeFinally(packager.build(), error => {
if (error == null) {
return Promise.all(publishTasks)
}
else {

await executeFinally(packager.build(), errorOccurred => {
if (errorOccurred) {
for (let task of publishTasks) {
task.cancel()
}
return null
return BluebirdPromise.resolve(null)
}
else {
return BluebirdPromise.all(publishTasks)
}
})
}
7 changes: 4 additions & 3 deletions src/codeSign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { executeFinally, all } from "./promise"
import { Promise as BluebirdPromise } from "bluebird"
import { randomBytes } from "crypto"

//noinspection JSUnusedLocalSymbols
const __awaiter = require("./awaiter")

export interface CodeSigningInfo {
Expand All @@ -27,7 +28,7 @@ export function createKeychain(keychainName: string, cscLink: string, cscKeyPass
const developerCertPath = path.join(tmpdir(), randomString() + ".p12")

const keychainPassword = randomString()
return executeFinally(Promise.all([
return executeFinally(BluebirdPromise.all([
download("https://developer.apple.com/certificationauthority/AppleWWDRCA.cer", appleCertPath),
download(cscLink, developerCertPath),
BluebirdPromise.mapSeries([
Expand All @@ -37,9 +38,9 @@ export function createKeychain(keychainName: string, cscLink: string, cscKeyPass
], it => exec("security", it))
])
.then(() => importCerts(keychainName, appleCertPath, developerCertPath, cscKeyPassword)),
error => {
errorOccurred => {
const tasks = [deleteFile(appleCertPath, true), deleteFile(developerCertPath, true)]
if (error != null) {
if (errorOccurred) {
tasks.push(deleteKeychain(keychainName))
}
return all(tasks)
Expand Down
3 changes: 2 additions & 1 deletion src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import * as path from "path"
import * as fs from "fs-extra-p"

export { Packager } from "./packager"
export { PackagerOptions, Platform } from "./platformPackager"
export { PackagerOptions } from "./platformPackager"
export { AppMetadata, DevMetadata, Platform, getProductName } from "./metadata"

/**
* Prototype for electron-builder
Expand Down
169 changes: 114 additions & 55 deletions src/linuxPackager.ts
Original file line number Diff line number Diff line change
@@ -1,41 +1,73 @@
import * as path from "path"
import { Promise as BluebirdPromise } from "bluebird"
import { init } from "../lib/linux"
import { PlatformPackager, BuildInfo, Platform } from "./platformPackager"
import { PlatformPackager, BuildInfo } from "./platformPackager"
import { Platform } from "./metadata"
import { dir as _tpmDir, TmpOptions } from "tmp"
import { exec, log } from "./util"
import { State as Gm } from "gm"
import { outputFile, readFile } from "fs-extra-p"
const template = require("lodash.template")

//noinspection JSUnusedLocalSymbols
const __awaiter = require("./awaiter")
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 class LinuxPackager extends PlatformPackager<DebOptions> {
desktopIcons: Promise<Array<string>>
private readonly debOptions: DebOptions

private readonly packageFiles: Promise<Array<string>>
private readonly scriptFiles: Promise<Array<string>>

constructor(info: BuildInfo) {
super(info)

if (this.options.dist && (this.customDistOptions == null || this.customDistOptions.desktopTemplate == null)) {
this.desktopIcons = this.computeDesktopIconPath()
}
else {
this.desktopIcons = BluebirdPromise.resolve(null)
this.debOptions = Object.assign({
name: this.metadata.name,
comment: this.metadata.description,
}, this.customDistOptions)

if (this.options.dist) {
const tempDir = tmpDir({
unsafeCleanup: true,
prefix: "electron-builder-"
})
this.packageFiles = this.computePackageFiles(tempDir)
this.scriptFiles = this.createScripts(tempDir)
}
}

protected get platform() {
return Platform.LINUX
}

private async computeDesktopIconPath(): Promise<Array<string>> {
const tempDir = await tmpDir({
unsafeCleanup: true,
prefix: "png-icons"
})
private async computePackageFiles(tempDirPromise: Promise<string>): Promise<Array<string>> {
const tempDir = await tempDirPromise

const promises: Array<Promise<Array<string>>> = []
if (this.customDistOptions == null || this.customDistOptions.desktop == null) {
promises.push(this.computeDesktopIconPath(tempDir))
}

promises.push(this.computeDesktop(tempDir))

return Array.prototype.concat.apply([], await BluebirdPromise.all(promises))
}

private async computeDesktop(tempDir: string): Promise<Array<string>> {
const tempFile = path.join(tempDir, this.appName + ".desktop")
await outputFile(tempFile, this.debOptions.desktop || `[Desktop Entry]
Name=${this.appName}
Comment=${this.debOptions.comment}
Exec="${this.appName}"
Terminal=false
Type=Application
Icon=${this.metadata.name}
`)
return [`${tempFile}=/usr/share/applications/${this.appName}.desktop`]
}

private async computeDesktopIconPath(tempDir: string): Promise<Array<string>> {
const outputs = await exec("icns2png", ["-x", "-o", tempDir, path.join(this.buildResourcesDir, "icon.icns")])
if (!outputs[0].toString().includes("ih32")) {
log("48x48 is not found in the icns, 128x128 will be resized")
Expand All @@ -47,9 +79,10 @@ export class LinuxPackager extends PlatformPackager<DebOptions> {
})
}

const appName = this.metadata.name
const name = this.metadata.name

function createMapping(size: string) {
return `${tempDir}/icon_${size}x${size}x32.png=/usr/share/icons/hicolor/${size}x${size}/apps/${appName}.png`
return `${tempDir}/icon_${size}x${size}x32.png=/usr/share/icons/hicolor/${size}x${size}/apps/${name}.png`
}

return [
Expand All @@ -62,54 +95,80 @@ export class LinuxPackager extends PlatformPackager<DebOptions> {
]
}

async packageInDistributableFormat(outDir: string, appOutDir: string, arch: string): Promise<any> {
const specification: DebOptions = {
version: this.metadata.version,
title: this.metadata.name,
comment: this.metadata.description,
maintainer: `${this.metadata.author.name} <${this.metadata.author.email}>`,
arch: arch === "ia32" ? 32 : 64,
target: "deb",
executable: this.metadata.name,
desktop: `[Desktop Entry]
Name=${this.metadata.name}
Comment=${this.metadata.description}
Exec=${this.metadata.name}
Terminal=false
Type=Application
Icon=${this.metadata.name}
`,
dirs: await this.desktopIcons
}
private async createScripts(tempDirPromise: Promise<string>): Promise<Array<string>> {
const tempDir = await tempDirPromise
const defaultTemplatesDir = path.join(__dirname, "..", "templates", "linux")

if (this.customDistOptions != null) {
Object.assign(specification, this.customDistOptions)
}
return await buildDeb({
log: function emptyLog() {/* ignore out */},
appPath: appOutDir,
out: outDir,
config: {
linux: specification
}
})
const templateOptions = Object.assign({
// old API compatibility
executable: this.appName,
}, this.debOptions)

const afterInstallTemplate = this.debOptions.afterInstall || path.join(defaultTemplatesDir, "after-install.tpl")
const afterInstallFilePath = writeConfigFile(tempDir, afterInstallTemplate, templateOptions)

const afterRemoveTemplate = this.debOptions.afterRemove || path.join(defaultTemplatesDir, "after-remove.tpl")
const afterRemoveFilePath = writeConfigFile(tempDir, afterRemoveTemplate, templateOptions)

return await BluebirdPromise.all<string>([afterInstallFilePath, afterRemoveFilePath])
}

async packageInDistributableFormat(outDir: string, appOutDir: string, arch: string): Promise<any> {
return await this.buildDeb(this.debOptions, outDir, appOutDir, arch)
.then(it => this.dispatchArtifactCreated(it))
}

private async buildDeb(options: DebOptions, outDir: string, appOutDir: string, arch: string): Promise<string> {
const archName = arch === "ia32" ? "i386" : "amd64"
const target = "deb"
const outFilename = `${this.metadata.name}-${this.metadata.version}-${archName}.${target}`
const destination = path.join(outDir, outFilename)
const scripts = await this.scriptFiles
await exec("fpm", [
"-s", "dir",
"-t", target,
"--architecture", archName,
"--rpm-os", "linux",
"--name", this.metadata.name,
"--force",
"--after-install", scripts[0],
"--after-remove", scripts[1],
"--description", options.comment,
"--maintainer", options.maintainer || `${this.metadata.author.name} <${this.metadata.author.email}>`,
"--version", this.metadata.version,
"--package", destination,
"--deb-compression", options.compression || "xz",
appOutDir + "/=/opt/" + this.appName,
].concat(await this.packageFiles))
return outFilename
}
}

async function writeConfigFile(tempDir: string, templatePath: string, options: any): Promise<string> {
const config = template(await readFile(templatePath, "utf8"),
{
// set interpolate explicitely 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
}

export interface DebOptions {
title: string
name: string
comment: string

version: string

arch: number
maintainer: string
executable: string
target: string

desktopTemplate?: string
/**
* .desktop file template
*/
desktop?: string

dirs?: Array<string>
afterInstall?: string
afterRemove?: string

compression?: string
}
16 changes: 8 additions & 8 deletions src/macPackager.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { PlatformPackager, BuildInfo, Platform } from "./platformPackager"
import { PlatformPackager, BuildInfo } from "./platformPackager"
import { Platform } from "./metadata"
import * as path from "path"
import { Promise as BluebirdPromise } from "bluebird"
import { log, spawn } from "./util"
Expand Down Expand Up @@ -30,7 +31,7 @@ export default class MacPackager extends PlatformPackager<appdmg.Specification>
async pack(platform: string, outDir: string, appOutDir: string, arch: string): Promise<any> {
await super.pack(platform, outDir, appOutDir, arch)
let codeSigningInfo = await this.codeSigningInfo
return await this.signMac(path.join(appOutDir, this.metadata.name + ".app"), codeSigningInfo)
return await this.signMac(path.join(appOutDir, this.appName + ".app"), codeSigningInfo)
}

private signMac(distPath: string, codeSigningInfo: CodeSigningInfo): Promise<any> {
Expand All @@ -55,7 +56,7 @@ export default class MacPackager extends PlatformPackager<appdmg.Specification>
log("Creating DMG")

const specification: appdmg.Specification = {
title: this.metadata.name,
title: this.appName,
icon: path.join(this.buildResourcesDir, "icon.icns"),
"icon-size": 80,
background: path.join(this.buildResourcesDir, "background.png"),
Expand All @@ -74,10 +75,10 @@ export default class MacPackager extends PlatformPackager<appdmg.Specification>
}

if (specification.title == null) {
specification.title = this.metadata.name
specification.title = this.appName
}

specification.contents[1].path = path.join(appOutDir, this.metadata.name + ".app")
specification.contents[1].path = path.join(appOutDir, this.appName + ".app")

const emitter = require("appdmg")({
target: artifactPath,
Expand All @@ -96,10 +97,9 @@ export default class MacPackager extends PlatformPackager<appdmg.Specification>

private zipMacApp(outDir: string): Promise<string> {
log("Creating ZIP for Squirrel.Mac")
const appName = this.metadata.name
// -y param is important - "store symbolic links as the link instead of the referenced file"
const resultPath = `${appName}-${this.metadata.version}-mac.zip`
const args = ["-ryXq", resultPath, appName + ".app"]
const resultPath = `${this.metadata.name}-${this.metadata.version}-mac.zip`
const args = ["-ryXq", resultPath, this.appName + ".app"]

// todo move to options
if (process.env.TEST_MODE === "true") {
Expand Down
Loading

0 comments on commit 5d376e1

Please sign in to comment.