Skip to content

Commit

Permalink
feat(mac): extra dist files
Browse files Browse the repository at this point in the history
Close #3148
  • Loading branch information
develar committed Aug 10, 2018
1 parent dfa9f7d commit efb40da
Show file tree
Hide file tree
Showing 12 changed files with 512 additions and 426 deletions.
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@
"sanitize-filename": "^1.6.1",
"sax": "^1.2.4",
"semver": "^5.5.0",
"source-map-support": "^0.5.6",
"source-map-support": "^0.5.8",
"stat-mode": "^0.2.2",
"sumchecker": "^2.0.2",
"temp-file": "^3.1.3",
Expand All @@ -69,10 +69,10 @@
"yargs": "^12.0.1"
},
"devDependencies": {
"@babel/core": "^7.0.0-beta.56",
"@babel/preset-env": "^7.0.0-beta.56",
"@babel/preset-react": "^7.0.0-beta.56",
"@babel/preset-stage-0": "^7.0.0-beta.56",
"@babel/core": "^7.0.0-rc.1",
"@babel/preset-env": "^7.0.0-rc.1",
"@babel/preset-react": "^7.0.0-rc.1",
"@babel/preset-stage-0": "^7.0.0-rc.1",
"@types/debug": "^0.0.30",
"@types/ejs": "^2.6.0",
"@types/electron-is-dev": "^0.3.0",
Expand Down
29 changes: 17 additions & 12 deletions packages/app-builder-lib/src/fileMatcher.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import BluebirdPromise from "bluebird-lst"
import { asArray, log } from "builder-util"
import { copyDir, copyOrLinkFile, Filter, statOrNull, FileTransformer } from "builder-util/out/fs"
import { copyDir, copyOrLinkFile, Filter, statOrNull, FileTransformer, USE_HARD_LINKS } from "builder-util/out/fs"
import { ensureDir } from "fs-extra-p"
import { Minimatch } from "minimatch"
import * as path from "path"
Expand Down Expand Up @@ -119,10 +119,11 @@ export function getMainFileMatchers(appDir: string, destination: string, macroEx
const packager = platformPackager.info
const buildResourceDir = path.resolve(packager.projectDir, packager.buildResourcesDir)

let matchers = packager.isPrepackedAppAsar ? null : getFileMatchers(packager.config, "files", appDir, destination, {
let matchers = packager.isPrepackedAppAsar ? null : getFileMatchers(packager.config, "files", destination, {
macroExpander,
customBuildOptions: platformSpecificBuildOptions,
outDir,
globalOutDir: outDir,
defaultSrc: appDir,
})
if (matchers == null) {
matchers = [new FileMatcher(appDir, destination, macroExpander)]
Expand Down Expand Up @@ -233,12 +234,14 @@ export function getNodeModuleFileMatcher(appDir: string, destination: string, ma
export interface GetFileMatchersOptions {
readonly macroExpander: (pattern: string) => string
readonly customBuildOptions: PlatformSpecificBuildOptions
readonly outDir: string
readonly globalOutDir: string

readonly defaultSrc: string
}

/** @internal */
export function getFileMatchers(config: Configuration, name: "files" | "extraFiles" | "extraResources" | "asarUnpack", defaultSrc: string, defaultDestination: string, options: GetFileMatchersOptions): Array<FileMatcher> | null {
const defaultMatcher = new FileMatcher(defaultSrc, defaultDestination, options.macroExpander)
export function getFileMatchers(config: Configuration, name: "files" | "extraFiles" | "extraResources" | "asarUnpack" | "extraDistFiles", defaultDestination: string, options: GetFileMatchersOptions): Array<FileMatcher> | null {
const defaultMatcher = new FileMatcher(options.defaultSrc, defaultDestination, options.macroExpander)
const fileMatchers: Array<FileMatcher> = []

function addPatterns(patterns: Array<string | FileSet> | string | null | undefined | FileSet) {
Expand All @@ -262,14 +265,16 @@ export function getFileMatchers(config: Configuration, name: "files" | "extraFil
throw new Error(`Advanced file copying not supported for "${name}"`)
}
else {
const from = pattern.from == null ? defaultSrc : path.resolve(defaultSrc, pattern.from)
const from = pattern.from == null ? options.defaultSrc : path.resolve(options.defaultSrc, pattern.from)
const to = pattern.to == null ? defaultDestination : path.resolve(defaultDestination, pattern.to)
fileMatchers.push(new FileMatcher(from, to, options.macroExpander, pattern.filter))
}
}
}

addPatterns((config as any)[name])
if (name !== "extraDistFiles") {
addPatterns((config as any)[name])
}
addPatterns((options.customBuildOptions as any)[name])

if (!defaultMatcher.isEmpty()) {
Expand All @@ -278,7 +283,7 @@ export function getFileMatchers(config: Configuration, name: "files" | "extraFil
}

// we cannot exclude the whole out dir, because sometimes users want to use some file in the out dir in the patterns
const relativeOutDir = defaultMatcher.normalizePattern(path.relative(defaultSrc, options.outDir))
const relativeOutDir = defaultMatcher.normalizePattern(path.relative(options.defaultSrc, options.globalOutDir))
if (!relativeOutDir.startsWith(".")) {
defaultMatcher.addPattern(`!${relativeOutDir}/*-unpacked{,/**/*}`)
}
Expand All @@ -287,7 +292,7 @@ export function getFileMatchers(config: Configuration, name: "files" | "extraFil
}

/** @internal */
export function copyFiles(matchers: Array<FileMatcher> | null, transformer: FileTransformer | null): Promise<any> {
export function copyFiles(matchers: Array<FileMatcher> | null, transformer: FileTransformer | null, isUseHardLink?: boolean): Promise<any> {
if (matchers == null || matchers.length === 0) {
return Promise.resolve()
}
Expand All @@ -303,7 +308,7 @@ export function copyFiles(matchers: Array<FileMatcher> | null, transformer: File
const toStat = await statOrNull(matcher.to)
// https://github.com/electron-userland/electron-builder/issues/1245
if (toStat != null && toStat.isDirectory()) {
return await copyOrLinkFile(matcher.from, path.join(matcher.to, path.basename(matcher.from)), fromStat)
return await copyOrLinkFile(matcher.from, path.join(matcher.to, path.basename(matcher.from)), fromStat, isUseHardLink)
}

await ensureDir(path.dirname(matcher.to))
Expand All @@ -314,6 +319,6 @@ export function copyFiles(matchers: Array<FileMatcher> | null, transformer: File
matcher.prependPattern("**/*")
}
log.debug({matcher}, "copying files using pattern")
return await copyDir(matcher.from, matcher.to, {filter: matcher.createFilter(), transformer})
return await copyDir(matcher.from, matcher.to, {filter: matcher.createFilter(), transformer, isUseHardLink: isUseHardLink ? USE_HARD_LINKS : null})
})
}
5 changes: 5 additions & 0 deletions packages/app-builder-lib/src/options/macOptions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ export interface MacConfiguration extends PlatformSpecificBuildOptions {
readonly cscInstallerLink?: string | null
/** @private */
readonly cscInstallerKeyPassword?: string | null

/**
* Extra files to put in archive. Not applicable for `tar.*`.
*/
readonly extraDistFiles?: Array<string> | string | null
}

/**
Expand Down
25 changes: 15 additions & 10 deletions packages/app-builder-lib/src/platformPackager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,7 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>

private getExtraFileMatchers(isResources: boolean, appOutDir: string, options: GetFileMatchersOptions): Array<FileMatcher> | null {
const base = isResources ? this.getResourcesDir(appOutDir) : (this.platform === Platform.MAC ? path.join(appOutDir, `${this.appInfo.productFilename}.app`, "Contents") : appOutDir)
return getFileMatchers(this.config, isResources ? "extraResources" : "extraFiles", this.projectDir, base, options)
return getFileMatchers(this.config, isResources ? "extraResources" : "extraFiles", base, options)
}

get electronDistExecutableName() {
Expand All @@ -154,13 +154,20 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>
return this.config.muonVersion == null ? "Electron" : "Brave"
}

createGetFileMatchersOptions(outDir: string, arch: Arch, customBuildOptions: PlatformSpecificBuildOptions): GetFileMatchersOptions {
return {
macroExpander: it => this.expandMacro(it, arch == null ? null : Arch[arch], {"/*": "{,/**/*}"}),
customBuildOptions,
globalOutDir: outDir,
defaultSrc: this.projectDir,
}
}

protected async doPack(outDir: string, appOutDir: string, platformName: ElectronPlatformName, arch: Arch, platformSpecificBuildOptions: DC, targets: Array<Target>) {
if (this.packagerOptions.prepackaged != null) {
return
}

const macroExpander = (it: string) => this.expandMacro(it, arch == null ? null : Arch[arch], {"/*": "{,/**/*}"})

const framework = this.info.framework
log.info({
platform: platformName,
Expand All @@ -187,11 +194,8 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>
}
}

const getFileMatchersOptions: GetFileMatchersOptions = {
macroExpander,
customBuildOptions: platformSpecificBuildOptions,
outDir,
}
const getFileMatchersOptions = this.createGetFileMatchersOptions(outDir, arch, platformSpecificBuildOptions)
const macroExpander = getFileMatchersOptions.macroExpander
const extraResourceMatchers = this.getExtraFileMatchers(true, appOutDir, getFileMatchersOptions)
computeParsedPatterns(extraResourceMatchers)
const extraFileMatchers = this.getExtraFileMatchers(false, appOutDir, getFileMatchersOptions)
Expand Down Expand Up @@ -292,10 +296,11 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>
taskManager.addTask(BluebirdPromise.each(_computeFileSets(mainMatchers), it => copyAppFiles(it, this.info, combinedTransformer)))
}
else {
const unpackPattern = getFileMatchers(config, "asarUnpack", appDir, defaultDestination, {
const unpackPattern = getFileMatchers(config, "asarUnpack", defaultDestination, {
macroExpander,
customBuildOptions: platformSpecificBuildOptions,
outDir: packContext.outDir,
globalOutDir: packContext.outDir,
defaultSrc: appDir,
})
const fileMatcher = unpackPattern == null ? null : unpackPattern[0]
taskManager.addTask(_computeFileSets(mainMatchers)
Expand Down
19 changes: 16 additions & 3 deletions packages/app-builder-lib/src/targets/ArchiveTarget.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Arch } from "builder-util"
import * as path from "path"
import { Platform, Target, TargetSpecificOptions } from "../core"
import { copyFiles, getFileMatchers } from "../fileMatcher"
import { PlatformPackager } from "../platformPackager"
import { archive, tar } from "./archive"

Expand Down Expand Up @@ -34,10 +35,22 @@ export class ArchiveTarget extends Target {
await tar(packager.compression, format, artifactPath, appOutDir, isMac, packager.info.tempDirManager)
}
else {
await archive(format, artifactPath, appOutDir, {

This comment has been minimized.

Copy link
@lutzroeder

lutzroeder Aug 18, 2018

Contributor

Before appOutDir was xxxx/mac/Foo.app and withoutDir: false
After dirToArchive is xxxx/mac and withoutDir: false

This leads to different the mac folder being included in the archive when before it wasn't (see #3254).

let withoutDir = !isMac
let dirToArchive = appOutDir
if (isMac) {
dirToArchive = path.dirname(appOutDir)
const fileMatchers = getFileMatchers(packager.config, "extraDistFiles", dirToArchive, packager.createGetFileMatchersOptions(this.outDir, arch, packager.platformSpecificBuildOptions))
if (fileMatchers != null) {
await copyFiles(fileMatchers, null, true)
withoutDir = true
}
}

const archiveOptions = {
compression: packager.compression,
withoutDir: !isMac,
})
withoutDir,
}
await archive(format, artifactPath, dirToArchive, archiveOptions)
}

packager.info.dispatchArtifactCreated({
Expand Down
4 changes: 1 addition & 3 deletions packages/app-builder-lib/src/targets/archive.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,6 @@ export interface ArchiveOptions {
*/
isArchiveHeaderCompressed?: boolean

listFile?: string

dictSize?: number
excluded?: Array<string> | null

Expand Down Expand Up @@ -151,7 +149,7 @@ export async function archive(format: string, outFile: string, dirToArchive: str
// remove file before - 7z doesn't overwrite file, but update
await unlinkIfExists(outFile)

args.push(outFile, options.listFile == null ? (options.withoutDir ? "." : path.basename(dirToArchive)) : `@${options.listFile}`)
args.push(outFile, options.withoutDir ? "." : path.basename(dirToArchive))
if (options.excluded != null) {
for (const mask of options.excluded) {
args.push(`-xr!${mask}`)
Expand Down
2 changes: 1 addition & 1 deletion packages/builder-util/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"chalk": "^2.4.1",
"debug": "^3.1.0",
"builder-util-runtime": "^0.0.0-semantic-release",
"source-map-support": "^0.5.6",
"source-map-support": "^0.5.8",
"7zip-bin": "~4.0.2",
"semver": "^5.5.0",
"lazy-val": "^1.0.3",
Expand Down
10 changes: 7 additions & 3 deletions packages/builder-util/src/fs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,11 @@ export function copyFile(src: string, dest: string, isEnsureDir = true) {
*
* ensureDir is not called, dest parent dir must exists
*/
export function copyOrLinkFile(src: string, dest: string, stats?: Stats | null, isUseHardLink = _isUseHardLink, exDevErrorHandler?: (() => boolean) | null): Promise<any> {
export function copyOrLinkFile(src: string, dest: string, stats?: Stats | null, isUseHardLink?: boolean, exDevErrorHandler?: (() => boolean) | null): Promise<any> {
if (isUseHardLink === undefined) {
isUseHardLink = _isUseHardLink
}

if (stats != null) {
const originalModeNumber = stats.mode
const mode = new Mode(stats)
Expand Down Expand Up @@ -223,7 +227,7 @@ function doCopyFile(src: string, dest: string, stats: Stats | null | undefined):
export class FileCopier {
isUseHardLink: boolean

constructor(private readonly isUseHardLinkFunction?: (file: string) => boolean, private readonly transformer?: FileTransformer | null) {
constructor(private readonly isUseHardLinkFunction?: ((file: string) => boolean) | null, private readonly transformer?: FileTransformer | null) {
if (isUseHardLinkFunction === USE_HARD_LINKS) {
this.isUseHardLink = true
}
Expand Down Expand Up @@ -274,7 +278,7 @@ export class FileCopier {
export interface CopyDirOptions {
filter?: Filter | null
transformer?: FileTransformer | null
isUseHardLink?: (file: string) => boolean
isUseHardLink?: ((file: string) => boolean) | null
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/electron-updater/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"fs-extra-p": "^4.6.1",
"js-yaml": "^3.12.0",
"semver": "^5.5.0",
"source-map-support": "^0.5.6",
"source-map-support": "^0.5.8",
"builder-util-runtime": "~0.0.0-semantic-release",
"electron-is-dev": "^0.3.0",
"lodash.isequal": "^4.5.0"
Expand Down
33 changes: 33 additions & 0 deletions test/out/mac/__snapshots__/macArchiveTest.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,39 @@ Object {
}
`;

exports[`extraDistFiles 1`] = `
Object {
"mac": Array [
Object {
"arch": "x64",
"file": "Test App ßW-1.1.0-mac.zip",
"safeArtifactName": "TestApp-1.1.0-mac.zip",
},
],
}
`;

exports[`extraDistFiles 2`] = `
Object {
"CFBundleDisplayName": "Test App ßW",
"CFBundleExecutable": "Test App ßW",
"CFBundleIconFile": "Test App ßW.icns",
"CFBundleIdentifier": "org.electron-builder.testApp",
"CFBundleInfoDictionaryVersion": "6.0",
"CFBundleName": "Test App ßW",
"CFBundlePackageType": "APPL",
"CFBundleShortVersionString": "1.1.0",
"DTSDKBuild": "14D125",
"DTSDKName": "macosx10.1010.10",
"LSApplicationCategoryType": "your.app.category.type",
"LSMinimumSystemVersion": "10.9.0",
"NSHighResolutionCapable": true,
"NSMainNibFile": "MainMenu",
"NSPrincipalClass": "AtomApplication",
"NSSupportsAutomaticGraphicsSwitching": true,
}
`;

exports[`invalid target 1`] = `"ERR_CONFIG_INVALID"`;

exports[`only zip 1`] = `
Expand Down
18 changes: 17 additions & 1 deletion test/src/mac/macArchiveTest.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { exec } from "builder-util"
import { parseXml } from "builder-util-runtime"
import { Platform } from "electron-builder"
import { readFile, symlink } from "fs-extra-p"
import { outputFile, readFile, symlink } from "fs-extra-p"
import * as path from "path"
import pathSorter from "path-sort"
import { assertThat } from "../helpers/fileAssert"
Expand Down Expand Up @@ -33,6 +33,22 @@ test.ifAll.ifMac("empty installLocation", app({
},
}))

test.ifAll.ifMac("extraDistFiles", app({
targets: Platform.MAC.createTarget("zip"),
config: {
mac: {
extraDistFiles: "extra.txt"
}
}
}, {
signed: false,
projectDirCreated: projectDir => {
return Promise.all([
outputFile(path.join(projectDir, "extra.txt"), "test"),
])
},
}))

test.ifAll.ifMac("pkg extended configuration", app({
targets: Platform.MAC.createTarget("pkg"),
config: {
Expand Down
Loading

0 comments on commit efb40da

Please sign in to comment.