Skip to content

Commit

Permalink
feat(nsis): artifact file name pattern
Browse files Browse the repository at this point in the history
Close #1221, #1219
  • Loading branch information
develar committed Feb 8, 2017
1 parent 4546b1c commit 3d39fa6
Show file tree
Hide file tree
Showing 36 changed files with 224 additions and 137 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ A complete solution to package and build a ready for distribution Electron app f
* [Linux](https://github.com/electron-userland/electron-builder/wiki/Options#LinuxBuildOptions-target): [AppImage](http://appimage.org), [snap](http://snapcraft.io), debian package (`deb`), `rpm`, `freebsd`, `pacman`, `p5p`, `apk`.
* [Windows](https://github.com/electron-userland/electron-builder/wiki/Options#WinBuildOptions-target): NSIS, AppX (Windows Store), Squirrel.Windows.
* [Two package.json structure](https://github.com/electron-userland/electron-builder/wiki/Two-package.json-Structure) is supported, but you are not forced to use it even if you have native production dependencies.
* [Publishing artifacts](https://github.com/electron-userland/electron-builder/wiki/Publishing-Artifacts) to GitHub Releases and Bintray.
* [Publishing artifacts](https://github.com/electron-userland/electron-builder/wiki/Publishing-Artifacts) to GitHub Releases, Amazon S3 and Bintray.
* Pack in a distributable format [already packaged app](#pack-only-in-a-distributable-format).

| Question | Answer |
Expand Down
2 changes: 1 addition & 1 deletion circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ dependencies:
- sudo apt-get install git-lfs=1.3.0
- ssh [email protected] git-lfs-authenticate $CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME.git download
- git lfs pull
- docker run --rm --env-file ./test/docker-env.list -v ${PWD}:/project -v ~/.electron:/root/.electron -v ~/.cache/electron-builder:/root/.cache/electron-builder electronuserland/electron-builder:$([ "$CIRCLE_NODE_INDEX" == "2" ] && echo "6" || echo "wine") /bin/bash -c "node ./test/vendor/yarn.js && node ./test/vendor/yarn.js test"
- docker run --rm --env-file ./test/docker-env.list -v ${PWD}:/project -v ~/.electron:/root/.electron -v ~/.cache/electron-builder:/root/.cache/electron-builder electronuserland/electron-builder:wine) /bin/bash -c "node ./test/vendor/yarn.js && node ./test/vendor/yarn.js test"

test:
override:
Expand Down
2 changes: 1 addition & 1 deletion docs/Auto Update.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ Emitted when there is no available update.
* `total`
* `transferred`
Emitted on progress. Only supported over Windows build, since `Squirrel.Mac` does not provide this data.
Emitted on progress. Only supported over Windows build, since `Squirrel.Mac` [does not provide](https://github.com/electron-userland/electron-builder/issues/1167) this data.
#### Event: `update-downloaded`
Expand Down
1 change: 1 addition & 0 deletions docs/Options.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ See [NSIS target notes](https://github.com/electron-userland/electron-builder/wi
| language | <a name="NsisOptions-language"></a>* [LCID Dec](https://msdn.microsoft.com/en-au/goglobal/bb964664.aspx), defaults to `1033`(`English - United States`).
| warningsAsErrors | <a name="NsisOptions-warningsAsErrors"></a>Defaults to `true`. If `warningsAsErrors` is `true` (default): NSIS will treat warnings as errors. If `warningsAsErrors` is `false`: NSIS will allow warnings.
| menuCategory | <a name="NsisOptions-menuCategory"></a>Whether to create submenu for start menu shortcut and program files directory. Defaults to `false`. If `true`, company name will be used. Or string value.
| artifactName | <a name="NsisOptions-artifactName"></a><p>The artifact file name pattern. Defaults to <code>${productName} Setup ${version}.${ext}</code>. <code>${name}</code>, <code>${productName}</code>, <code>${version}</code>, <code>${ext}</code>, <code>${arch}</code>, <code>${os}</code> (expanded to <code>mac</code>, <code>linux</code> or <code>win</code> according to current platform) macro are supported.</p> <p>If no <code>arch</code>, macro will be removed from your pattern with leading space, <code>-</code> or <code>_</code> (so, you don’t need to worry and can reuse pattern).</p>

<a name="Protocol"></a>
### `protocols` URL Protocol Schemes
Expand Down
6 changes: 4 additions & 2 deletions docs/Publishing Artifacts.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ Travis and AppVeyor support publishing artifacts. But it requires additional con

`electron-builder` allows you to just add `GH_TOKEN` environment variable and that's all.

Currently, [GitHub Releases](https://help.github.com/articles/about-releases/), [Bintray](https://bintray.com) and [S3](https://aws.amazon.com/s3/) are supported.
Currently, [GitHub Releases](https://help.github.com/articles/about-releases/), [Amazon S3](https://aws.amazon.com/s3/) and [Bintray](https://bintray.com) are supported.

To use Amazon S3 please install `electron-publisher-s3` dependency.

## CLI Flags
```
Expand Down Expand Up @@ -72,7 +74,7 @@ But please consider using automatic rules instead of explicitly specifying `publ
<a name="PublishConfiguration"></a>
### `publish`

Can be specified in the [build](https://github.com/electron-userland/electron-builder/wiki/Options#build) or any platform- or target- specific options.
Can be specified in the [config](https://github.com/electron-userland/electron-builder/wiki/Options#configuration-options) or any platform- or target- specific options.

If `GH_TOKEN` is set — defaults to `[{provider: "github"}]`.
If `BT_TOKEN` is set and `GH_TOKEN` is not set — defaults to `[{provider: "bintray"}]`.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
"7zip-bin": "^2.0.4",
"archiver": "^1.3.0",
"asar-electron-builder": "^0.13.5",
"aws-sdk": "^2.9.0",
"aws-sdk": "^2.10.0",
"bluebird-lst-c": "^1.0.6",
"chalk": "^1.1.3",
"chromium-pickle-js": "^0.2.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/electron-builder-http/src/publishOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export type Publish = string | Array<string> | PublishConfiguration | GithubOpti
/*
### `publish`
Can be specified in the [build](https://github.com/electron-userland/electron-builder/wiki/Options#build) or any platform- or target- specific options.
Can be specified in the [config](https://github.com/electron-userland/electron-builder/wiki/Options#configuration-options) or any platform- or target- specific options.
If `GH_TOKEN` is set — defaults to `[{provider: "github"}]`.
If `BT_TOKEN` is set and `GH_TOKEN` is not set — defaults to `[{provider: "bintray"}]`.
Expand Down
6 changes: 4 additions & 2 deletions packages/electron-builder-publisher/readme.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# electron-publisher-s3
# electron-builder-publisher

Part of [electron-builder](https://github.com/electron-userland/electron-builder).

See the [Publishing Artifacts.](https://github.com/electron-userland/electron-builder/wiki/Publishing-Artifacts) section of the [Wiki](https://github.com/electron-userland/electron-builder/wiki) for more information.
See the [Publishing Artifacts](https://github.com/electron-userland/electron-builder/wiki/Publishing-Artifacts) section of the [Wiki](https://github.com/electron-userland/electron-builder/wiki) for more information.

Can be used standalone.
2 changes: 1 addition & 1 deletion packages/electron-builder-publisher/src/gitHubPublisher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export class GitHubPublisher extends HttpPublisher {
}

constructor(context: PublishContext, private readonly info: GithubOptions, private readonly version: string, private readonly options: PublishOptions = {}) {
super(context)
super(context, true)

let token = info.token
if (isEmptyOrSpaces(token)) {
Expand Down
8 changes: 4 additions & 4 deletions packages/electron-builder-publisher/src/publisher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export abstract class Publisher {

abstract get providerName(): string

abstract upload(file: string, artifactName?: string): Promise<any>
abstract upload(file: string, safeArtifactName?: string): Promise<any>

protected createProgressBar(fileName: string, fileStat: Stats): ProgressBar | null {
if (this.context.progress == null) {
Expand Down Expand Up @@ -63,12 +63,12 @@ export abstract class Publisher {
}

export abstract class HttpPublisher extends Publisher {
constructor(protected readonly context: PublishContext) {
constructor(protected readonly context: PublishContext, private readonly useSafeArtifactName = false) {
super(context)
}

async upload(file: string, artifactName?: string): Promise<any> {
const fileName = artifactName || basename(file)
async upload(file: string, safeArtifactName?: string): Promise<any> {
const fileName = (this.useSafeArtifactName ? safeArtifactName : null) || basename(file)
const fileStat = await stat(file)

const progressBar = this.createProgressBar(fileName, fileStat)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@ import { buildInstaller, convertVersion, SquirrelOptions } from "./squirrelPack"
import { SquirrelWindowsOptions } from "electron-builder/out/options/winOptions"
import { Target, Arch, getArchSuffix } from "electron-builder-core"

const SW_VERSION = "1.5.1.4"
const SW_VERSION = "1.5.2.0"
//noinspection SpellCheckingInspection
const SW_SHA2 = "30caa74802259f956d7b73f4b282917c10c6dd3d29f5ca3e4d996b2896f2aa0d"
const SW_SHA2 = "e96a109d4641ebb85d163eaefe7770b165ebc25d1cc77c5179f021b232fc3730"

export default class SquirrelWindowsTarget extends Target {
private readonly options: SquirrelWindowsOptions = Object.assign({}, this.packager.platformSpecificBuildOptions, this.packager.config.squirrelWindows)
Expand Down
21 changes: 0 additions & 21 deletions packages/electron-builder/src/errorMessages.ts
Original file line number Diff line number Diff line change
@@ -1,28 +1,7 @@
export const buildIsMissed = `Please specify 'build' configuration in the development package.json ('%s'), at least
build: {
"appId": "your.id",
"category": "your.app.category.type"
}
}
is required.
`

export const authorEmailIsMissed = `Please specify author 'email' in the application package.json
See https://docs.npmjs.com/files/package.json#people-fields-author-contributors
It is required to set Linux .deb package maintainer. Or you can set maintainer in the custom linux options.
(see https://github.com/electron-userland/electron-builder#distributable-format-configuration).
`

export const buildInAppSpecified = `'build' in the application package.json ('%s') is not supported since 3.0 anymore
Please move 'build' into the development package.json ('%s')
`

export const nameInBuildSpecified = `'name' in the 'build' is forbidden.
Please move 'name' from 'build' into the application package.json ('%s')
`
7 changes: 7 additions & 0 deletions packages/electron-builder/src/options/winOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,13 @@ export interface NsisOptions {

// defaults to false
readonly useZip?: boolean

/*
The artifact file name pattern. Defaults to `${productName} Setup ${version}.${ext}`. `${name}`, `${productName}`, `${version}`, `${ext}`, `${arch}`, `${os}` (expanded to `mac`, `linux` or `win` according to current platform) macro are supported.
If no `arch`, macro will be removed from your pattern with leading space, `-` or `_` (so, you don't need to worry and can reuse pattern).
*/
readonly artifactName?: string | null
}

/*
Expand Down
66 changes: 32 additions & 34 deletions packages/electron-builder/src/packager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,7 @@ import { TmpDir } from "electron-builder-util/out/tmp"
import { EventEmitter } from "events"
import * as path from "path"
import { lt as isVersionLessThan } from "semver"
import * as util from "util"
import { AppInfo } from "./appInfo"
import * as errorMessages from "./errorMessages"
import MacPackager from "./macPackager"
import { AfterPackContext, Config, Metadata } from "./metadata"
import { ArtifactCreated, BuildInfo, PackagerOptions, SourceRepositoryInfo } from "./packagerApi"
Expand Down Expand Up @@ -273,8 +271,9 @@ export class Packager implements BuildInfo {
}

private checkMetadata(appPackageFile: string, devAppPackageFile: string): void {
const errors: Array<string> = []
const reportError = (missedFieldName: string) => {
throw new Error(`Please specify '${missedFieldName}' in the application package.json ('${appPackageFile}')`)
errors.push(`Please specify '${missedFieldName}' in the application package.json ('${appPackageFile}')`)
}

const checkNotEmpty = (name: string, value: string | n) => {
Expand All @@ -289,45 +288,44 @@ export class Packager implements BuildInfo {
checkNotEmpty("description", appMetadata.description)
checkNotEmpty("version", appMetadata.version)

checkDependencies(this.devMetadata.dependencies)
checkDependencies(this.devMetadata.dependencies, errors)
if ((<any>appMetadata) !== this.devMetadata) {
checkDependencies(appMetadata.dependencies)
checkDependencies(appMetadata.dependencies, errors)

if ((<any>appMetadata).build != null) {
throw new Error(util.format(errorMessages.buildInAppSpecified, appPackageFile, devAppPackageFile))
errors.push(`'build' in the application package.json (${appPackageFile}) is not supported since 3.0 anymore. Please move 'build' into the development package.json (${devAppPackageFile})`)
}
}

const build = <any>this.config
if (build == null) {
throw new Error(util.format(errorMessages.buildIsMissed, devAppPackageFile))
const config = <any>this.config
if (config["osx-sign"] != null) {
errors.push("osx-sign is deprecated and not supported — please see https://github.com/electron-userland/electron-builder/wiki/Code-Signing")
}
if (config["osx"] != null) {
errors.push(`osx is deprecated and not supported — please use mac instead`)
}
if (config["app-copyright"] != null) {
errors.push(`app-copyright is deprecated and not supported — please use copyright instead`)
}
if (config["app-category-type"] != null) {
errors.push(`app-category-type is deprecated and not supported — please use mac.category instead`)
}
else {
if (build["osx-sign"] != null) {
throw new Error("osx-sign is deprecated and not supported — please see https://github.com/electron-userland/electron-builder/wiki/Code-Signing")
}
if (build["osx"] != null) {
throw new Error(`build.osx is deprecated and not supported — please use build.mac instead`)
}
if (build["app-copyright"] != null) {
throw new Error(`build.app-copyright is deprecated and not supported — please use build.copyright instead`)
}
if (build["app-category-type"] != null) {
throw new Error(`build.app-category-type is deprecated and not supported — please use build.mac.category instead`)
}

const author = appMetadata.author
if (author == null) {
throw new Error(`Please specify "author" in the application package.json ('${appPackageFile}') — it is used as company name.`)
}
const author = appMetadata.author
if (author == null) {
errors.push(`Please specify "author" in the application package.json ('${appPackageFile}') — it is used as company name and copyright owner.`)
}

if (build.name != null) {
throw new Error(util.format(errorMessages.nameInBuildSpecified, appPackageFile))
}
if (config.name != null) {
errors.push(`'name' in the config is forbidden. Please move 'name' into the package.json (${appPackageFile})`)
}

if (build.prune != null) {
warn("prune is deprecated — development dependencies are never copied in any case")
}
if (config.prune != null) {
errors.push("prune is deprecated — development dependencies are never copied in any case")
}

if (errors.length > 0) {
throw new Error(errors.join("\n"))
}
}

Expand Down Expand Up @@ -450,14 +448,14 @@ export async function checkWineVersion(checkPromise: Promise<string>) {
}
}

function checkDependencies(dependencies?: { [key: string]: string }) {
function checkDependencies(dependencies: { [key: string]: string } | null | undefined, errors: Array<string>) {
if (dependencies == null) {
return
}

for (const name of ["electron", "electron-prebuilt", "electron-builder"]) {
if (name in dependencies) {
throw new Error(`Package "${name}" is only allowed in "devDependencies". `
errors.push(`Package "${name}" is only allowed in "devDependencies". `
+ `Please remove it from the "dependencies" section in your package.json.`)
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/electron-builder/src/packagerApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ export interface ArtifactCreated {
readonly file?: string
readonly data?: Buffer

readonly artifactName?: string
readonly safeArtifactName?: string

readonly publishConfig?: PublishConfiguration
}
Expand Down
44 changes: 42 additions & 2 deletions packages/electron-builder/src/platformPackager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,10 +84,10 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>
return this.packagerOptions.prepackaged || path.join(outDir, `${this.platform.buildConfigurationKey}${getArchSuffix(arch)}${this.platform === Platform.MAC ? "" : "-unpacked"}`)
}

dispatchArtifactCreated(file: string, target: Target | null, artifactName?: string) {
dispatchArtifactCreated(file: string, target: Target | null, safeArtifactName?: string) {
this.info.dispatchArtifactCreated({
file: file,
artifactName: artifactName,
safeArtifactName: safeArtifactName,
packager: this,
target: target,
})
Expand Down Expand Up @@ -394,6 +394,46 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>
await this.checkFileInPackage(resourcesDir, "package.json", "Application", isAsar)
}

expandArtifactNamePattern(pattern: string, ext: string, arch: Arch | null): string {
let p = pattern
if (arch == null) {
p = p
.replace("-${arch}", "")
.replace(" ${arch}", "")
.replace("_${arch}", "")
}

const appInfo = this.appInfo
return p.replace(/\$\{([a-zA-Z]+)\}/g, (match, p1): string => {
switch (p1) {
case "name":
return appInfo.name

case "version":
return appInfo.version

case "productName":
return appInfo.productFilename

case "arch":
if (arch == null) {
// see above, we remove macro if no arch
return ""
}
return Arch[arch]

case "os":
return this.platform.name

case "ext":
return ext

default:
throw new Error(`Macro ${p1} is not defined`)
}
})
}

generateName(ext: string | null, arch: Arch, deployment: boolean, classifier: string | null = null): string {
let c: string | null = null
let e: string | null = null
Expand Down
Loading

0 comments on commit 3d39fa6

Please sign in to comment.