From b151ffc85c71333d314d427857aa5067ff53afa2 Mon Sep 17 00:00:00 2001 From: develar Date: Sat, 2 Apr 2016 01:07:35 +0200 Subject: [PATCH] fix: Windows installer metadata is incorrect #278 Closes #278 --- docs/options.md | 9 +++---- package.json | 2 +- src/metadata.ts | 21 ++++++++++++--- src/winPackager.ts | 4 ++- test/fixtures/test-app-one/package.json | 3 ++- test/fixtures/test-app/package.json | 2 +- test/src/BuildTest.ts | 2 +- test/src/helpers/packTester.ts | 34 ++++++++++++++++++++----- test/src/helpers/runTests.ts | 2 +- test/typings/decompress-zip.d.ts | 10 ++++++++ 10 files changed, 67 insertions(+), 22 deletions(-) diff --git a/docs/options.md b/docs/options.md index 61da768939e..6164909b15e 100644 --- a/docs/options.md +++ b/docs/options.md @@ -4,7 +4,6 @@ In the development `package.json` custom `build` field can be specified to custo ```json "build": { "osx": { - "title": "computed name from the app package.js, you can overwrite", "icon": "build/icon.icns", "icon-size": 80, "background": "build/background.png", @@ -22,16 +21,13 @@ In the development `package.json` custom `build` field can be specified to custo "path": "computed path to artifact, do not specify it - will be overwritten" } ] - }, - "win": "see https://github.com/electronjs/windows-installer#usage" + } } ``` 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). -See [OS X options](https://www.npmjs.com/package/appdmg#json-specification) and [Windows options](https://github.com/electronjs/windows-installer#usage). - Here documented only `electron-builder` specific options: @@ -45,6 +41,7 @@ Here documented only `electron-builder` specific options: # Development `package.json` | Name | Description | --- | --- +| homepage | The url to the project homepage (NuGet Package `projectUrl` or Linux Package URL). | build | See [BuildMetadata](#BuildMetadata). ## `.build` @@ -53,5 +50,7 @@ Here documented only `electron-builder` specific options: | iconUrl |

*windows-only.* A URL to an ICO file to use as the application icon (displayed in Control Panel > Programs and Features). Defaults to the Atom icon.

Please note — [local icon file url is not accepted](https://github.com/atom/grunt-electron-installer/issues/73), must be https/http.

| productName | See [AppMetadata.productName](#AppMetadata-productName). | extraResources |

A [glob expression](https://www.npmjs.com/package/glob#glob-primer), when specified, copy the file or directory with matching names directly into the app’s directory (Contents/Resources for OS X).

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 <project_dir>/foo directory.

May be specified in the platform options (i.e. in the build.osx).

+| osx | See [OS X options](https://www.npmjs.com/package/appdmg#json-specification) +| win | See [windows-installer options](https://github.com/electronjs/windows-installer#usage) diff --git a/package.json b/package.json index 59cc44bc0cd..c44872b7803 100644 --- a/package.json +++ b/package.json @@ -55,7 +55,7 @@ "bluebird": "^3.3.4", "command-line-args": "^2.1.6", "electron-packager": "^6.0.0", - "electron-winstaller-fixed": "^2.0.6-beta.4", + "electron-winstaller-fixed": "^2.0.6-beta.5", "fs-extra": "^0.26.7", "fs-extra-p": "^0.2.0", "globby": "^4.0.0", diff --git a/src/metadata.ts b/src/metadata.ts index 22c81c6cef7..5a140899580 100755 --- a/src/metadata.ts +++ b/src/metadata.ts @@ -28,6 +28,11 @@ export interface AppMetadata extends Metadata { # Development `package.json` */ export interface DevMetadata extends Metadata { + /** + The url to the project homepage (NuGet Package `projectUrl` or Linux Package URL). + */ + readonly homepage?: string + /** See [BuildMetadata](#BuildMetadata). */ @@ -71,10 +76,6 @@ export interface BuildMetadata { */ readonly productName?: string - readonly osx?: appdmg.Specification - readonly win?: any, - readonly linux?: any - /** A [glob expression](https://www.npmjs.com/package/glob#glob-primer), when specified, copy the file or directory with matching names directly into the app's directory (`Contents/Resources` for OS X). @@ -85,6 +86,18 @@ export interface BuildMetadata { May be specified in the platform options (i.e. in the `build.osx`). */ readonly extraResources?: Array + + /** + See [OS X options](https://www.npmjs.com/package/appdmg#json-specification) + */ + readonly osx?: appdmg.Specification + + /** + See [windows-installer options](https://github.com/electronjs/windows-installer#usage) + */ + readonly win?: any, + + readonly linux?: any } export interface PlatformSpecificBuildOptions { diff --git a/src/winPackager.ts b/src/winPackager.ts index 13c364f2e3b..3fae7e4e20b 100644 --- a/src/winPackager.ts +++ b/src/winPackager.ts @@ -115,6 +115,7 @@ export default class WinPackager extends PlatformPackager { const version = this.metadata.version const installerOutDir = WinPackager.computeDistOut(outDir, arch) const archSuffix = arch === "x64" ? "" : ("-" + arch) + const projectUrl = this.devMetadata.homepage const options = Object.assign({ name: this.metadata.name, @@ -133,7 +134,8 @@ export default class WinPackager extends PlatformPackager { fixUpPaths: false, usePackageJson: false, noMsi: true, - extraFileSpecs: this.extraNuGetFileSources == null ? null : ("\n" + (await this.extraNuGetFileSources).join("\n")) + extraFileSpecs: this.extraNuGetFileSources == null ? null : ("\n" + (await this.extraNuGetFileSources).join("\n")), + extraMetadataSpecs: projectUrl == null ? null : `\n${projectUrl}`, }, this.customBuildOptions) await require("electron-winstaller-fixed").createWindowsInstaller(options) diff --git a/test/fixtures/test-app-one/package.json b/test/fixtures/test-app-one/package.json index 4af77ac3218..a65af155d69 100755 --- a/test/fixtures/test-app-one/package.json +++ b/test/fixtures/test-app-one/package.json @@ -2,13 +2,14 @@ "private": true, "name": "TestApp", "version": "1.0.0", + "homepage": "http://foo.example.com", "description": "Test Application", "scripts": { "start": "electron ." }, "author": "Foo Bar ", "devDependencies": { - "electron-prebuilt": "^0.37.2" + "electron-prebuilt": "^0.37.3" }, "build": { "app-bundle-id": "your.id", diff --git a/test/fixtures/test-app/package.json b/test/fixtures/test-app/package.json index 20f2f31d553..382069ff559 100755 --- a/test/fixtures/test-app/package.json +++ b/test/fixtures/test-app/package.json @@ -4,7 +4,7 @@ "start": "electron ." }, "devDependencies": { - "electron-prebuilt": "^0.37.2" + "electron-prebuilt": "^0.37.3" }, "build": { "app-bundle-id": "your.id", diff --git a/test/src/BuildTest.ts b/test/src/BuildTest.ts index 1c23de33910..94f7bdbbc1c 100755 --- a/test/src/BuildTest.ts +++ b/test/src/BuildTest.ts @@ -49,7 +49,7 @@ test("version from electron-prebuilt dependency", () => assertPack("test-app-one tempDirCreated: projectDir => { return BluebirdPromise.all([ outputJson(path.join(projectDir, "node_modules", "electron-prebuilt", "package.json"), { - version: "0.37.2" + version: "0.37.3" }), modifyPackageJson(projectDir, data => { data.devDependencies = {} diff --git a/test/src/helpers/packTester.ts b/test/src/helpers/packTester.ts index e4b79bc1e48..a54952e0d60 100755 --- a/test/src/helpers/packTester.ts +++ b/test/src/helpers/packTester.ts @@ -1,4 +1,4 @@ -import { copy, emptyDir, remove, writeJson, readJson } from "fs-extra-p" +import { copy, emptyDir, remove, writeJson, readJson, readFile } from "fs-extra-p" import * as assertThat from "should/as-function" import * as path from "path" import { parse as parsePlist } from "plist" @@ -186,12 +186,11 @@ async function checkWindowsResult(packager: Packager, packagerOptions: PackagerO assertThat(artifacts.map(it => it.artifactName).filter(it => it != null)).deepEqual([`TestAppSetup-1.0.0${archSuffix}.exe`]) } - const files = pathSorter((await new BluebirdPromise>((resolve, reject) => { - const unZipper = new DecompressZip(path.join(path.dirname(artifacts[0].file), `TestApp-1.0.0${archSuffix}-full.nupkg`)) - unZipper.on("list", resolve) - unZipper.on('error', reject) - unZipper.list() - })).map(it => it.replace(/\\/g, "/")).filter(it => (!it.startsWith("lib/net45/locales/") || it === "lib/net45/locales/en-US.pak") && !it.endsWith(".psmdcp"))) + const packageFile = path.join(path.dirname(artifacts[0].file), `TestApp-1.0.0${archSuffix}-full.nupkg`) + const unZipper = new DecompressZip(packageFile) + const fileDescriptors = await unZipper.getFiles() + + const files = pathSorter(fileDescriptors.map(it => it.path.replace(/\\/g, "/")).filter(it => (!it.startsWith("lib/net45/locales/") || it === "lib/net45/locales/en-US.pak") && !it.endsWith(".psmdcp"))) // console.log(JSON.stringify(files, null, 2)) const expectedContents = checkOptions == null || checkOptions.expectedContents == null ? expectedWinContents : checkOptions.expectedContents @@ -203,6 +202,27 @@ async function checkWindowsResult(packager: Packager, packagerOptions: PackagerO return it } })) + + if (checkOptions == null || checkOptions.expectedContents == null) { + await unZipper.extractFile(fileDescriptors.filter(it => it.path === "TestApp.nuspec")[0], { + path: path.dirname(packageFile), + }) + assertThat((await readFile(path.join(path.dirname(packageFile), "TestApp.nuspec"), "utf8")).replace(/\r\n/g, "\n")).equal(` + + + TestApp + 1.0.0 + My App + Foo Bar + Foo Bar + http://foo.example.com + https://raw.githubusercontent.com/szwacz/electron-boilerplate/master/resources/windows/icon.ico + false + Test Application + Copyright © ${new Date().getFullYear()} Foo Bar + +`) + } } async function getContents(path: string, productName: string) { diff --git a/test/src/helpers/runTests.ts b/test/src/helpers/runTests.ts index 4530c7ad23a..942b4e03501 100755 --- a/test/src/helpers/runTests.ts +++ b/test/src/helpers/runTests.ts @@ -14,7 +14,7 @@ const rootDir = path.join(__dirname, "..", "..", "..") const testPackageDir = path.join(require("os").tmpdir(), "electron_builder_published") const testNodeModules = path.join(testPackageDir, "node_modules") -const electronVersion = "0.37.2" +const electronVersion = "0.37.3" BluebirdPromise.all([ deleteOldElectronVersion(), diff --git a/test/typings/decompress-zip.d.ts b/test/typings/decompress-zip.d.ts index 3e1e200b701..8f14bb5ad3a 100644 --- a/test/typings/decompress-zip.d.ts +++ b/test/typings/decompress-zip.d.ts @@ -1,9 +1,19 @@ declare module "decompress-zip" { import { EventEmitter } from "events" + interface FileDescriptor { + path: string + } + export = class DecompressZip extends EventEmitter { constructor(filename: string) list(): void + + getFiles(): Promise> + + extract(options: {path: string, filter?: (file: string) => boolean}): void + + extractFile(file: FileDescriptor, options: {path: string, filter?: (file: string) => boolean}): Promise } } \ No newline at end of file