Skip to content

Commit

Permalink
feat: support file transformers not only for asar
Browse files Browse the repository at this point in the history
package.json cleanup, electron-compile support
  • Loading branch information
develar committed Mar 22, 2017
1 parent 0b8bff4 commit 58061ec
Show file tree
Hide file tree
Showing 12 changed files with 115 additions and 64 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
"ajv": "^5.0.4-beta.0",
"ajv-keywords": "^2.0.1-beta.2",
"archiver": "^1.3.0",
"aws-sdk": "^2.29.0",
"aws-sdk": "^2.30.0",
"bluebird-lst": "^1.0.2",
"chalk": "^1.1.3",
"chromium-pickle-js": "^0.2.0",
Expand All @@ -40,7 +40,7 @@
"electron-download-tf": "4.0.0",
"electron-macos-sign": "~1.6.0",
"fs-extra-p": "^4.1.0",
"hosted-git-info": "^2.3.1",
"hosted-git-info": "^2.4.1",
"ini": "^1.3.4",
"is-ci": "^1.0.10",
"isbinaryfile": "^3.0.2",
Expand Down
21 changes: 17 additions & 4 deletions packages/electron-builder-util/src/fs.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import BluebirdPromise from "bluebird-lst"
import { access, createReadStream, createWriteStream, link, lstat, mkdirs, readdir, readlink, stat, Stats, symlink, unlink } from "fs-extra-p"
import { access, createReadStream, createWriteStream, link, lstat, mkdirs, readdir, readlink, stat, Stats, symlink, unlink, writeFile } from "fs-extra-p"
import isCi from "is-ci"
import * as path from "path"
import Mode from "stat-mode"
Expand All @@ -8,6 +8,7 @@ import { debug } from "./util"
export const MAX_FILE_REQUESTS = 8
export const CONCURRENCY = {concurrency: MAX_FILE_REQUESTS}

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

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

export class FileCopier {
constructor(private isUseHardLinkFunction?: (file: string) => boolean, private isUseHardLink = _isUseHardLink) {
private isUseHardLink = _isUseHardLink

constructor(private readonly isUseHardLinkFunction?: (file: string) => boolean, private readonly transformer?: FileTransformer) {
}

async copy(src: string, dest: string, stat: Stats | undefined) {
try {
if (this.transformer != null && stat != null && stat.isFile()) {
let data = this.transformer(src)
if (data != null) {
if (typeof (<any>data).then === "function") {
data = await data
}
await writeFile(dest, data)
return
}
}
await copyFile(src, dest, stat, (!this.isUseHardLink || this.isUseHardLinkFunction == null) ? this.isUseHardLink : this.isUseHardLinkFunction(dest))
}
catch (e) {
Expand All @@ -189,13 +202,13 @@ export class FileCopier {
* Empty directories is never created.
* Hard links is used if supported and allowed.
*/
export function copyDir(src: string, destination: string, filter?: Filter, isUseHardLink?: (file: string) => boolean): Promise<any> {
export function copyDir(src: string, destination: string, filter?: Filter, transformer?: FileTransformer, isUseHardLink?: (file: string) => boolean): Promise<any> {
if (debug.enabled) {
debug(`Copying ${src} to ${destination}${_isUseHardLink ? " using hard links" : ""}`)
}

const createdSourceDirs = new Set<string>()
const fileCopier = new FileCopier(isUseHardLink)
const fileCopier = new FileCopier(isUseHardLink, transformer)
const links: Array<Link> = []
return walk(src, filter, async(file, stat, parent) => {
if (!stat.isFile() && !stat.isSymbolicLink()) {
Expand Down
2 changes: 1 addition & 1 deletion packages/electron-builder/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
"electron-macos-sign": "~1.6.0",
"electron-publish": "0.0.0-semantic-release",
"fs-extra-p": "^4.1.0",
"hosted-git-info": "^2.3.1",
"hosted-git-info": "^2.4.1",
"is-ci": "^1.0.10",
"isbinaryfile": "^3.0.2",
"js-yaml": "^3.8.2",
Expand Down
5 changes: 2 additions & 3 deletions packages/electron-builder/src/asarUtil.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import BluebirdPromise from "bluebird-lst"
import { AsarOptions } from "electron-builder-core"
import { debug } from "electron-builder-util"
import { CONCURRENCY, FileCopier, Filter, MAX_FILE_REQUESTS, statOrNull, walk } from "electron-builder-util/out/fs"
import { CONCURRENCY, FileCopier, FileTransformer, Filter, MAX_FILE_REQUESTS, statOrNull, walk } from "electron-builder-util/out/fs"
import { log } from "electron-builder-util/out/log"
import { createReadStream, createWriteStream, ensureDir, readFile, readlink, stat, Stats, writeFile } from "fs-extra-p"
import * as path from "path"
import { AsarFilesystem, Node, readAsar } from "./asar"
import { FileTransformer } from "./fileTransformer"

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

const dirToCreateForUnpackedFiles = new Set<string>(unpackedDirs)

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)
const transformedFiles = transformer == null ? new Array(files.length) : await BluebirdPromise.map(files, it => metadata.get(it)!.isFile() ? transformer(it) : null, CONCURRENCY)
const filesToUnpack: Array<UnpackedFileTask> = []
const fileCopier = new FileCopier()
/* tslint:disable:rule1 prefer-const */
Expand Down
13 changes: 6 additions & 7 deletions packages/electron-builder/src/fileTransformer.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
import { debug } from "electron-builder-util"
import { deepAssign } from "electron-builder-util/out/deepAssign"
import { FileTransformer } from "electron-builder-util/out/fs"
import { log, warn } from "electron-builder-util/out/log"
import { readJson } from "fs-extra-p"
import mime from "mime"
import * as path from "path"
import { BuildInfo } from "./packagerApi"
import { PlatformPackager } from "./platformPackager"

export type FileTransformer = (path: string) => Promise<null | string | Buffer> | null | string | Buffer

function isElectronCompileUsed(info: BuildInfo): boolean {
const depList = [(<any>info.metadata).devDependencies, info.metadata.dependencies]
if (info.isTwoPackageJsonProjectLayoutUsed) {
Expand Down Expand Up @@ -56,6 +55,10 @@ async function createElectronCompileTransformer(projectDir: string, defaultTrans
if (defaultResult != null) {
return await defaultResult
}

if (file.includes("/node_modules/") || file.includes("/bower_components/")) {
return null
}

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

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

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

Expand Down
6 changes: 3 additions & 3 deletions packages/electron-builder/src/platformPackager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,18 +191,18 @@ export abstract class PlatformPackager<DC extends PlatformSpecificBuildOptions>

const defaultMatcher = this.createFileMatcher(appDir, resourcesPath, macroExpander, platformSpecificBuildOptions)
const filter = defaultMatcher.createFilter(ignoreFiles, rawFilter, excludePatterns.length > 0 ? excludePatterns : null)
const transformer = await createTransformer(this.projectDir, appDir, this)
let promise
if (this.info.isPrepackedAppAsar) {
promise = copyDir(appDir, path.join(resourcesPath), filter)
promise = copyDir(appDir, path.join(resourcesPath), filter, transformer)
}
else if (asarOptions == null) {
promise = copyDir(appDir, path.join(resourcesPath, "app"), filter)
promise = copyDir(appDir, path.join(resourcesPath, "app"), filter, transformer)
}
else {
const unpackPattern = this.getFileMatchers("asarUnpack", appDir, path.join(resourcesPath, "app"), false, macroExpander, platformSpecificBuildOptions)
const fileMatcher = unpackPattern == null ? null : unpackPattern[0]

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

Expand Down
2 changes: 1 addition & 1 deletion packages/electron-publisher-s3/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
],
"dependencies": {
"fs-extra-p": "^4.1.0",
"aws-sdk": "^2.29.0",
"aws-sdk": "^2.30.0",
"mime": "^1.3.4",
"electron-publish": "~0.0.0-semantic-release",
"electron-builder-util": "~0.0.0-semantic-release"
Expand Down
23 changes: 23 additions & 0 deletions test/out/__snapshots__/extraMetadataTest.js.snap
Original file line number Diff line number Diff line change
@@ -1,5 +1,28 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`extra metadata (no asar) 1`] = `
Object {
"linux": Array [],
}
`;

exports[`extra metadata (no asar) 2`] = `
Object {
"author": "Foo Bar <foo@example.com>",
"description": "Test Application (test quite \\" #378)",
"foo": Object {
"bar": 12,
"existingProp": 22,
},
"homepage": "http://foo.example.com",
"license": "MIT",
"name": "TestApp",
"private": true,
"productName": "Test App ßW",
"version": "1.1.0",
}
`;

exports[`extra metadata - override icon 1`] = `"Cannot find specified resource \\"dev.icns\\""`;

exports[`extra metadata - two 1`] = `
Expand Down
1 change: 1 addition & 0 deletions test/src/RepoSlugTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ function checkInfo(info: any) {
delete info.httpstemplate
delete info.filetemplate
delete info.docstemplate
delete info.opts
expect(info).toMatchSnapshot()
}

Expand Down
58 changes: 35 additions & 23 deletions test/src/extraMetadataTest.ts
Original file line number Diff line number Diff line change
@@ -1,35 +1,47 @@
import { DIR_TARGET, Platform } from "electron-builder"
import { readAsarJson } from "electron-builder/out/asar"
import { readJson } from "fs-extra-p"
import * as path from "path"
import { assertThat } from "./helpers/fileAssert"
import { app, appTwo, appTwoThrows, modifyPackageJson } from "./helpers/packTester"

test.ifDevOrLinuxCi("extra metadata", app({
targets: Platform.LINUX.createTarget(DIR_TARGET),
extraMetadata: {
foo: {
bar: 12,
function createExtraMetadataTest(asar: boolean) {
return app({
targets: Platform.LINUX.createTarget(DIR_TARGET),
extraMetadata: {
foo: {
bar: 12,
},
build: {
asar: asar,
linux: {
executableName: "new-name",
},
}
},
build: {
linux: {
executableName: "new-name"
}, {
projectDirCreated: projectDir => modifyPackageJson(projectDir, data => {
data.scripts = {}
data.devDependencies = {"foo": "boo"}
data.foo = {
bar: 42,
existingProp: 22,
}
}),
packed: async context => {
await assertThat(path.join(context.getContent(Platform.LINUX), "new-name")).isFile()
if (asar) {
expect(await readAsarJson(path.join(context.getResources(Platform.LINUX), "app.asar"), "package.json")).toMatchSnapshot()
}
else {
expect(await readJson(path.join(context.getResources(Platform.LINUX), "app", "package.json"))).toMatchSnapshot()
}
}
},
}, {
projectDirCreated: projectDir => modifyPackageJson(projectDir, data => {
data.scripts = {}
data.devDependencies = {"foo": "boo"}
data.foo = {
bar: 42,
existingProp: 22,
}
}),
packed: async context => {
await assertThat(path.join(context.getContent(Platform.LINUX), "new-name")).isFile()
expect(await readAsarJson(path.join(context.getResources(Platform.LINUX), "app.asar"), "package.json")).toMatchSnapshot()
}
}))
})
}

test.ifDevOrLinuxCi("extra metadata", createExtraMetadataTest(true))
test.ifDevOrLinuxCi("extra metadata (no asar)", createExtraMetadataTest(false))

test.ifDevOrLinuxCi("extra metadata - two", appTwo({
targets: Platform.LINUX.createTarget(DIR_TARGET),
Expand Down
2 changes: 1 addition & 1 deletion test/src/helpers/packTester.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export async function assertPack(fixtureName: string, packagerOptions: PackagerO
await copyDir(projectDir, dir, it => {
const basename = path.basename(it)
return basename !== OUT_DIR_NAME && basename !== "node_modules" && !basename.startsWith(".")
}, it => path.basename(it) != "package.json")
}, null, it => path.basename(it) != "package.json")
projectDir = dir

try {
Expand Down
Loading

0 comments on commit 58061ec

Please sign in to comment.