From e68b4c47d2ee5054205fcf5fa1bc6a34b161a18a Mon Sep 17 00:00:00 2001 From: develar Date: Sun, 17 Apr 2016 14:02:44 +0200 Subject: [PATCH] fix: deb package description according to spec Closes #323 --- appveyor.yml | 1 - docs/Options.md | 12 ++++++---- src/linuxPackager.ts | 14 +++++++---- src/metadata.ts | 44 ++++++++++++++++++++++++---------- src/platformPackager.ts | 3 +-- test/src/helpers/packTester.ts | 32 ++++++++++++++++++------- tslint.json | 1 + 7 files changed, 73 insertions(+), 34 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index ea2da137f0b..1a5c21d29bc 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -12,7 +12,6 @@ install: - node -v - npm -v - npm prune - - npm install Microsoft/TypeScript - npm install build: off diff --git a/docs/Options.md b/docs/Options.md index 3fb58e604fc..0aa54bbb487 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -35,23 +35,24 @@ Here documented only `electron-builder` specific options: | --- | --- | **name** | The application name. | productName |

As [name](#AppMetadata-name), but allows you to specify a product name for your executable which contains spaces and other special characters not allowed in the [name property](https://docs.npmjs.com/files/package.json#name}).

+| **description** | The application description. # Development `package.json` | Name | Description | --- | --- +| **build** | See [.build](#BuildMetadata). | homepage |

The url to the project [homepage](https://docs.npmjs.com/files/package.json#homepage) (NuGet Package projectUrl (optional) or Linux Package URL (required)).

If not specified and your project repository is public on GitHub, it will be https://github.com/${user}/${project} by default.

| license | *linux-only.* The [license](https://docs.npmjs.com/files/package.json#license) name for this package. -| **build** | See [.build](#BuildMetadata). | directories | See [.directories](#MetadataDirectories) ## `.build` | Name | Description | --- | --- -| **app-bundle-id** | The bundle identifier to use in the application's plist. -| **app-category-type** |

The application category type, as shown in the Finder via *View -> Arrange by Application Category* when viewing the Applications directory.

For example, app-category-type=public.app-category.developer-tools will set the application category to *Developer Tools*.

Valid values are listed in [Apple’s documentation](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html#//apple_ref/doc/uid/TP40009250-SW8).

-| **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 Electron icon.

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

+| app-bundle-id | *OS X-only.* The bundle identifier to use in the application's plist. +| app-category-type |

*OS X-only.* The application category type, as shown in the Finder via *View -> Arrange by Application Category* when viewing the Applications directory.

For example, app-category-type=public.app-category.developer-tools will set the application category to *Developer Tools*.

Valid values are listed in [Apple’s documentation](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html#//apple_ref/doc/uid/TP40009250-SW8).

+| 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 Electron 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 [.build.osx](#OsXBuildOptions). @@ -83,6 +84,9 @@ See all [windows-installer options](https://github.com/electron/windows-installe ### `.build.linux` | Name | Description | --- | --- +| description | As [description](#AppMetadata-description) from application package.json, but allows you to specify different for Linux. +| maintainer | The maintainer. Defaults to [author](#AppMetadata-author). +| vendor | The vendor. Defaults to [author](#AppMetadata-author). | compression | *deb-only.* The compression type, one of `gz`, `bzip2`, `xz` (default: `xz`). diff --git a/src/linuxPackager.ts b/src/linuxPackager.ts index 4ef87a05ff4..ea0ef06ba0f 100755 --- a/src/linuxPackager.ts +++ b/src/linuxPackager.ts @@ -23,7 +23,7 @@ export class LinuxPackager extends PlatformPackager { this.debOptions = Object.assign({ name: this.metadata.name, - comment: this.metadata.description, + description: this.metadata.description, }, this.customBuildOptions) if (this.options.dist) { @@ -57,7 +57,7 @@ export class LinuxPackager extends PlatformPackager { const tempFile = path.join(tempDir, this.appName + ".desktop") await outputFile(tempFile, this.debOptions.desktop || `[Desktop Entry] Name=${this.appName} -Comment=${this.debOptions.comment} +Comment=${this.debOptions.description} Exec="${this.appName}" Terminal=false Type=Application @@ -171,7 +171,8 @@ Icon=${this.metadata.name} if (projectUrl == null) { throw new Error("Please specify project homepage") } - + + const author = options.maintainer || `${this.metadata.author.name} <${this.metadata.author.email}>` const args = [ "-s", "dir", "-t", target, @@ -181,8 +182,9 @@ Icon=${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}>`, + "--description", this.appName + '\n ' + this.debOptions.description, + "--maintainer", author, + "--vendor", options.vendor || author, "--version", this.metadata.version, "--package", destination, "--deb-compression", options.compression || (this.devMetadata.build.compression === "store" ? "gz" : "xz"), @@ -191,6 +193,8 @@ Icon=${this.metadata.name} use(this.devMetadata.license, it => args.push("--license", it)) use(this.computeBuildNumber(), it => args.push("--iteration", it)) + + use(options.fpm, it => args.push(...it)) args.push(`${appOutDir}/=/opt/${this.appName}`) args.push(...(await this.packageFiles)) diff --git a/src/metadata.ts b/src/metadata.ts index 721af7b0ca8..67d3edd2bb0 100755 --- a/src/metadata.ts +++ b/src/metadata.ts @@ -19,6 +19,9 @@ export interface AppMetadata extends Metadata { */ readonly productName?: string + /* + The application description. + */ readonly description: string readonly author: AuthorMetadata @@ -28,6 +31,11 @@ export interface AppMetadata extends Metadata { # Development `package.json` */ export interface DevMetadata extends Metadata { + /* + See [.build](#BuildMetadata). + */ + readonly build: BuildMetadata + /* The url to the project [homepage](https://docs.npmjs.com/files/package.json#homepage) (NuGet Package `projectUrl` (optional) or Linux Package URL (required)). @@ -40,11 +48,6 @@ export interface DevMetadata extends Metadata { */ readonly license?: string - /* - See [.build](#BuildMetadata). - */ - readonly build: BuildMetadata - /* See [.directories](#MetadataDirectories) */ @@ -65,17 +68,17 @@ export interface AuthorMetadata { */ export interface BuildMetadata { /* - The bundle identifier to use in the application's plist. + *OS X-only.* The bundle identifier to use in the application's plist. */ - readonly "app-bundle-id": string + readonly "app-bundle-id"?: string /* - The application category type, as shown in the Finder via *View -> Arrange by Application Category* when viewing the Applications directory. + *OS X-only.* The application category type, as shown in the Finder via *View -> Arrange by Application Category* when viewing the Applications directory. For example, `app-category-type=public.app-category.developer-tools` will set the application category to *Developer Tools*. Valid values are listed in [Apple's documentation](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/LaunchServicesKeys.html#//apple_ref/doc/uid/TP40009250-SW8). */ - readonly "app-category-type": string + readonly "app-category-type"?: string /* *windows-only.* A URL to an ICO file to use as the application icon (displayed in Control Panel > Programs and Features). Defaults to the Electron icon. @@ -85,7 +88,7 @@ export interface BuildMetadata { * 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/${user}/${project}/master/build/icon.ico` by default. */ - readonly iconUrl: string + readonly iconUrl?: string /* See [AppMetadata.productName](#AppMetadata-productName). @@ -122,6 +125,8 @@ export interface BuildMetadata { The compression level, one of `store`, `normal`, `maximum` (default: `normal`). If you want to rapidly test build, `store` can reduce build time significantly. */ readonly compression?: "store" | "normal" | "maximum" + + readonly "build-version": string } /* @@ -169,10 +174,23 @@ export interface WinBuildOptions extends PlatformSpecificBuildOptions { ### `.build.linux` */ export interface LinuxBuildOptions { - name: string - comment: string + /* + As [description](#AppMetadata-description) from application package.json, but allows you to specify different for Linux. + */ + description?: string + + /* + The maintainer. Defaults to [author](#AppMetadata-author). + */ + maintainer?: string + + /* + The vendor. Defaults to [author](#AppMetadata-author). + */ + vendor?: string - maintainer: string + // should be not documented, only to experiment + fpm?: string[] //.desktop file template desktop?: string diff --git a/src/platformPackager.ts b/src/platformPackager.ts index d5e70023f5e..92036be222d 100644 --- a/src/platformPackager.ts +++ b/src/platformPackager.ts @@ -195,9 +195,8 @@ export abstract class PlatformPackager return null } - //noinspection JSMethodCanBeStatic protected computeBuildNumber(): string { - return process.env.TRAVIS_BUILD_NUMBER || process.env.APPVEYOR_BUILD_NUMBER || process.env.CIRCLE_BUILD_NUM + return this.devMetadata.build["build-version"] || process.env.TRAVIS_BUILD_NUMBER || process.env.APPVEYOR_BUILD_NUMBER || process.env.CIRCLE_BUILD_NUM } } diff --git a/test/src/helpers/packTester.ts b/test/src/helpers/packTester.ts index da3d01da052..a80292990b1 100755 --- a/test/src/helpers/packTester.ts +++ b/test/src/helpers/packTester.ts @@ -137,22 +137,36 @@ async function checkLinuxResult(projectDir: string, packager: Packager, packager assertThat(await getContents(`${projectDir}/${outDirName}/TestApp-1.1.0-i386.deb`, productName)).deepEqual(expectedContents) } - const regexp = /^ *(\w+): *(.+)$/gm - const info = (await exec("dpkg", ["--info", packageFile])).toString() - let match: Array - const metadata: any = {} - while ((match = regexp.exec(info)) !== null) { - metadata[match[1]] = match[2] - } - assertThat(metadata).has.properties({ + assertThat(parseDebControl((await exec("dpkg", ["--info", packageFile])).toString())).has.properties({ License: "MIT", Homepage: "http://foo.example.com", Maintainer: "Foo Bar ", + Vendor: "Foo Bar ", Package: "testapp", - Description: "Test Application", + Description: "TestApp\n Test Application", + Version: "1.1.0-42", }) } +function parseDebControl(info: string): any { + const regexp = /([\w]+): *(.+\n)([^:\n]+\n)?/g + let match: Array + const metadata: any = {} + info = info.substring(info.indexOf("Package:")) + while ((match = regexp.exec(info)) !== null) { + let value = match[2] + if (match[3] != null) { + value += match[3] + } + + if (value[value.length - 1] == "\n") { + value = value.substring(0, value.length - 1) + } + metadata[match[1]] = value + } + return metadata +} + async function checkOsXResult(packager: Packager, artifacts: Array) { const productName = getProductName(packager.metadata, packager.devMetadata) const packedAppDir = path.join(path.dirname(artifacts[0].file), (productName || packager.metadata.name) + ".app") diff --git a/tslint.json b/tslint.json index e6928a0fe24..6dfa3d49b6a 100644 --- a/tslint.json +++ b/tslint.json @@ -26,6 +26,7 @@ ], "no-use-before-declare": true, "no-internal-module": true, + "no-trailing-whitespace": true, "no-var-keyword": true, "one-line": [ true,