Skip to content

Commit 58061ec

Browse files
committed
feat: support file transformers not only for asar
package.json cleanup, electron-compile support
1 parent 0b8bff4 commit 58061ec

File tree

12 files changed

+115
-64
lines changed

12 files changed

+115
-64
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"ajv": "^5.0.4-beta.0",
3232
"ajv-keywords": "^2.0.1-beta.2",
3333
"archiver": "^1.3.0",
34-
"aws-sdk": "^2.29.0",
34+
"aws-sdk": "^2.30.0",
3535
"bluebird-lst": "^1.0.2",
3636
"chalk": "^1.1.3",
3737
"chromium-pickle-js": "^0.2.0",
@@ -40,7 +40,7 @@
4040
"electron-download-tf": "4.0.0",
4141
"electron-macos-sign": "~1.6.0",
4242
"fs-extra-p": "^4.1.0",
43-
"hosted-git-info": "^2.3.1",
43+
"hosted-git-info": "^2.4.1",
4444
"ini": "^1.3.4",
4545
"is-ci": "^1.0.10",
4646
"isbinaryfile": "^3.0.2",

packages/electron-builder-util/src/fs.ts

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import BluebirdPromise from "bluebird-lst"
2-
import { access, createReadStream, createWriteStream, link, lstat, mkdirs, readdir, readlink, stat, Stats, symlink, unlink } from "fs-extra-p"
2+
import { access, createReadStream, createWriteStream, link, lstat, mkdirs, readdir, readlink, stat, Stats, symlink, unlink, writeFile } from "fs-extra-p"
33
import isCi from "is-ci"
44
import * as path from "path"
55
import Mode from "stat-mode"
@@ -8,6 +8,7 @@ import { debug } from "./util"
88
export const MAX_FILE_REQUESTS = 8
99
export const CONCURRENCY = {concurrency: MAX_FILE_REQUESTS}
1010

11+
export type FileTransformer = (path: string) => Promise<null | string | Buffer> | null | string | Buffer
1112
export type Filter = (file: string, stat: Stats) => boolean
1213

1314
export function unlinkIfExists(file: string) {
@@ -160,11 +161,23 @@ export function copyFile(src: string, dest: string, stats?: Stats | null, isUseH
160161
}
161162

162163
export class FileCopier {
163-
constructor(private isUseHardLinkFunction?: (file: string) => boolean, private isUseHardLink = _isUseHardLink) {
164+
private isUseHardLink = _isUseHardLink
165+
166+
constructor(private readonly isUseHardLinkFunction?: (file: string) => boolean, private readonly transformer?: FileTransformer) {
164167
}
165168

166169
async copy(src: string, dest: string, stat: Stats | undefined) {
167170
try {
171+
if (this.transformer != null && stat != null && stat.isFile()) {
172+
let data = this.transformer(src)
173+
if (data != null) {
174+
if (typeof (<any>data).then === "function") {
175+
data = await data
176+
}
177+
await writeFile(dest, data)
178+
return
179+
}
180+
}
168181
await copyFile(src, dest, stat, (!this.isUseHardLink || this.isUseHardLinkFunction == null) ? this.isUseHardLink : this.isUseHardLinkFunction(dest))
169182
}
170183
catch (e) {
@@ -189,13 +202,13 @@ export class FileCopier {
189202
* Empty directories is never created.
190203
* Hard links is used if supported and allowed.
191204
*/
192-
export function copyDir(src: string, destination: string, filter?: Filter, isUseHardLink?: (file: string) => boolean): Promise<any> {
205+
export function copyDir(src: string, destination: string, filter?: Filter, transformer?: FileTransformer, isUseHardLink?: (file: string) => boolean): Promise<any> {
193206
if (debug.enabled) {
194207
debug(`Copying ${src} to ${destination}${_isUseHardLink ? " using hard links" : ""}`)
195208
}
196209

197210
const createdSourceDirs = new Set<string>()
198-
const fileCopier = new FileCopier(isUseHardLink)
211+
const fileCopier = new FileCopier(isUseHardLink, transformer)
199212
const links: Array<Link> = []
200213
return walk(src, filter, async(file, stat, parent) => {
201214
if (!stat.isFile() && !stat.isSymbolicLink()) {

packages/electron-builder/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@
5858
"electron-macos-sign": "~1.6.0",
5959
"electron-publish": "0.0.0-semantic-release",
6060
"fs-extra-p": "^4.1.0",
61-
"hosted-git-info": "^2.3.1",
61+
"hosted-git-info": "^2.4.1",
6262
"is-ci": "^1.0.10",
6363
"isbinaryfile": "^3.0.2",
6464
"js-yaml": "^3.8.2",

packages/electron-builder/src/asarUtil.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import BluebirdPromise from "bluebird-lst"
22
import { AsarOptions } from "electron-builder-core"
33
import { debug } from "electron-builder-util"
4-
import { CONCURRENCY, FileCopier, Filter, MAX_FILE_REQUESTS, statOrNull, walk } from "electron-builder-util/out/fs"
4+
import { CONCURRENCY, FileCopier, FileTransformer, Filter, MAX_FILE_REQUESTS, statOrNull, walk } from "electron-builder-util/out/fs"
55
import { log } from "electron-builder-util/out/log"
66
import { createReadStream, createWriteStream, ensureDir, readFile, readlink, stat, Stats, writeFile } from "fs-extra-p"
77
import * as path from "path"
88
import { AsarFilesystem, Node, readAsar } from "./asar"
9-
import { FileTransformer } from "./fileTransformer"
109

1110
const isBinaryFile: any = BluebirdPromise.promisify(require("isbinaryfile"))
1211
const pickle = require ("chromium-pickle-js")
@@ -160,7 +159,7 @@ export class AsarPackager {
160159

161160
const dirToCreateForUnpackedFiles = new Set<string>(unpackedDirs)
162161

163-
const transformedFiles = transformer == null ? new Array(files.length) : await BluebirdPromise.map(files, it => it.includes("/node_modules/") || it.includes("/bower_components/") || !metadata.get(it)!.isFile() ? null : transformer(it), CONCURRENCY)
162+
const transformedFiles = transformer == null ? new Array(files.length) : await BluebirdPromise.map(files, it => metadata.get(it)!.isFile() ? transformer(it) : null, CONCURRENCY)
164163
const filesToUnpack: Array<UnpackedFileTask> = []
165164
const fileCopier = new FileCopier()
166165
/* tslint:disable:rule1 prefer-const */

packages/electron-builder/src/fileTransformer.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,13 @@
11
import { debug } from "electron-builder-util"
22
import { deepAssign } from "electron-builder-util/out/deepAssign"
3+
import { FileTransformer } from "electron-builder-util/out/fs"
34
import { log, warn } from "electron-builder-util/out/log"
45
import { readJson } from "fs-extra-p"
56
import mime from "mime"
67
import * as path from "path"
78
import { BuildInfo } from "./packagerApi"
89
import { PlatformPackager } from "./platformPackager"
910

10-
export type FileTransformer = (path: string) => Promise<null | string | Buffer> | null | string | Buffer
11-
1211
function isElectronCompileUsed(info: BuildInfo): boolean {
1312
const depList = [(<any>info.metadata).devDependencies, info.metadata.dependencies]
1413
if (info.isTwoPackageJsonProjectLayoutUsed) {
@@ -56,6 +55,10 @@ async function createElectronCompileTransformer(projectDir: string, defaultTrans
5655
if (defaultResult != null) {
5756
return await defaultResult
5857
}
58+
59+
if (file.includes("/node_modules/") || file.includes("/bower_components/")) {
60+
return null
61+
}
5962

6063
const hashInfo = await compilerHost.fileChangeCache.getHashForPath(file)
6164

@@ -74,11 +77,7 @@ async function createElectronCompileTransformer(projectDir: string, defaultTrans
7477

7578
const cache = compilerHost.cachesForCompilers.get(compiler)
7679
const result = await cache.getOrFetch(file, (file: string, hashInfo: any) => compilerHost.compileUncached(file, hashInfo, compiler))
77-
const code = result.code
78-
if (type === "application/javascript" && code != null && (code.includes("require('electron-compile')") || code.includes('require("electron-compile")'))) {
79-
warn("electron-compile should be not used in the production code")
80-
}
81-
return code || result.binaryData
80+
return result.code || result.binaryData
8281
}
8382
}
8483

packages/electron-builder/src/platformPackager.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -191,18 +191,18 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>
191191

192192
const defaultMatcher = this.createFileMatcher(appDir, resourcesPath, macroExpander, platformSpecificBuildOptions)
193193
const filter = defaultMatcher.createFilter(ignoreFiles, rawFilter, excludePatterns.length > 0 ? excludePatterns : null)
194+
const transformer = await createTransformer(this.projectDir, appDir, this)
194195
let promise
195196
if (this.info.isPrepackedAppAsar) {
196-
promise = copyDir(appDir, path.join(resourcesPath), filter)
197+
promise = copyDir(appDir, path.join(resourcesPath), filter, transformer)
197198
}
198199
else if (asarOptions == null) {
199-
promise = copyDir(appDir, path.join(resourcesPath, "app"), filter)
200+
promise = copyDir(appDir, path.join(resourcesPath, "app"), filter, transformer)
200201
}
201202
else {
202203
const unpackPattern = this.getFileMatchers("asarUnpack", appDir, path.join(resourcesPath, "app"), false, macroExpander, platformSpecificBuildOptions)
203204
const fileMatcher = unpackPattern == null ? null : unpackPattern[0]
204205

205-
let transformer = await createTransformer(this.projectDir, appDir, this)
206206
promise = new AsarPackager(appDir, resourcesPath, asarOptions, fileMatcher == null ? null : fileMatcher.createFilter()).pack(filter, transformer)
207207
}
208208

packages/electron-publisher-s3/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
],
1313
"dependencies": {
1414
"fs-extra-p": "^4.1.0",
15-
"aws-sdk": "^2.29.0",
15+
"aws-sdk": "^2.30.0",
1616
"mime": "^1.3.4",
1717
"electron-publish": "~0.0.0-semantic-release",
1818
"electron-builder-util": "~0.0.0-semantic-release"

test/out/__snapshots__/extraMetadataTest.js.snap

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,28 @@
11
// Jest Snapshot v1, https://goo.gl/fbAQLP
22

3+
exports[`extra metadata (no asar) 1`] = `
4+
Object {
5+
"linux": Array [],
6+
}
7+
`;
8+
9+
exports[`extra metadata (no asar) 2`] = `
10+
Object {
11+
"author": "Foo Bar <foo@example.com>",
12+
"description": "Test Application (test quite \\" #378)",
13+
"foo": Object {
14+
"bar": 12,
15+
"existingProp": 22,
16+
},
17+
"homepage": "http://foo.example.com",
18+
"license": "MIT",
19+
"name": "TestApp",
20+
"private": true,
21+
"productName": "Test App ßW",
22+
"version": "1.1.0",
23+
}
24+
`;
25+
326
exports[`extra metadata - override icon 1`] = `"Cannot find specified resource \\"dev.icns\\""`;
427

528
exports[`extra metadata - two 1`] = `

test/src/RepoSlugTest.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ function checkInfo(info: any) {
66
delete info.httpstemplate
77
delete info.filetemplate
88
delete info.docstemplate
9+
delete info.opts
910
expect(info).toMatchSnapshot()
1011
}
1112

test/src/extraMetadataTest.ts

Lines changed: 35 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,47 @@
11
import { DIR_TARGET, Platform } from "electron-builder"
22
import { readAsarJson } from "electron-builder/out/asar"
3+
import { readJson } from "fs-extra-p"
34
import * as path from "path"
45
import { assertThat } from "./helpers/fileAssert"
56
import { app, appTwo, appTwoThrows, modifyPackageJson } from "./helpers/packTester"
67

7-
test.ifDevOrLinuxCi("extra metadata", app({
8-
targets: Platform.LINUX.createTarget(DIR_TARGET),
9-
extraMetadata: {
10-
foo: {
11-
bar: 12,
8+
function createExtraMetadataTest(asar: boolean) {
9+
return app({
10+
targets: Platform.LINUX.createTarget(DIR_TARGET),
11+
extraMetadata: {
12+
foo: {
13+
bar: 12,
14+
},
15+
build: {
16+
asar: asar,
17+
linux: {
18+
executableName: "new-name",
19+
},
20+
}
1221
},
13-
build: {
14-
linux: {
15-
executableName: "new-name"
22+
}, {
23+
projectDirCreated: projectDir => modifyPackageJson(projectDir, data => {
24+
data.scripts = {}
25+
data.devDependencies = {"foo": "boo"}
26+
data.foo = {
27+
bar: 42,
28+
existingProp: 22,
29+
}
30+
}),
31+
packed: async context => {
32+
await assertThat(path.join(context.getContent(Platform.LINUX), "new-name")).isFile()
33+
if (asar) {
34+
expect(await readAsarJson(path.join(context.getResources(Platform.LINUX), "app.asar"), "package.json")).toMatchSnapshot()
35+
}
36+
else {
37+
expect(await readJson(path.join(context.getResources(Platform.LINUX), "app", "package.json"))).toMatchSnapshot()
1638
}
1739
}
18-
},
19-
}, {
20-
projectDirCreated: projectDir => modifyPackageJson(projectDir, data => {
21-
data.scripts = {}
22-
data.devDependencies = {"foo": "boo"}
23-
data.foo = {
24-
bar: 42,
25-
existingProp: 22,
26-
}
27-
}),
28-
packed: async context => {
29-
await assertThat(path.join(context.getContent(Platform.LINUX), "new-name")).isFile()
30-
expect(await readAsarJson(path.join(context.getResources(Platform.LINUX), "app.asar"), "package.json")).toMatchSnapshot()
31-
}
32-
}))
40+
})
41+
}
42+
43+
test.ifDevOrLinuxCi("extra metadata", createExtraMetadataTest(true))
44+
test.ifDevOrLinuxCi("extra metadata (no asar)", createExtraMetadataTest(false))
3345

3446
test.ifDevOrLinuxCi("extra metadata - two", appTwo({
3547
targets: Platform.LINUX.createTarget(DIR_TARGET),

test/src/helpers/packTester.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ export async function assertPack(fixtureName: string, packagerOptions: PackagerO
9292
await copyDir(projectDir, dir, it => {
9393
const basename = path.basename(it)
9494
return basename !== OUT_DIR_NAME && basename !== "node_modules" && !basename.startsWith(".")
95-
}, it => path.basename(it) != "package.json")
95+
}, null, it => path.basename(it) != "package.json")
9696
projectDir = dir
9797

9898
try {

0 commit comments

Comments
 (0)