diff --git a/package.json b/package.json index 376e4785920..3aedf91f2ea 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,6 @@ ], "bin": { "build": "./out/build-cli.js", - "cleanup": "./out/cleanup.js", "install-app-deps": "./out/install-app-deps.js", "node-gyp-rebuild": "./out/node-gyp-rebuild.js" }, @@ -102,13 +101,12 @@ "@types/source-map-support": "^0.2.28", "babel-plugin-array-includes": "^2.0.3", "babel-plugin-transform-async-to-module-method": "^6.16.0", - "babel-plugin-transform-es2015-destructuring": "^6.18.0", + "babel-plugin-transform-es2015-destructuring": "^6.19.0", "babel-plugin-transform-es2015-parameters": "^6.18.0", "babel-plugin-transform-es2015-spread": "^6.8.0", "babel-plugin-transform-inline-imports-commonjs": "^1.2.0", - "babel-register": "^6.18.0", "decompress-zip": "^0.3.0", - "depcheck": "^0.6.4", + "depcheck": "^0.6.5", "diff": "^3.0.1", "husky": "^0.11.9", "jest-cli": "^17.0.3", diff --git a/src/cleanup.ts b/src/cleanup.ts deleted file mode 100644 index 1ed6c3b0dfe..00000000000 --- a/src/cleanup.ts +++ /dev/null @@ -1,59 +0,0 @@ -#! /usr/bin/env node - -import { readdir, lstat, Stats, remove, readFile } from "fs-extra-p" -import BluebirdPromise from "bluebird-lst-c" -import * as path from "path" -import { getCacheDirectory } from "./util/util" - -async function main() { - const dir = path.join(getCacheDirectory(), "fpm") - let items: string[] | null = null - try { - items = await readdir(dir) - } - catch (e) { - if (e.code !== "ENOENT") { - throw e - } - return - } - - await BluebirdPromise.map(items, <(item: string) => BluebirdPromise> (async (it) => { - let stat: Stats | null = null - const itemPath = path.join(dir, it) - try { - stat = await lstat(itemPath) - } - catch (e) { - if (e.code !== "ENOENT") { - throw e - } - return - } - - if (!stat!.isDirectory() || !(await isRecentlyUsed(itemPath))) { - console.log(`remove unused ${itemPath}`) - await remove(itemPath) - } - })) - - await BluebirdPromise.map(items, remove) -} - -async function isRecentlyUsed(dir: string) { - try { - const lastUsed = parseInt(await readFile(path.join(dir, ".lastUsed"), "utf8"), 10) - if (!isNaN(lastUsed) && (Date.now() - lastUsed) < (3600000 * 2)) { - return true - } - } - catch (e) { - if (e.code !== "ENOENT") { - throw e - } - } - - return false -} - -main() \ No newline at end of file diff --git a/src/packager/dirPackager.ts b/src/packager/dirPackager.ts index 71b599b60df..05e6e138a36 100644 --- a/src/packager/dirPackager.ts +++ b/src/packager/dirPackager.ts @@ -27,7 +27,7 @@ function subOptionWarning (properties: any, optionName: any, parameter: any, val properties[parameter] = value } -export async function pack(packager: PlatformPackager, out: string, platform: string, arch: string, electronVersion: string, initializeApp: () => Promise) { +export async function unpackElectron(packager: PlatformPackager, out: string, platform: string, arch: string, electronVersion: string) { const electronDist = packager.devMetadata.build.electronDist if (electronDist == null) { const zipPath = (await BluebirdPromise.all([ @@ -50,11 +50,4 @@ export async function pack(packager: PlatformPackager, out: string, platfor chmod(path.join(out, "resources"), "0755") ]) } - - if (platform === "darwin" || platform === "mas") { - await(require("./mac")).createApp(packager, out, initializeApp) - } - else { - await initializeApp() - } } \ No newline at end of file diff --git a/src/packager/mac.ts b/src/packager/mac.ts index 5c389598b46..47c5b82d40e 100644 --- a/src/packager/mac.ts +++ b/src/packager/mac.ts @@ -24,7 +24,7 @@ function filterCFBundleIdentifier(identifier: string) { return identifier.replace(/ /g, "-").replace(/[^a-zA-Z0-9.-]/g, "") } -export async function createApp(packager: PlatformPackager, appOutDir: string, initializeApp: () => Promise) { +export async function createApp(packager: PlatformPackager, appOutDir: string) { const appInfo = packager.appInfo const appFilename = appInfo.productFilename @@ -37,12 +37,7 @@ export async function createApp(packager: PlatformPackager, appOutDir: stri const helperNPPlistFilename = path.join(frameworksPath, "Electron Helper NP.app", "Contents", "Info.plist") const buildMetadata = packager.devMetadata.build! - - const result = await BluebirdPromise.all([ - initializeApp(), - BluebirdPromise.map([appPlistFilename, helperPlistFilename, helperEHPlistFilename, helperNPPlistFilename, (buildMetadata)["extend-info"]], it => it == null ? it : readFile(it, "utf8")) - ]) - const fileContents: Array = result[1]! + const fileContents: Array = await BluebirdPromise.map([appPlistFilename, helperPlistFilename, helperEHPlistFilename, helperNPPlistFilename, (buildMetadata)["extend-info"]], it => it == null ? it : readFile(it, "utf8")) const appPlist = parsePlist(fileContents[0]) const helperPlist = parsePlist(fileContents[1]) const helperEHPlist = parsePlist(fileContents[2]) diff --git a/src/platformPackager.ts b/src/platformPackager.ts index 1e96aef01ca..9585e907050 100644 --- a/src/platformPackager.ts +++ b/src/platformPackager.ts @@ -2,7 +2,7 @@ import { AppMetadata, DevMetadata, Platform, PlatformSpecificBuildOptions, Arch, import EventEmitter = NodeJS.EventEmitter import BluebirdPromise from "bluebird-lst-c" import * as path from "path" -import { readdir, remove } from "fs-extra-p" +import { readdir, remove, rename } from "fs-extra-p" import { statOrNull, use, unlinkIfExists, isEmptyOrSpaces, asArray, debug } from "./util/util" import { Packager } from "./packager" import { AsarOptions } from "asar-electron-builder" @@ -11,7 +11,7 @@ import { checkFileInArchive, createAsarArchive } from "./asarUtil" import { warn, log } from "./util/log" import { AppInfo } from "./appInfo" import { copyFiltered } from "./util/filter" -import { pack } from "./packager/dirPackager" +import { unpackElectron } from "./packager/dirPackager" import { TmpDir } from "./util/tmp" import { FileMatchOptions, FileMatcher, FilePattern, deprecatedUserIgnoreFilter } from "./fileMatcher" import { BuildOptions } from "./builder" @@ -189,81 +189,89 @@ export abstract class PlatformPackager const resourcesPath = this.platform === Platform.MAC ? path.join(appOutDir, "Electron.app", "Contents", "Resources") : path.join(appOutDir, "resources") log(`Packaging for ${platformName} ${Arch[arch]} using electron ${this.info.electronVersion} to ${path.relative(this.projectDir, appOutDir)}`) - await pack(this, appOutDir, platformName, Arch[arch], this.info.electronVersion, async () => { - const appDir = this.info.appDir - const ignoreFiles = new Set([path.resolve(appDir, outDir), path.resolve(appDir, this.buildResourcesDir)]) - // prune dev or not listed dependencies - await dependencies(appDir, true, ignoreFiles) - - if (debug.enabled) { - const nodeModulesDir = path.join(appDir, "node_modules") - debug(`Pruned dev or extraneous dependencies: ${Array.from(ignoreFiles).slice(2).map(it => path.relative(nodeModulesDir, it)).join(", ")}`) - } - const patterns = this.getFileMatchers("files", appDir, path.join(resourcesPath, "app"), false, fileMatchOptions, platformSpecificBuildOptions) - let defaultMatcher = patterns == null ? new FileMatcher(appDir, path.join(resourcesPath, "app"), fileMatchOptions) : patterns[0] - if (defaultMatcher.isEmpty()) { - defaultMatcher.addPattern("**/*") + const appDir = this.info.appDir + const ignoreFiles = new Set([path.resolve(appDir, outDir), path.resolve(appDir, this.buildResourcesDir)]) + // prune dev or not listed dependencies + await BluebirdPromise.all([ + dependencies(appDir, true, ignoreFiles), + unpackElectron(this, appOutDir, platformName, Arch[arch], this.info.electronVersion), + ]) + + if (debug.enabled) { + const nodeModulesDir = path.join(appDir, "node_modules") + debug(`Pruned dev or extraneous dependencies: ${Array.from(ignoreFiles).slice(2).map(it => path.relative(nodeModulesDir, it)).join(", ")}`) + } + + const patterns = this.getFileMatchers("files", appDir, path.join(resourcesPath, "app"), false, fileMatchOptions, platformSpecificBuildOptions) + let defaultMatcher = patterns == null ? new FileMatcher(appDir, path.join(resourcesPath, "app"), fileMatchOptions) : patterns[0] + if (defaultMatcher.isEmpty()) { + defaultMatcher.addPattern("**/*") + } + else { + defaultMatcher.addPattern("package.json") + } + defaultMatcher.addPattern("!**/node_modules/*/{CHANGELOG.md,ChangeLog,changelog.md,README.md,README,readme.md,readme,test,__tests__,tests,powered-test,example,examples,*.d.ts}") + defaultMatcher.addPattern("!**/node_modules/.bin") + defaultMatcher.addPattern("!**/*.{o,hprof,orig,pyc,pyo,rbc,swp}") + defaultMatcher.addPattern("!**/._*") + defaultMatcher.addPattern("!.idea") + defaultMatcher.addPattern("!*.iml") + //noinspection SpellCheckingInspection + defaultMatcher.addPattern("!**/{.DS_Store,.git,.hg,.svn,CVS,RCS,SCCS,__pycache__,thumbs.db,.gitignore,.gitattributes,.editorconfig,.flowconfig,.yarn-metadata.json,.idea,appveyor.yml,.travis.yml,circle.yml,npm-debug.log,.nyc_output,yarn.lock,.yarn-integrity}") + + let rawFilter: any = null + const deprecatedIgnore = (this.devMetadata.build).ignore + if (deprecatedIgnore != null) { + if (typeof deprecatedIgnore === "function") { + warn(`"ignore" is specified as function, may be new "files" option will be suit your needs? Please see https://github.com/electron-userland/electron-builder/wiki/Options#BuildMetadata-files`) } else { - defaultMatcher.addPattern("package.json") - } - defaultMatcher.addPattern("!**/node_modules/*/{CHANGELOG.md,ChangeLog,changelog.md,README.md,README,readme.md,readme,test,__tests__,tests,powered-test,example,examples,*.d.ts}") - defaultMatcher.addPattern("!**/node_modules/.bin") - defaultMatcher.addPattern("!**/*.{o,hprof,orig,pyc,pyo,rbc,swp}") - defaultMatcher.addPattern("!**/._*") - defaultMatcher.addPattern("!.idea") - defaultMatcher.addPattern("!*.iml") - //noinspection SpellCheckingInspection - defaultMatcher.addPattern("!**/{.DS_Store,.git,.hg,.svn,CVS,RCS,SCCS,__pycache__,thumbs.db,.gitignore,.gitattributes,.editorconfig,.flowconfig,.yarn-metadata.json,.idea,appveyor.yml,.travis.yml,circle.yml,npm-debug.log,.nyc_output,yarn.lock,.yarn-integrity}") - - let rawFilter: any = null - const deprecatedIgnore = (this.devMetadata.build).ignore - if (deprecatedIgnore != null) { - if (typeof deprecatedIgnore === "function") { - warn(`"ignore" is specified as function, may be new "files" option will be suit your needs? Please see https://github.com/electron-userland/electron-builder/wiki/Options#BuildMetadata-files`) - } - else { - warn(`"ignore" is deprecated, please use "files", see https://github.com/electron-userland/electron-builder/wiki/Options#BuildMetadata-files`) - } - rawFilter = deprecatedUserIgnoreFilter(deprecatedIgnore, appDir) + warn(`"ignore" is deprecated, please use "files", see https://github.com/electron-userland/electron-builder/wiki/Options#BuildMetadata-files`) } + rawFilter = deprecatedUserIgnoreFilter(deprecatedIgnore, appDir) + } - let excludePatterns: Array = [] - if (extraResourceMatchers != null) { - for (let i = 0; i < extraResourceMatchers.length; i++) { - const patterns = extraResourceMatchers[i].getParsedPatterns(this.info.projectDir) - excludePatterns = excludePatterns.concat(patterns) - } + let excludePatterns: Array = [] + if (extraResourceMatchers != null) { + for (let i = 0; i < extraResourceMatchers.length; i++) { + const patterns = extraResourceMatchers[i].getParsedPatterns(this.info.projectDir) + excludePatterns = excludePatterns.concat(patterns) } - if (extraFileMatchers != null) { - for (let i = 0; i < extraFileMatchers.length; i++) { - const patterns = extraFileMatchers[i].getParsedPatterns(this.info.projectDir) - excludePatterns = excludePatterns.concat(patterns) - } + } + if (extraFileMatchers != null) { + for (let i = 0; i < extraFileMatchers.length; i++) { + const patterns = extraFileMatchers[i].getParsedPatterns(this.info.projectDir) + excludePatterns = excludePatterns.concat(patterns) } + } - const filter = defaultMatcher.createFilter(ignoreFiles, rawFilter, excludePatterns.length ? excludePatterns : null) - let promise - if (asarOptions == null) { - promise = copyFiltered(appDir, path.join(resourcesPath, "app"), filter, this.info.devMetadata.build.dereference || this.platform === Platform.WINDOWS) - } - else { - const unpackPattern = this.getFileMatchers("asarUnpack", appDir, path.join(resourcesPath, "app"), false, fileMatchOptions, platformSpecificBuildOptions) - const fileMatcher = unpackPattern == null ? null : unpackPattern[0] - //noinspection ES6MissingAwait - promise = createAsarArchive(appDir, resourcesPath, asarOptions, filter, fileMatcher == null ? null : fileMatcher.createFilter()) - } + const filter = defaultMatcher.createFilter(ignoreFiles, rawFilter, excludePatterns.length ? excludePatterns : null) + let promise + if (asarOptions == null) { + promise = copyFiltered(appDir, path.join(resourcesPath, "app"), filter, this.info.devMetadata.build.dereference || this.platform === Platform.WINDOWS) + } + else { + const unpackPattern = this.getFileMatchers("asarUnpack", appDir, path.join(resourcesPath, "app"), false, fileMatchOptions, platformSpecificBuildOptions) + const fileMatcher = unpackPattern == null ? null : unpackPattern[0] + promise = createAsarArchive(appDir, resourcesPath, asarOptions, filter, fileMatcher == null ? null : fileMatcher.createFilter()) + } - const promises = [promise, unlinkIfExists(path.join(resourcesPath, "default_app.asar")), unlinkIfExists(path.join(appOutDir, "version"))] - if (this.info.electronVersion != null && this.info.electronVersion[0] === "0") { - // electron release >= 0.37.4 - the default_app/ folder is a default_app.asar file - promises.push(remove(path.join(resourcesPath, "default_app"))) - } + //noinspection ES6MissingAwait + const promises = [promise, unlinkIfExists(path.join(resourcesPath, "default_app.asar")), unlinkIfExists(path.join(appOutDir, "version")), this.postInitApp(appOutDir)] + if (this.platform !== Platform.MAC) { + promises.push(rename(path.join(appOutDir, "LICENSE"), path.join(appOutDir, "LICENSE.electron.txt")) .catch(() => {/* ignore */})) + } + if (this.info.electronVersion != null && this.info.electronVersion[0] === "0") { + // electron release >= 0.37.4 - the default_app/ folder is a default_app.asar file + promises.push(remove(path.join(resourcesPath, "default_app"))) + } - promises.push(this.postInitApp(appOutDir)) - await BluebirdPromise.all(promises) - }) + await BluebirdPromise.all(promises) + + if (platformName === "darwin" || platformName === "mas") { + await (require("./packager/mac")).createApp(this, appOutDir) + } await this.doCopyExtraFiles(extraResourceMatchers) await this.doCopyExtraFiles(extraFileMatchers) @@ -280,8 +288,7 @@ export abstract class PlatformPackager await this.sanityCheckPackage(appOutDir, asarOptions != null) } - protected postInitApp(executableFile: string): Promise { - return BluebirdPromise.resolve(null) + protected async postInitApp(executableFile: string): Promise { } async getIconPath(): Promise { diff --git a/src/targets/nsis.ts b/src/targets/nsis.ts index b48f0b58aaa..1a07f8040f6 100644 --- a/src/targets/nsis.ts +++ b/src/targets/nsis.ts @@ -7,7 +7,7 @@ import { getBinFromBintray } from "../util/binDownload" import { v5 as uuid5 } from "uuid-1345" import { normalizeExt, Target, getPublishConfigs, getResolvedPublishConfig, ArtifactCreated } from "../platformPackager" import { archive } from "./archive" -import { subTask, log } from "../util/log" +import { subTask, log, warn } from "../util/log" import { unlink, readFile, writeFile, createReadStream } from "fs-extra-p" import { SemVer } from "semver" import { NsisOptions } from "../options/winOptions" @@ -35,6 +35,11 @@ export default class NsisTarget extends Target { constructor(private packager: WinPackager, private outDir: string) { super("nsis") + + const deps = packager.info.metadata.dependencies + if (deps != null && deps["electron-squirrel-startup"] != null) { + warn('"electron-squirrel-startup" dependency is not required for NSIS') + } } private computePublishConfigs(): Promise | null> { diff --git a/src/targets/squirrelPack.ts b/src/targets/squirrelPack.ts index 0c8ac7db093..92bb8bc7ab0 100644 --- a/src/targets/squirrelPack.ts +++ b/src/targets/squirrelPack.ts @@ -152,7 +152,6 @@ async function pack(options: SquirrelOptions, directory: string, updateFile: str - diff --git a/test/src/helpers/checkDeps.ts b/test/src/helpers/checkDeps.ts index 1263c395bc1..5dba7087f24 100644 --- a/test/src/helpers/checkDeps.ts +++ b/test/src/helpers/checkDeps.ts @@ -7,13 +7,14 @@ const printErrorAndExit = require("../../../out/util/promise").printErrorAndExit const knownUnusedDevDependencies = new Set([ "@develar/types", - "ava-tf", + "jest-cli", "decompress-zip", "diff", "husky", "json8", "path-sort", "typescript", + "tslint", "depcheck" ]) diff --git a/test/src/helpers/expectedContents.ts b/test/src/helpers/expectedContents.ts index f292c98acbf..ddf3598f11b 100755 --- a/test/src/helpers/expectedContents.ts +++ b/test/src/helpers/expectedContents.ts @@ -11,7 +11,7 @@ export const expectedLinuxContents = ["/", "/opt/TestApp/icudtl.dat", "/opt/TestApp/libffmpeg.so", "/opt/TestApp/libnode.so", - "/opt/TestApp/LICENSE", + "/opt/TestApp/LICENSE.electron.txt", "/opt/TestApp/LICENSES.chromium.html", "/opt/TestApp/natives_blob.bin", "/opt/TestApp/snapshot_blob.bin", @@ -67,7 +67,7 @@ export const expectedWinContents = [ "lib/net45/icudtl.dat", "lib/net45/libEGL.dll", "lib/net45/libGLESv2.dll", - "lib/net45/LICENSE", + "lib/net45/LICENSE.electron.txt", "lib/net45/LICENSES.chromium.html", "lib/net45/natives_blob.bin", "lib/net45/node.dll", @@ -96,7 +96,7 @@ export const nsisPerMachineInstall = pathSorter([ "Program Files/TestApp/1.1.0/icudtl.dat", "Program Files/TestApp/1.1.0/libEGL.dll", "Program Files/TestApp/1.1.0/libGLESv2.dll", - "Program Files/TestApp/1.1.0/LICENSE", + "Program Files/TestApp/1.1.0/LICENSE.electron.txt", "Program Files/TestApp/1.1.0/LICENSES.chromium.html", "Program Files/TestApp/1.1.0/locales", "Program Files/TestApp/1.1.0/natives_blob.bin", diff --git a/yarn.lock b/yarn.lock index 3fd5fccf9c6..57e6ff7b8d1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -421,7 +421,7 @@ babel-plugin-transform-async-to-module-method@^6.16.0: babel-runtime "^6.0.0" babel-types "^6.16.0" -babel-plugin-transform-es2015-destructuring@^6.18.0: +babel-plugin-transform-es2015-destructuring@^6.19.0: version "6.19.0" resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.19.0.tgz#ff1d911c4b3f4cab621bd66702a869acd1900533" dependencies: @@ -1072,7 +1072,7 @@ delegates@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" -depcheck@^0.6.4: +depcheck@^0.6.5: version "0.6.5" resolved "https://registry.yarnpkg.com/depcheck/-/depcheck-0.6.5.tgz#baee2148e83f1295d372d7c50fd6f7205ccdb8fa" dependencies: