From 58061eca10d69205d223caa8fac448e7a78b4cc7 Mon Sep 17 00:00:00 2001 From: develar Date: Wed, 22 Mar 2017 08:43:51 +0100 Subject: [PATCH] feat: support file transformers not only for asar package.json cleanup, electron-compile support --- package.json | 4 +- packages/electron-builder-util/src/fs.ts | 21 +++++-- packages/electron-builder/package.json | 2 +- packages/electron-builder/src/asarUtil.ts | 5 +- .../electron-builder/src/fileTransformer.ts | 13 ++--- .../electron-builder/src/platformPackager.ts | 6 +- packages/electron-publisher-s3/package.json | 2 +- .../__snapshots__/extraMetadataTest.js.snap | 23 ++++++++ test/src/RepoSlugTest.ts | 1 + test/src/extraMetadataTest.ts | 58 +++++++++++-------- test/src/helpers/packTester.ts | 2 +- yarn.lock | 42 ++++++++------ 12 files changed, 115 insertions(+), 64 deletions(-) diff --git a/package.json b/package.json index e63329049f5..7c23bced9eb 100644 --- a/package.json +++ b/package.json @@ -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", @@ -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", diff --git a/packages/electron-builder-util/src/fs.ts b/packages/electron-builder-util/src/fs.ts index 3a74d691633..93332aa9a45 100644 --- a/packages/electron-builder-util/src/fs.ts +++ b/packages/electron-builder-util/src/fs.ts @@ -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" @@ -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 export type Filter = (file: string, stat: Stats) => boolean export function unlinkIfExists(file: string) { @@ -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 (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) { @@ -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 { +export function copyDir(src: string, destination: string, filter?: Filter, transformer?: FileTransformer, isUseHardLink?: (file: string) => boolean): Promise { if (debug.enabled) { debug(`Copying ${src} to ${destination}${_isUseHardLink ? " using hard links" : ""}`) } const createdSourceDirs = new Set() - const fileCopier = new FileCopier(isUseHardLink) + const fileCopier = new FileCopier(isUseHardLink, transformer) const links: Array = [] return walk(src, filter, async(file, stat, parent) => { if (!stat.isFile() && !stat.isSymbolicLink()) { diff --git a/packages/electron-builder/package.json b/packages/electron-builder/package.json index 8329baca273..c4d1329304c 100644 --- a/packages/electron-builder/package.json +++ b/packages/electron-builder/package.json @@ -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", diff --git a/packages/electron-builder/src/asarUtil.ts b/packages/electron-builder/src/asarUtil.ts index 3d299c4a8a4..e8328492006 100644 --- a/packages/electron-builder/src/asarUtil.ts +++ b/packages/electron-builder/src/asarUtil.ts @@ -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") @@ -160,7 +159,7 @@ export class AsarPackager { const dirToCreateForUnpackedFiles = new Set(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 = [] const fileCopier = new FileCopier() /* tslint:disable:rule1 prefer-const */ diff --git a/packages/electron-builder/src/fileTransformer.ts b/packages/electron-builder/src/fileTransformer.ts index 379a044ce7d..691c1577242 100644 --- a/packages/electron-builder/src/fileTransformer.ts +++ b/packages/electron-builder/src/fileTransformer.ts @@ -1,5 +1,6 @@ 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" @@ -7,8 +8,6 @@ import * as path from "path" import { BuildInfo } from "./packagerApi" import { PlatformPackager } from "./platformPackager" -export type FileTransformer = (path: string) => Promise | null | string | Buffer - function isElectronCompileUsed(info: BuildInfo): boolean { const depList = [(info.metadata).devDependencies, info.metadata.dependencies] if (info.isTwoPackageJsonProjectLayoutUsed) { @@ -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) @@ -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 } } diff --git a/packages/electron-builder/src/platformPackager.ts b/packages/electron-builder/src/platformPackager.ts index d90b0d6ed07..8cc63712220 100644 --- a/packages/electron-builder/src/platformPackager.ts +++ b/packages/electron-builder/src/platformPackager.ts @@ -191,18 +191,18 @@ export abstract class PlatformPackager 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) } diff --git a/packages/electron-publisher-s3/package.json b/packages/electron-publisher-s3/package.json index 41aefde125c..9de0f247027 100644 --- a/packages/electron-publisher-s3/package.json +++ b/packages/electron-publisher-s3/package.json @@ -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" diff --git a/test/out/__snapshots__/extraMetadataTest.js.snap b/test/out/__snapshots__/extraMetadataTest.js.snap index cab50c80ed3..f86e390ebc7 100644 --- a/test/out/__snapshots__/extraMetadataTest.js.snap +++ b/test/out/__snapshots__/extraMetadataTest.js.snap @@ -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 ", + "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`] = ` diff --git a/test/src/RepoSlugTest.ts b/test/src/RepoSlugTest.ts index abf6ed2c885..914b3fb7bc8 100644 --- a/test/src/RepoSlugTest.ts +++ b/test/src/RepoSlugTest.ts @@ -6,6 +6,7 @@ function checkInfo(info: any) { delete info.httpstemplate delete info.filetemplate delete info.docstemplate + delete info.opts expect(info).toMatchSnapshot() } diff --git a/test/src/extraMetadataTest.ts b/test/src/extraMetadataTest.ts index f439fb2b5ac..aa32b562930 100644 --- a/test/src/extraMetadataTest.ts +++ b/test/src/extraMetadataTest.ts @@ -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), diff --git a/test/src/helpers/packTester.ts b/test/src/helpers/packTester.ts index 2ebe1bd1fe9..e2244b2f886 100755 --- a/test/src/helpers/packTester.ts +++ b/test/src/helpers/packTester.ts @@ -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 { diff --git a/yarn.lock b/yarn.lock index df5a0d4653d..413d0cf2f08 100644 --- a/yarn.lock +++ b/yarn.lock @@ -162,7 +162,7 @@ app-usage-stats@^0.5.0: test-value "^2.1.0" usage-stats "^0.9.0" -append-transform@^0.4.3: +append-transform@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" dependencies: @@ -271,9 +271,9 @@ asynckit@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" -aws-sdk@^2.29.0: - version "2.29.0" - resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.29.0.tgz#aebf0c90effa4abea426dd59187f51b5ae121684" +aws-sdk@^2.30.0: + version "2.30.0" + resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.30.0.tgz#9d6d3b665e18fb7b9b9481092ea4d1ee1bfeed63" dependencies: buffer "4.9.1" crypto-browserify "1.0.9" @@ -1016,8 +1016,8 @@ diff@^3.0.0, diff@^3.0.1: resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" dmd@^3.0.0: - version "3.0.2" - resolved "https://registry.yarnpkg.com/dmd/-/dmd-3.0.2.tgz#9dbc1b24142f0ceaee8b835a112275d80f975b92" + version "3.0.3" + resolved "https://registry.yarnpkg.com/dmd/-/dmd-3.0.3.tgz#3c91f7ba895d379a21c187386d2427e52909a070" dependencies: array-back "^1.0.4" cache-point "^0.4.0" @@ -1451,9 +1451,9 @@ home-path@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/home-path/-/home-path-1.0.3.tgz#9ece59fec3f032e6d10b5434fee264df4c2de32f" -hosted-git-info@^2.1.4, hosted-git-info@^2.3.1: - version "2.3.1" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.3.1.tgz#ac439421605f0beb0ea1349de7d8bb28e50be1dd" +hosted-git-info@^2.1.4, hosted-git-info@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.1.tgz#4b0445e41c004a8bd1337773a4ff790ca40318c8" html-encoding-sniffer@^1.0.1: version "1.0.1" @@ -1641,13 +1641,13 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" istanbul-api@^1.1.0-alpha.1: - version "1.1.4" - resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.1.4.tgz#e70d288cb63a838ab768e562894562d46ff23063" + version "1.1.5" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.1.5.tgz#3ddb38f11183196da8f6e5c90c938cd3917b16a7" dependencies: async "^2.1.4" fileset "^2.0.2" istanbul-lib-coverage "^1.0.0" - istanbul-lib-hook "^1.0.3" + istanbul-lib-hook "^1.0.4" istanbul-lib-instrument "^1.6.1" istanbul-lib-report "^1.0.0-alpha.3" istanbul-lib-source-maps "^1.1.0" @@ -1660,11 +1660,11 @@ istanbul-lib-coverage@^1.0.0, istanbul-lib-coverage@^1.0.0-alpha, istanbul-lib-c version "1.0.1" resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.0.1.tgz#f263efb519c051c5f1f3343034fc40e7b43ff212" -istanbul-lib-hook@^1.0.3: - version "1.0.3" - resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.3.tgz#3e804afdef74e386bb766f520b3f83a3a5d99085" +istanbul-lib-hook@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.0.4.tgz#1919debbc195807880041971caf9c7e2be2144d6" dependencies: - append-transform "^0.4.3" + append-transform "^0.4.0" istanbul-lib-instrument@^1.1.1, istanbul-lib-instrument@^1.4.2, istanbul-lib-instrument@^1.6.1: version "1.6.1" @@ -2255,7 +2255,7 @@ mime@^1.3.4: dependencies: brace-expansion "^1.0.0" -minimist@0.0.8, minimist@~0.0.1: +minimist@0.0.8: version "0.0.8" resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" @@ -2263,6 +2263,10 @@ minimist@^1.1.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.1: version "0.5.1" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" @@ -2591,8 +2595,8 @@ punycode@^1.4.1: resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" q@^1.1.2: - version "1.4.1" - resolved "https://registry.yarnpkg.com/q/-/q-1.4.1.tgz#55705bcd93c5f3673530c2c2cbc0c2b3addc286e" + version "1.5.0" + resolved "https://registry.yarnpkg.com/q/-/q-1.5.0.tgz#dd01bac9d06d30e6f219aecb8253ee9ebdc308f1" qs@~6.4.0: version "6.4.0"