From ec3b2f37948f4257559bc50e2cd84843cf71aa6e Mon Sep 17 00:00:00 2001 From: develar Date: Wed, 1 Feb 2017 09:01:04 +0100 Subject: [PATCH] feat: ${os} and ${arch} in publish.url Close #1194 --- docs/Options.md | 22 ++++----- docs/Publishing Artifacts.md | 2 +- .../src/publishOptions.ts | 2 +- packages/electron-builder/src/fileMatcher.ts | 18 +++---- packages/electron-builder/src/metadata.ts | 14 ++++-- .../electron-builder/src/platformPackager.ts | 27 +++++----- .../src/publish/PublishManager.ts | 49 ++++++++++++------- .../mac/__snapshots__/macPackagerTest.js.snap | 2 +- test/src/mac/macPackagerTest.ts | 2 +- test/src/windows/nsisTest.ts | 2 +- 10 files changed, 77 insertions(+), 63 deletions(-) diff --git a/docs/Options.md b/docs/Options.md index e2d740891ae..81e2d1be8b9 100644 --- a/docs/Options.md +++ b/docs/Options.md @@ -37,9 +37,9 @@ Don't customize paths to background and icon, — just follow conventions. * [protocols URL Protocol Schemes](#Protocol) * [squirrelWindows](#SquirrelWindowsOptions) * [win Windows Specific Options](#WinBuildOptions) - * [dmg.window DMG Windows Position and Size](#DmgWindow) * [snap [Snap](http://snapcraft.io) Specific Options](#SnapOptions) * [appImage [AppImage](http://appimage.org) Specific Options](#AppImageOptions) + * [dmg.window DMG Windows Position and Size](#DmgWindow) * [Fields in the package.json](#Metadata) @@ -219,15 +219,6 @@ To use Squirrel.Windows please install `electron-builder-squirrel-windows` depen | rfc3161TimeStampServer | The URL of the RFC 3161 time stamp server. Defaults to `http://timestamp.comodoca.com/rfc3161`. | timeStampServer | The URL of the time stamp server. Defaults to `http://timestamp.verisign.com/scripts/timstamp.dll`. - -### `dmg.window` DMG Windows Position and Size -| Name | Description -| --- | --- -| x | The X position relative to left of the screen. Defaults to 400. -| y | The Y position relative to top of the screen. Defaults to 100. -| width | * The width. Defaults to background image width or 540. -| height | * The height. Defaults to background image height or 380. - ### `snap` [Snap](http://snapcraft.io) Specific Options | Name | Description @@ -245,6 +236,15 @@ To use Squirrel.Windows please install `electron-builder-squirrel-windows` depen | --- | --- | includeRequiredLib | Whether to include required system libraries (`gconf2`, `libappindicator1`). Defaults to `false`. + +### `dmg.window` DMG Windows Position and Size +| Name | Description +| --- | --- +| x | The X position relative to left of the screen. Defaults to 400. +| y | The Y position relative to top of the screen. Defaults to 100. +| width | * The width. Defaults to background image width or 540. +| height | * The height. Defaults to background image height or 380. + ## Fields in the package.json @@ -274,7 +274,7 @@ Some standard fields should be defined in the `package.json`. Development dependencies are never copied in any case. You don't need to ignore it explicitly. -[Multiple patterns](#multiple-glob-patterns) are supported. You can use `${os}` (expanded to mac, linux or win according to current platform) and `${arch}` in the pattern. +[Multiple patterns](#multiple-glob-patterns) are supported. You can use `${os}` (expanded to `mac`, `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 `foo` directory. Remember that default pattern `**/*` **is not added to your custom** if some of your patterns is not ignore (i.e. not starts with `!`). diff --git a/docs/Publishing Artifacts.md b/docs/Publishing Artifacts.md index 5ace91c39ba..296c2e97822 100644 --- a/docs/Publishing Artifacts.md +++ b/docs/Publishing Artifacts.md @@ -97,7 +97,7 @@ Amazon S3 — `https` must be used, so, if you use direct Amazon S3 endpoints, f ### `publish` Generic (any https server) | Name | Description | --- | --- -| **url** | The base url. e.g. `https://s3.amazonaws.com/bucket_name` +| **url** | The base url. e.g. `https://s3.amazonaws.com/bucket_name`. You can use `${os}` (expanded to `mac`, `linux` or `win` according to current platform) and `${arch}` macros. | channel | The channel. Defaults to `latest`. diff --git a/packages/electron-builder-http/src/publishOptions.ts b/packages/electron-builder-http/src/publishOptions.ts index 04ca1f23f77..3d1c29943db 100644 --- a/packages/electron-builder-http/src/publishOptions.ts +++ b/packages/electron-builder-http/src/publishOptions.ts @@ -33,7 +33,7 @@ export interface PublishConfiguration { */ export interface GenericServerOptions extends PublishConfiguration { /* - The base url. e.g. `https://s3.amazonaws.com/bucket_name` + The base url. e.g. `https://s3.amazonaws.com/bucket_name`. You can use `${os}` (expanded to `mac`, `linux` or `win` according to current platform) and `${arch}` macros. */ url: string diff --git a/packages/electron-builder/src/fileMatcher.ts b/packages/electron-builder/src/fileMatcher.ts index 6c9ab78fc55..8e1d4ed04ce 100644 --- a/packages/electron-builder/src/fileMatcher.ts +++ b/packages/electron-builder/src/fileMatcher.ts @@ -1,16 +1,12 @@ -import * as path from "path" -import { createFilter, hasMagic } from "./util/filter" -import { Minimatch } from "minimatch" -import { asArray } from "electron-builder-util" import BluebirdPromise from "bluebird-lst-c" -import { statOrNull, copyDir, copyFile, Filter } from "electron-builder-util/out/fs" +import { asArray } from "electron-builder-util" +import { copyDir, copyFile, Filter, statOrNull } from "electron-builder-util/out/fs" import { warn } from "electron-builder-util/out/log" import { mkdirs } from "fs-extra-p" - -export interface FileMatchOptions { - arch: string, - os: string -} +import { Minimatch } from "minimatch" +import * as path from "path" +import { Macros } from "./metadata" +import { createFilter, hasMagic } from "./util/filter" export class FileMatcher { readonly from: string @@ -18,7 +14,7 @@ export class FileMatcher { readonly patterns: Array - constructor(from: string, to: string, private options: FileMatchOptions, patterns?: Array | string | n) { + constructor(from: string, to: string, private options: Macros, patterns?: Array | string | n) { this.from = this.expandPattern(from) this.to = this.expandPattern(to) this.patterns = asArray(patterns).map(it => path.posix.normalize(it)) diff --git a/packages/electron-builder/src/metadata.ts b/packages/electron-builder/src/metadata.ts index 45562b33a5e..4c132574e0a 100755 --- a/packages/electron-builder/src/metadata.ts +++ b/packages/electron-builder/src/metadata.ts @@ -1,9 +1,9 @@ -import { PlatformPackager } from "./platformPackager" -import { MacOptions, DmgOptions, MasBuildOptions } from "./options/macOptions" +import { Arch, Platform } from "electron-builder-core" import { Publish } from "electron-builder-http/out/publishOptions" -import { WinBuildOptions, NsisOptions, SquirrelWindowsOptions, AppXOptions } from "./options/winOptions" import { LinuxBuildOptions, SnapOptions } from "./options/linuxOptions" -import { Platform } from "electron-builder-core" +import { DmgOptions, MacOptions, MasBuildOptions } from "./options/macOptions" +import { AppXOptions, NsisOptions, SquirrelWindowsOptions, WinBuildOptions } from "./options/winOptions" +import { PlatformPackager } from "./platformPackager" export interface AsarOptions { dot?: boolean @@ -222,6 +222,7 @@ export interface AfterPackContext { readonly appOutDir: string readonly packager: PlatformPackager readonly electronPlatformName: string + readonly arch: Arch } export interface BeforeBuildContext { @@ -332,4 +333,9 @@ export interface PlatformSpecificBuildOptions { readonly publish?: Publish readonly forceCodeSigning?: boolean +} + +export interface Macros { + os: string + arch: string } \ No newline at end of file diff --git a/packages/electron-builder/src/platformPackager.ts b/packages/electron-builder/src/platformPackager.ts index 9a3537819dd..d400e7c0f07 100644 --- a/packages/electron-builder/src/platformPackager.ts +++ b/packages/electron-builder/src/platformPackager.ts @@ -1,19 +1,19 @@ -import { PlatformSpecificBuildOptions, FileAssociation, Config, AsarOptions, FilePattern } from "./metadata" import BluebirdPromise from "bluebird-lst-c" -import * as path from "path" +import { Arch, getArchSuffix, Platform, Target } from "electron-builder-core" +import { asArray, debug, isEmptyOrSpaces, use } from "electron-builder-util" +import { deepAssign } from "electron-builder-util/out/deepAssign" +import { copyDir, statOrNull, unlinkIfExists } from "electron-builder-util/out/fs" +import { log, warn } from "electron-builder-util/out/log" import { readdir, remove, rename } from "fs-extra-p" -import { use, isEmptyOrSpaces, asArray, debug } from "electron-builder-util" import { Minimatch } from "minimatch" -import { checkFileInArchive, createAsarArchive } from "./asarUtil" -import { warn, log } from "electron-builder-util/out/log" +import * as path from "path" import { AppInfo } from "./appInfo" +import { checkFileInArchive, createAsarArchive } from "./asarUtil" +import { copyFiles, deprecatedUserIgnoreFilter, FileMatcher } from "./fileMatcher" +import { AsarOptions, Config, FileAssociation, FilePattern, Macros, PlatformSpecificBuildOptions } from "./metadata" import { unpackElectron } from "./packager/dirPackager" -import { FileMatchOptions, FileMatcher, deprecatedUserIgnoreFilter, copyFiles } from "./fileMatcher" -import { deepAssign } from "electron-builder-util/out/deepAssign" -import { statOrNull, unlinkIfExists, copyDir } from "electron-builder-util/out/fs" -import { Arch, Target, getArchSuffix, Platform } from "electron-builder-core" +import { BuildInfo, PackagerOptions } from "./packagerApi" import { readInstalled } from "./readInstalled" -import { PackagerOptions, BuildInfo } from "./packagerApi" export abstract class PlatformPackager { readonly packagerOptions: PackagerOptions @@ -104,7 +104,7 @@ export abstract class PlatformPackager .then(() => BluebirdPromise.each(targets, it => it.isAsyncSupported ? null : it.build(appOutDir, arch)))) } - private getExtraFileMatchers(isResources: boolean, appOutDir: string, fileMatchOptions: FileMatchOptions, customBuildOptions: DC): Array | null { + private getExtraFileMatchers(isResources: boolean, appOutDir: string, fileMatchOptions: Macros, customBuildOptions: DC): Array | null { const base = isResources ? this.getResourcesDir(appOutDir) : (this.platform === Platform.MAC ? path.join(appOutDir, `${this.appInfo.productFilename}.app`, "Contents") : appOutDir) return this.getFileMatchers(isResources ? "extraResources" : "extraFiles", this.projectDir, base, true, fileMatchOptions, customBuildOptions) } @@ -115,7 +115,7 @@ export abstract class PlatformPackager } const asarOptions = await this.computeAsarOptions(platformSpecificBuildOptions) - const fileMatchOptions: FileMatchOptions = { + const fileMatchOptions: Macros = { arch: Arch[arch], os: this.platform.buildConfigurationKey } @@ -220,6 +220,7 @@ export abstract class PlatformPackager appOutDir: appOutDir, packager: this, electronPlatformName: platformName, + arch: arch, }) await this.sanityCheckPackage(appOutDir, asarOptions != null) } @@ -272,7 +273,7 @@ export abstract class PlatformPackager return deepAssign({}, result, defaultOptions) } - private getFileMatchers(name: "files" | "extraFiles" | "extraResources" | "asarUnpack", defaultSrc: string, defaultDest: string, allowAdvancedMatching: boolean, fileMatchOptions: FileMatchOptions, customBuildOptions: DC): Array | null { + private getFileMatchers(name: "files" | "extraFiles" | "extraResources" | "asarUnpack", defaultSrc: string, defaultDest: string, allowAdvancedMatching: boolean, fileMatchOptions: Macros, customBuildOptions: DC): Array | null { const globalPatterns: Array | string | n | FilePattern = (this.config)[name] const platformSpecificPatterns: Array | string | n = (customBuildOptions)[name] diff --git a/packages/electron-builder/src/publish/PublishManager.ts b/packages/electron-builder/src/publish/PublishManager.ts index c30f41670eb..77e99cc0bba 100644 --- a/packages/electron-builder/src/publish/PublishManager.ts +++ b/packages/electron-builder/src/publish/PublishManager.ts @@ -1,23 +1,23 @@ -import { Packager } from "../packager" -import { PlatformPackager } from "../platformPackager" -import { debug, isEmptyOrSpaces, asArray} from "electron-builder-util" -import { Publisher, PublishOptions, getResolvedPublishConfig, getCiTag } from "./publisher" import BluebirdPromise from "bluebird-lst-c" -import { GitHubPublisher } from "./gitHubPublisher" -import { PublishConfiguration, GithubOptions, BintrayOptions, GenericServerOptions, VersionInfo, UpdateInfo } from "electron-builder-http/out/publishOptions" +import { createHash } from "crypto" +import { Platform, Arch } from "electron-builder-core" +import { BintrayOptions, GenericServerOptions, GithubOptions, PublishConfiguration, UpdateInfo, VersionInfo } from "electron-builder-http/out/publishOptions" +import { asArray, debug, isEmptyOrSpaces } from "electron-builder-util" import { log } from "electron-builder-util/out/log" -import { BintrayPublisher } from "./BintrayPublisher" -import { BuildInfo, ArtifactCreated } from "../packagerApi" -import { Platform } from "electron-builder-core" -import { safeDump } from "js-yaml" -import { writeFile, outputJson, createReadStream } from "fs-extra-p" -import * as path from "path" -import { ArchiveTarget } from "../targets/ArchiveTarget" import { throwError } from "electron-builder-util/out/promise" +import { createReadStream, outputJson, writeFile } from "fs-extra-p" import isCi from "is-ci" +import { safeDump } from "js-yaml" +import * as path from "path" import * as url from "url" -import { PlatformSpecificBuildOptions } from "../metadata" -import { createHash } from "crypto" +import { Macros, PlatformSpecificBuildOptions } from "../metadata" +import { Packager } from "../packager" +import { ArtifactCreated, BuildInfo } from "../packagerApi" +import { PlatformPackager } from "../platformPackager" +import { ArchiveTarget } from "../targets/ArchiveTarget" +import { BintrayPublisher } from "./BintrayPublisher" +import { GitHubPublisher } from "./gitHubPublisher" +import { getCiTag, getResolvedPublishConfig, Publisher, PublishOptions } from "./publisher" export class PublishManager { private readonly nameToPublisher = new Map() @@ -68,7 +68,11 @@ export class PublishManager { return } - await writeFile(path.join(packager.getResourcesDir(event.appOutDir), "app-update.yml"), safeDump(publishConfigs[0])) + let publishConfig = publishConfigs[0] + if ((publishConfig).url != null) { + publishConfig = Object.assign({}, publishConfig, {url: expandPattern((publishConfig).url, {os: packager.platform.buildConfigurationKey, arch: Arch[Arch.x64]})}) + } + await writeFile(path.join(packager.getResourcesDir(event.appOutDir), "app-update.yml"), safeDump(publishConfig)) }) packager.artifactCreated(event => this.addTask(this.artifactCreated(event))) @@ -191,7 +195,7 @@ async function writeUpdateInfo(event: ArtifactCreated, _publishConfigs: ArrayoutputJson)(updateInfoFile, { version: version, - url: computeDownloadUrl(publishConfig, packager.generateName2("zip", "mac", isGitHub), version) + url: computeDownloadUrl(publishConfig, packager.generateName2("zip", "mac", isGitHub), version, {os: Platform.MAC.buildConfigurationKey, arch: Arch[Arch.x64]}) }, {spaces: 2}) packager.info.dispatchArtifactCreated({ @@ -261,9 +265,9 @@ function isAuthTokenSet() { return !isEmptyOrSpaces(process.env.GH_TOKEN) || !isEmptyOrSpaces(process.env.BT_TOKEN) } -function computeDownloadUrl(publishConfig: PublishConfiguration, fileName: string, version: string) { +function computeDownloadUrl(publishConfig: PublishConfiguration, fileName: string, version: string, macros: Macros) { if (publishConfig.provider === "generic") { - const baseUrl = url.parse((publishConfig).url) + const baseUrl = url.parse(expandPattern((publishConfig).url, macros)) return url.format(Object.assign({}, baseUrl, {pathname: path.posix.resolve(baseUrl.pathname || "/", encodeURI(fileName))})) } else { @@ -272,6 +276,13 @@ function computeDownloadUrl(publishConfig: PublishConfiguration, fileName: strin } } +function expandPattern(pattern: string, macros: Macros): string { + return pattern + .replace(/\$\{os}/g, macros.os) + .replace(/\$\{arch}/g, macros.arch) +} + + export function getPublishConfigs(packager: PlatformPackager, targetSpecificOptions: PlatformSpecificBuildOptions | null | undefined, errorIfCannot: boolean): Promise> | null { let publishers diff --git a/test/out/mac/__snapshots__/macPackagerTest.js.snap b/test/out/mac/__snapshots__/macPackagerTest.js.snap index 98dde7cdb38..106c95e5f97 100644 --- a/test/out/mac/__snapshots__/macPackagerTest.js.snap +++ b/test/out/mac/__snapshots__/macPackagerTest.js.snap @@ -59,7 +59,7 @@ Array [ exports[`test one-package 3`] = ` Object { - "url": "https://develar.s3.amazonaws.com/test/Test%20App%20%C3%9FW-1.1.0-mac.zip", + "url": "https://develar.s3.amazonaws.com/test/mac/x64/Test%20App%20%C3%9FW-1.1.0-mac.zip", "version": "1.1.0", } `; diff --git a/test/src/mac/macPackagerTest.ts b/test/src/mac/macPackagerTest.ts index 796a0902dec..2437ab34db1 100644 --- a/test/src/mac/macPackagerTest.ts +++ b/test/src/mac/macPackagerTest.ts @@ -13,7 +13,7 @@ test.ifMac("one-package", app({ config: { publish: { provider: "generic", - url: "https://develar.s3.amazonaws.com/test", + url: "https://develar.s3.amazonaws.com/test/${os}/${arch}", }, mac: { fileAssociations: [ diff --git a/test/src/windows/nsisTest.ts b/test/src/windows/nsisTest.ts index 8c54a6a7c44..680685c8fbe 100644 --- a/test/src/windows/nsisTest.ts +++ b/test/src/windows/nsisTest.ts @@ -50,7 +50,7 @@ test.ifDevOrLinuxCi("perMachine, no run after finish", app({ }, publish: { provider: "generic", - url: "https://develar.s3.amazonaws.com/test", + url: "https://develar.s3.amazonaws.com/test/${os}/${arch}", }, }, }, {