diff --git a/.idea/dictionaries/develar.xml b/.idea/dictionaries/develar.xml
index cda3f20b634..a682717901d 100644
--- a/.idea/dictionaries/develar.xml
+++ b/.idea/dictionaries/develar.xml
@@ -26,6 +26,7 @@
archiver
archs
armv
+ arpproducticon
asar
aspx
atexit
@@ -83,6 +84,7 @@
docdash
docstrap
donorbox
+ dontnet
dpkg
dsym
dyld
@@ -259,6 +261,7 @@
prebuild
precompilation
preinstall
+ preinstalled
prelease
prerelease
priconfig
diff --git a/README.md b/README.md
index 8492ba904b0..e0286cece3f 100644
--- a/README.md
+++ b/README.md
@@ -145,3 +145,4 @@ We do this open source work in our free time. If you'd like us to invest more ti
## Sponsors
+
diff --git a/appveyor.yml b/appveyor.yml
index e09755e0505..7d093bca730 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -7,7 +7,7 @@ cache:
- '%LOCALAPPDATA%\electron-builder\cache'
environment:
- TEST_FILES: ExtraBuildTest,BuildTest,extraMetadataTest,filesTest,globTest,nsisUpdaterTest,oneClickInstallerTest,installerTest,appxTest
+ TEST_FILES: ExtraBuildTest,BuildTest,extraMetadataTest,filesTest,globTest,nsisUpdaterTest,oneClickInstallerTest,installerTest,appxTest,msiTest
install:
- ps: Install-Product node 8 x64
diff --git a/package.json b/package.json
index 5349110bc39..19d910fc057 100644
--- a/package.json
+++ b/package.json
@@ -31,9 +31,9 @@
"7zip-bin": "^2.2.7",
"archiver": "^2.1.0",
"async-exit-hook": "^2.0.1",
- "aws-sdk": "^2.138.0",
+ "aws-sdk": "^2.139.0",
"bluebird-lst": "^1.0.5",
- "chalk": "2.1.0",
+ "chalk": "^2.3.0",
"chromium-pickle-js": "^0.2.0",
"cuint": "^0.2.2",
"debug": "^3.1.0",
@@ -72,7 +72,6 @@
},
"devDependencies": {
"@develar/gitbook": "3.2.10",
- "@types/chalk": "^0.4.31",
"@types/debug": "^0.0.30",
"@types/ejs": "^2.3.33",
"@types/electron-is-dev": "^0.3.0",
diff --git a/packages/builder-util/package.json b/packages/builder-util/package.json
index 016ff384e39..fac353b9935 100644
--- a/packages/builder-util/package.json
+++ b/packages/builder-util/package.json
@@ -16,7 +16,7 @@
"is-ci": "^1.0.10",
"stat-mode": "^0.2.2",
"bluebird-lst": "^1.0.5",
- "chalk": "2.1.0",
+ "chalk": "^2.3.0",
"debug": "^3.1.0",
"node-emoji": "^1.8.1",
"builder-util-runtime": "^0.0.0-semantic-release",
diff --git a/packages/builder-util/src/log.ts b/packages/builder-util/src/log.ts
index e1dbde01bf5..1f6700a67f5 100644
--- a/packages/builder-util/src/log.ts
+++ b/packages/builder-util/src/log.ts
@@ -1,5 +1,5 @@
import BluebirdPromise from "bluebird-lst"
-import { yellow } from "chalk"
+import chalk from "chalk"
import { get as getEmoji } from "node-emoji"
import WritableStream = NodeJS.WritableStream
@@ -14,7 +14,7 @@ class Logger {
}
warn(message: string): void {
- this.log(yellow(`Warning: ${message}`))
+ this.log(chalk.yellow(`Warning: ${message}`))
}
log(message: string): void {
@@ -39,7 +39,7 @@ class TtyLogger extends Logger {
}
warn(message: string): void {
- this.log(`${getEmoji("warning")} ${yellow(message)}`)
+ this.log(`${getEmoji("warning")} ${chalk.yellow(message)}`)
}
}
diff --git a/packages/builder-util/src/promise.ts b/packages/builder-util/src/promise.ts
index 17b50f915a6..c92e57042e0 100644
--- a/packages/builder-util/src/promise.ts
+++ b/packages/builder-util/src/promise.ts
@@ -1,7 +1,7 @@
-import { red } from "chalk"
+import chalk from "chalk"
export function printErrorAndExit(error: Error) {
- console.error(red((error.stack || error).toString()))
+ console.error(chalk.red((error.stack || error).toString()))
process.exit(-1)
}
diff --git a/packages/builder-util/src/util.ts b/packages/builder-util/src/util.ts
index 5ee90646818..07ff3332356 100644
--- a/packages/builder-util/src/util.ts
+++ b/packages/builder-util/src/util.ts
@@ -1,6 +1,6 @@
import BluebirdPromise from "bluebird-lst"
import { safeStringifyJson } from "builder-util-runtime"
-import { red, yellow } from "chalk"
+import chalk from "chalk"
import { ChildProcess, execFile, spawn as _spawn, SpawnOptions } from "child_process"
import { createHash } from "crypto"
import _debug from "debug"
@@ -99,18 +99,18 @@ export function exec(file: string, args?: Array | null, options?: ExecOp
resolve(stdout.toString())
}
else {
- let message = red(removePassword(`Exit code: ${(error as any).code}. ${error.message}`))
+ let message = chalk.red(removePassword(`Exit code: ${(error as any).code}. ${error.message}`))
if (stdout.length !== 0) {
if (file.endsWith("wine")) {
stdout = removeWineSpam(stdout.toString())
}
- message += `\n${yellow(stdout.toString())}`
+ message += `\n${chalk.yellow(stdout.toString())}`
}
if (stderr.length !== 0) {
if (file.endsWith("wine")) {
stderr = removeWineSpam(stderr.toString())
}
- message += `\n${red(stderr.toString())}`
+ message += `\n${chalk.red(stderr.toString())}`
}
reject(new Error(message))
diff --git a/packages/builder-util/src/wine.ts b/packages/builder-util/src/wine.ts
index 8813c19db08..b8bb62f06c6 100644
--- a/packages/builder-util/src/wine.ts
+++ b/packages/builder-util/src/wine.ts
@@ -16,9 +16,9 @@ const wineExecutable = new Lazy(async () => {
let version: string | null = null
let checksum: string | null = null
if (semver.gte(osVersion, "10.13.0")) {
- version = "2.0.2-mac-10.13"
+ version = "2.0.3-mac-10.13"
// noinspection SpellCheckingInspection
- checksum = "v6r9RSQBAbfvpVQNrEj48X8Cw1181rEGMRatGxSKY5p+7khzzy/0tOdfHGO8cU+GqYvH43FAKMK8p6vUfCqSSA=="
+ checksum = "dlEVCf0YKP5IEiOKPNE48Q8NKXbXVdhuaI9hG2oyDEay2c+93PE5qls7XUbIYq4Xi1gRK8fkWeCtzN2oLpVQtg=="
}
else if (semver.gte(osVersion, "10.12.0")) {
version = "2.0.1-mac-10.12"
@@ -52,7 +52,16 @@ export function execWine(file: string, args: Array, options: ExecOptions
}
else {
return wineExecutable.value
- .then(wine => exec(wine.path, [file].concat(args), wine.env == null ? options : {env: wine.env, ...options}))
+ .then(wine => {
+ const effectiveOptions = wine.env == null ? options : {...options}
+ if (wine.env != null) {
+ effectiveOptions.env = options.env == null ? wine.env : {
+ ...options.env,
+ ...wine.env,
+ }
+ }
+ return exec(wine.path, [file].concat(args), effectiveOptions)
+ })
}
}
diff --git a/packages/electron-builder/package.json b/packages/electron-builder/package.json
index b9dc07c82b4..52cc429d558 100644
--- a/packages/electron-builder/package.json
+++ b/packages/electron-builder/package.json
@@ -54,7 +54,7 @@
"7zip-bin": "^2.2.7",
"async-exit-hook": "^2.0.1",
"bluebird-lst": "^1.0.5",
- "chalk": "2.1.0",
+ "chalk": "^2.3.0",
"chromium-pickle-js": "^0.2.0",
"cuint": "^0.2.2",
"app-package-builder": "0.0.0-semantic-release",
diff --git a/packages/electron-builder/src/appInfo.ts b/packages/electron-builder/src/appInfo.ts
index 43faee1db7f..abe24d655c2 100644
--- a/packages/electron-builder/src/appInfo.ts
+++ b/packages/electron-builder/src/appInfo.ts
@@ -26,11 +26,8 @@ export class AppInfo {
if (!isEmptyOrSpaces(this.buildNumber)) {
buildVersion += `.${this.buildNumber}`
}
- this.buildVersion = buildVersion
- }
- else {
- this.buildVersion = buildVersion
}
+ this.buildVersion = buildVersion
this.productName = info.config.productName || info.metadata.productName || info.metadata.name!
this.productFilename = sanitizeFileName(this.productName)
diff --git a/packages/electron-builder/src/builder.ts b/packages/electron-builder/src/builder.ts
index 6c5573d1269..951d888f89f 100644
--- a/packages/electron-builder/src/builder.ts
+++ b/packages/electron-builder/src/builder.ts
@@ -2,7 +2,7 @@ import BluebirdPromise from "bluebird-lst"
import { addValue, Arch, archFromString, isEmptyOrSpaces, warn } from "builder-util"
import { CancellationToken } from "builder-util-runtime"
import { executeFinally } from "builder-util/out/promise"
-import { underline } from "chalk"
+import chalk from "chalk"
import { PublishOptions } from "electron-publish"
import { deepAssign } from "read-config-file/out/deepAssign"
import { Configuration } from "./configuration"
@@ -304,19 +304,19 @@ export function configureBuildCommand(yargs: yargs.Yargs): yargs.Yargs {
.option("mac", {
group: buildGroup,
alias: ["m", "o", "macos"],
- description: `Build for macOS, accepts target list (see ${underline("https://goo.gl/5uHuzj")}).`,
+ description: `Build for macOS, accepts target list (see ${chalk.underline("https://goo.gl/5uHuzj")}).`,
type: "array",
})
.option("linux", {
group: buildGroup,
alias: "l",
- description: `Build for Linux, accepts target list (see ${underline("https://goo.gl/4vwQad")})`,
+ description: `Build for Linux, accepts target list (see ${chalk.underline("https://goo.gl/4vwQad")})`,
type: "array",
})
.option("win", {
group: buildGroup,
alias: ["w", "windows"],
- description: `Build for Windows, accepts target list (see ${underline("https://goo.gl/jYsTEJ")})`,
+ description: `Build for Windows, accepts target list (see ${chalk.underline("https://goo.gl/jYsTEJ")})`,
type: "array",
})
.option("x64", {
@@ -342,7 +342,7 @@ export function configureBuildCommand(yargs: yargs.Yargs): yargs.Yargs {
.option("publish", {
group: publishGroup,
alias: "p",
- description: `Publish artifacts (to GitHub Releases), see ${underline("https://goo.gl/tSFycD")}`,
+ description: `Publish artifacts (to GitHub Releases), see ${chalk.underline("https://goo.gl/tSFycD")}`,
choices: ["onTag", "onTagOrDraft", "always", "never", undefined as any],
})
.option("draft", {
@@ -385,7 +385,7 @@ export function configureBuildCommand(yargs: yargs.Yargs): yargs.Yargs {
.option("config", {
alias: ["c"],
group: buildGroup,
- description: "The path to an electron-builder config. Defaults to `electron-builder.yml` (or `json`, or `json5`), see " + underline("https://goo.gl/YFRJOM"),
+ description: "The path to an electron-builder config. Defaults to `electron-builder.yml` (or `json`, or `json5`), see " + chalk.underline("https://goo.gl/YFRJOM"),
})
.group(["help", "version"], "Other:")
.example("electron-builder -mwl", "build for macOS, Windows and Linux")
diff --git a/packages/electron-builder/src/cli/cli.ts b/packages/electron-builder/src/cli/cli.ts
index 95541ec4485..97572e20803 100644
--- a/packages/electron-builder/src/cli/cli.ts
+++ b/packages/electron-builder/src/cli/cli.ts
@@ -2,7 +2,7 @@
import { exec, log, warn } from "builder-util"
import { printErrorAndExit } from "builder-util/out/promise"
-import { cyan, dim, green, reset, underline } from "chalk"
+import chalk from "chalk"
import { readJson } from "fs-extra-p"
import isCi from "is-ci"
import * as path from "path"
@@ -35,7 +35,7 @@ yargs
yargs => yargs,
wrap(argv => start()))
.help()
- .epilog(`See ${underline("https://electron.build")} for more documentation.`)
+ .epilog(`See ${chalk.underline("https://electron.build")} for more documentation.`)
.strict()
.recommendCommands()
.argv
@@ -63,7 +63,7 @@ function checkIsOutdated() {
const notifier = updateNotifier({pkg: it})
if (notifier.update != null) {
notifier.notify({
- message: `Update available ${dim(notifier.update.current)}${reset(" → ")}${green(notifier.update.latest)} \nRun ${cyan("yarn upgrade electron-builder")} to update`
+ message: `Update available ${chalk.dim(notifier.update.current)}${chalk.reset(" → ")}${chalk.green(notifier.update.latest)} \nRun ${chalk.cyan("yarn upgrade electron-builder")} to update`
})
}
})
diff --git a/packages/electron-builder/src/cli/create-self-signed-cert.ts b/packages/electron-builder/src/cli/create-self-signed-cert.ts
index 73f4390a6df..e061f3cbbaf 100644
--- a/packages/electron-builder/src/cli/create-self-signed-cert.ts
+++ b/packages/electron-builder/src/cli/create-self-signed-cert.ts
@@ -1,6 +1,6 @@
import { exec, log, spawn, TmpDir } from "builder-util"
import { unlinkIfExists } from "builder-util/out/fs"
-import { bold } from "chalk"
+import chalk from "chalk"
import { ensureDir } from "fs-extra-p"
import * as path from "path"
import sanitizeFileName from "sanitize-filename"
@@ -15,7 +15,7 @@ export async function createSelfSignedCert(publisher: string) {
const cer = `${tempPrefix}.cer`
const pvk = `${tempPrefix}.pvk`
- log(bold('When asked to enter a password ("Create Private Key Password"), please select "None".'))
+ log(chalk.bold('When asked to enter a password ("Create Private Key Password"), please select "None".'))
try {
await ensureDir(path.dirname(tempPrefix))
diff --git a/packages/electron-builder/src/options/MsiOptions.ts b/packages/electron-builder/src/options/MsiOptions.ts
index 8607ad923b9..d755220a52d 100644
--- a/packages/electron-builder/src/options/MsiOptions.ts
+++ b/packages/electron-builder/src/options/MsiOptions.ts
@@ -7,12 +7,19 @@ export interface MsiOptions extends TargetSpecificOptions {
*/
readonly oneClick?: boolean
- /***
+ /**
* Install per all users (per-machine).
* @default true
+ * @private Well, one-click per-user is not easy to write for us, feature hidden for now
*/
readonly perMachine?: boolean
+ /**
+ * *one-click installer only.* Whether to run the installed application after finish.
+ * @default true
+ */
+ readonly runAfterFinish?: boolean
+
/**
* The [upgrade code](https://msdn.microsoft.com/en-us/library/windows/desktop/aa372375(v=vs.85).aspx). Optional, by default generated using app id.
*/
@@ -23,4 +30,9 @@ export interface MsiOptions extends TargetSpecificOptions {
* @default true
*/
readonly warningsAsErrors?: boolean
+
+ /**
+ * The name that will be used for all shortcuts. Defaults to the application name.
+ */
+ readonly shortcutName?: string | null
}
\ No newline at end of file
diff --git a/packages/electron-builder/src/targets/AppxTarget.ts b/packages/electron-builder/src/targets/AppxTarget.ts
index b141a36150c..80b259fc075 100644
--- a/packages/electron-builder/src/targets/AppxTarget.ts
+++ b/packages/electron-builder/src/targets/AppxTarget.ts
@@ -8,7 +8,7 @@ import { Target } from "../core"
import { getTemplatePath } from "../util/pathManager"
import { getSignVendorPath, isOldWin6 } from "../windowsCodeSign"
import { WinPackager } from "../winPackager"
-import { VmManager } from "../parallels"
+import { VmManager } from "../vm/vm"
import { createHelperDir } from "./targetUtil"
import { AppXOptions } from "../"
diff --git a/packages/electron-builder/src/targets/MsiTarget.ts b/packages/electron-builder/src/targets/MsiTarget.ts
index d91d4428c8f..94fb34095eb 100644
--- a/packages/electron-builder/src/targets/MsiTarget.ts
+++ b/packages/electron-builder/src/targets/MsiTarget.ts
@@ -1,6 +1,6 @@
import { Target } from "../core"
import { WinPackager } from "../winPackager"
-import { Arch, warn } from "builder-util"
+import { Arch, warn, isEmptyOrSpaces } from "builder-util"
import { readFile, writeFile } from "fs-extra-p"
import { getTemplatePath } from "../util/pathManager"
import * as path from "path"
@@ -11,11 +11,21 @@ import { UUID } from "builder-util-runtime"
import BluebirdPromise from "bluebird-lst"
import { walk } from "builder-util/out/fs"
import { createHash } from "crypto"
+import { VmManager } from "../vm/vm"
+import { WineVmManager } from "../vm/wine"
+import * as ejs from "ejs"
+import { Lazy } from "lazy-val"
+import { getBinFromGithub } from "builder-util/out/binDownload"
const ELECTRON_BUILDER_UPGRADE_CODE_NS_UUID = UUID.parse("d752fe43-5d44-44d5-9fc9-6dd1bf19d5cc")
const ELECTRON_BUILDER_COMPONENT_KEY_PATH_NS_UUID = UUID.parse("a1fd0bba-2e5e-48dd-8b0e-caa943b1b0c9")
const ROOT_DIR_ID = "APPLICATIONFOLDER"
+const projectTemplate = new Lazy<(data: any) => string>(async () => {
+ return ejs.compile(await readFile(path.join(getTemplatePath("msi"), "template.wxs"), "utf8"))
+})
+
+// WiX doesn't support Mono, so, dontnet462 is required to be installed for wine (preinstalled in our bundled wine)
export default class MsiTarget extends Target {
readonly options: MsiOptions = deepAssign({
perMachine: true,
@@ -27,128 +37,92 @@ export default class MsiTarget extends Target {
async build(appOutDir: string, arch: Arch) {
const packager = this.packager
- const vm = await packager.vm.value
-
const stageDir = await createHelperDir(this, arch)
+ const vm = process.platform === "win32" ? new VmManager() : new WineVmManager()
const projectFile = stageDir.getTempFile("project.wxs")
const objectFile = stageDir.getTempFile("project.wixobj")
- await writeFile(projectFile, await this.writeManifest(getTemplatePath("msi"), appOutDir, arch))
+ await writeFile(projectFile, await this.writeManifest(appOutDir, arch, vm))
- // const vendorPath = "/Users/develar/Library/Caches/electron-builder/wix"
- const vendorPath = "C:\\Program Files (x86)\\WiX Toolset v4.0\\bin"
+ const vendorPath = await getBinFromGithub("wix", "4.0.0.5512", "cA62F/9OAuR7YnOORAhE0ZExUASD+PFtf67tckhX/GLXBvAwBk7c7+mx8Kwrt0TDomomVz1TaryUgcRz+zKXng==")
+ // noinspection SpellCheckingInspection
const candleArgs = [
"-arch", arch === Arch.ia32 ? "x86" : (arch === Arch.armv7l ? "arm" : "x64"),
"-out", vm.toVmFile(objectFile),
- `-dappDir=${"C:\\Users\\develar\\win-unpacked"}`,
- "-pedantic",
- ]
- if (this.options.warningsAsErrors !== false) {
- candleArgs.push("-wx")
- }
+ // `-dappDir=${"C:\\Users\\develar\\win-unpacked"}`,
+ `-dappDir=${vm.toVmFile(appOutDir)}`,
+ ].concat(this.getCommonWixArgs())
candleArgs.push(vm.toVmFile(projectFile))
await vm.exec(vm.toVmFile(path.join(vendorPath, "candle.exe")), candleArgs)
const artifactName = packager.expandArtifactNamePattern(this.options, "msi", arch)
const artifactPath = path.join(this.outDir, artifactName)
+ await this.light(objectFile, vm, artifactPath, appOutDir, vendorPath)
+
+ await stageDir.cleanup()
+
+ packager.info.dispatchArtifactCreated({
+ file: artifactPath,
+ packager,
+ arch,
+ safeArtifactName: packager.computeSafeArtifactName(artifactName, "msi"),
+ target: this,
+ isWriteUpdateInfo: false,
+ })
+ }
+ private async light(objectFile: string, vm: VmManager, artifactPath: string, appOutDir: string, vendorPath: string) {
// noinspection SpellCheckingInspection
const lightArgs = [
"-out", vm.toVmFile(artifactPath),
- "-pedantic",
"-v",
// https://github.com/wixtoolset/issues/issues/5169
"-spdb",
- `-dappDir=${"C:\\Users\\develar\\win-unpacked"}`,
- // "-b", "Z:\\Volumes\\test\\electron-builder-test\\dist\\win-unpacked" || vm.toVmFile(appOutDir),
- ]
- if (this.options.warningsAsErrors !== false) {
- lightArgs.push("-wx")
+ // https://sourceforge.net/p/wix/bugs/2405/
+ // error LGHT1076 : ICE61: This product should remove only older versions of itself. The Maximum version is not less than the current product. (1.1.0.42 1.1.0.42)
+ "-sw1076",
+ // `-dappDir=${"C:\\Users\\develar\\win-unpacked"}`,
+ `-dappDir=${vm.toVmFile(appOutDir)}`,
+ // "-dcl:high",
+ ].concat(this.getCommonWixArgs())
+
+ // http://windows-installer-xml-wix-toolset.687559.n2.nabble.com/Build-3-5-2229-0-give-me-the-following-error-error-LGHT0216-An-unexpected-Win32-exception-with-errorn-td5707443.html
+ if (process.platform !== "win32") {
+ // noinspection SpellCheckingInspection
+ lightArgs.push("-sval")
}
if (this.options.oneClick === false) {
- // lightArgs.push("-ext", vm.toVmFile(path.join(vendorPath, "WixUIExtension.dll")))
lightArgs.push("-ext", "WixUIExtension")
}
lightArgs.push(vm.toVmFile(objectFile))
await vm.exec(vm.toVmFile(path.join(vendorPath, "light.exe")), lightArgs)
+ }
- await stageDir.cleanup()
-
- packager.info.dispatchArtifactCreated({
- file: artifactPath,
- packager,
- arch,
- safeArtifactName: packager.computeSafeArtifactName(artifactName, "msi"),
- target: this,
- isWriteUpdateInfo: false,
- })
+ private getCommonWixArgs() {
+ const args: Array = ["-pedantic"]
+ if (this.options.warningsAsErrors !== false) {
+ args.push("-wx")
+ }
+ return args
}
- private async writeManifest(templatePath: string, appOutDir: string, arch: Arch) {
+ private async writeManifest(appOutDir: string, arch: Arch, vm: VmManager) {
const appInfo = this.packager.appInfo
- const registryKeyPathId = UUID.v5(appInfo.id, ELECTRON_BUILDER_COMPONENT_KEY_PATH_NS_UUID)
-
- const dirNames = new Set()
- let dirs = ""
- const fileSpace = " ".repeat(6)
-
- let isRootDirAddedToRemoveTable = false
-
- const files = await BluebirdPromise.map(walk(appOutDir), file => {
- let packagePath = file.substring(appOutDir.length + 1)
- if (path.sep !== "\\") {
- packagePath = packagePath.replace(/\//g, "\\")
- }
-
- let isAddRemoveFolder = false
-
- const lastSlash = packagePath.lastIndexOf("\\")
- const fileName = lastSlash > 0 ? packagePath.substring(lastSlash + 1) : packagePath
- let directoryId: string | null = null
- let dirName = ""
- // Wix Directory.FileSource doesn't work - https://stackoverflow.com/questions/21519388/wix-filesource-confusion
- if (lastSlash > 0) {
- // This Name attribute may also define multiple directories using the inline directory syntax.
- // For example, "ProgramFilesFolder:\My Company\My Product\bin" would create a reference to a Directory element with Id="ProgramFilesFolder" then create directories named "My Company" then "My Product" then "bin" nested beneath each other.
- // This syntax is a shortcut to defining each directory in an individual Directory element.
- dirName = packagePath.substring(0, lastSlash)
- // add U (user) suffix just to be sure that will be not overwrite system WIX directory ids.
- directoryId = `${dirName.toLowerCase()}_u`
- if (!dirNames.has(dirName)) {
- isAddRemoveFolder = true
- dirNames.add(dirName)
- dirs += ` \n`
- }
- }
- else if (!isRootDirAddedToRemoveTable) {
- isRootDirAddedToRemoveTable = true
- isAddRemoveFolder = true
- }
-
- // since RegistryValue can be part of Component, *** *** *** *** *** *** *** *** *** wix cannot auto generate guid
- // https://stackoverflow.com/questions/1405100/change-my-component-guid-in-wix
- let result = ``
- if (!this.options.perMachine) {
- // https://stackoverflow.com/questions/16119708/component-testcomp-installs-to-user-profile-it-must-use-a-registry-key-under-hk
- result += `\n${fileSpace} `
- if (isAddRemoveFolder) {
- // https://stackoverflow.com/questions/3290576/directory-xx-is-in-the-user-profile-but-is-not-listed-in-the-removefile-table
- result += `\n${fileSpace} `
- }
- }
- // Id="${hashString(packagePath)}"
- result += `\n${fileSpace} \n${fileSpace}`
- return result
+ const {files, dirs} = await this.computeFileDeclaration(appOutDir)
+
+ const compression = this.packager.compression
+ const options = this.options
+ const text = (await projectTemplate.value)({
+ isRunAfterFinish: options.runAfterFinish !== false,
+ isAssisted: options.oneClick === false,
+ iconPath: await this.packager.getIconPath(),
+ compressionLevel: compression === "store" ? "none" : "high",
})
- return (await readFile(path.join(templatePath, "template.wxs"), "utf8"))
+ return text
.replace(/\$\{([a-zA-Z0-9]+)\}/g, (match, p1): string => {
const options = this.options
switch (p1) {
@@ -176,18 +150,11 @@ export default class MsiTarget extends Target {
case "version":
return appInfo.versionInWeirdWindowsForm
- case "compressionLevel":
- const compression = this.packager.compression
- return compression === "store" ? "none" : "high"
-
- case "uiRef":
- return options.oneClick === false ? '' : ""
-
case "dirs":
return dirs
case "files":
- return fileSpace + files.join(`\n${fileSpace}`)
+ return files
case "programFilesId":
if (options.perMachine) {
@@ -203,13 +170,87 @@ export default class MsiTarget extends Target {
}
})
}
-}
-// function hashString(s: string) {
-// const hash = createHash("md5")
-// hash.update(s)
-// return hash.digest("hex")
-// }
+ private async computeFileDeclaration(appOutDir: string) {
+ const appInfo = this.packager.appInfo
+ const registryKeyPathId = UUID.v5(appInfo.id, ELECTRON_BUILDER_COMPONENT_KEY_PATH_NS_UUID)
+ let isRootDirAddedToRemoveTable = false
+ const dirNames = new Set()
+ let dirs = ""
+ const fileSpace = " ".repeat(6)
+
+ const files = await BluebirdPromise.map(walk(appOutDir), file => {
+ const packagePath = file.substring(appOutDir.length + 1)
+ let isAddRemoveFolder = false
+
+ const lastSlash = packagePath.lastIndexOf(path.sep)
+ const fileName = lastSlash > 0 ? packagePath.substring(lastSlash + 1) : packagePath
+ let directoryId: string | null = null
+ let dirName = ""
+ // Wix Directory.FileSource doesn't work - https://stackoverflow.com/questions/21519388/wix-filesource-confusion
+ if (lastSlash > 0) {
+ // This Name attribute may also define multiple directories using the inline directory syntax.
+ // For example, "ProgramFilesFolder:\My Company\My Product\bin" would create a reference to a Directory element with Id="ProgramFilesFolder" then create directories named "My Company" then "My Product" then "bin" nested beneath each other.
+ // This syntax is a shortcut to defining each directory in an individual Directory element.
+ dirName = packagePath.substring(0, lastSlash)
+ // add U (user) suffix just to be sure that will be not overwrite system WIX directory ids.
+ directoryId = `${dirName.toLowerCase()}_u`
+ if (!dirNames.has(dirName)) {
+ isAddRemoveFolder = true
+ dirNames.add(dirName)
+ dirs += ` \n`
+ }
+ }
+ else if (!isRootDirAddedToRemoveTable) {
+ isRootDirAddedToRemoveTable = true
+ isAddRemoveFolder = true
+ }
+
+ // since RegistryValue can be part of Component, *** *** *** *** *** *** *** *** *** wix cannot auto generate guid
+ // https://stackoverflow.com/questions/1405100/change-my-component-guid-in-wix
+ let result = ``
+
+ // https://stackoverflow.com/questions/16119708/component-testcomp-installs-to-user-profile-it-must-use-a-registry-key-under-hk
+ result += `\n${fileSpace} `
+ if (isAddRemoveFolder) {
+ // https://stackoverflow.com/questions/3290576/directory-xx-is-in-the-user-profile-but-is-not-listed-in-the-removefile-table
+ result += `\n${fileSpace} `
+ }
+ }
+ else {
+ result += ">"
+ }
+
+ result += `\n${fileSpace} \n`
+ const shortcutName = isEmptyOrSpaces(options.shortcutName) ? appInfo.productFilename : this.packager.expandMacro(options.shortcutName!!)
+ result += `${fileSpace} \n`
+ result += `${fileSpace}`
+ }
+ else {
+ result += `/>`
+ }
+
+ return `${result}\n${fileSpace}`
+ })
+
+ return {dirs, files: fileSpace + files.join(`\n${fileSpace}`)}
+ }
+}
const nullByteBuffer = Buffer.from([0])
diff --git a/packages/electron-builder/src/targets/nsis/nsisOptions.ts b/packages/electron-builder/src/targets/nsis/nsisOptions.ts
index b7b4d415a23..6d90d56b85b 100644
--- a/packages/electron-builder/src/targets/nsis/nsisOptions.ts
+++ b/packages/electron-builder/src/targets/nsis/nsisOptions.ts
@@ -53,7 +53,7 @@ export interface NsisOptions extends CommonNsisOptions, TargetSpecificOptions {
readonly allowToChangeInstallationDirectory?: boolean
/**
- * *one-click installer only.* Run application after finish.
+ * *one-click installer only.* Whether to run the installed application after finish.
* @default true
*/
readonly runAfterFinish?: boolean
diff --git a/packages/electron-builder/src/vm/mono.ts b/packages/electron-builder/src/vm/mono.ts
new file mode 100644
index 00000000000..3df20eb09fd
--- /dev/null
+++ b/packages/electron-builder/src/vm/mono.ts
@@ -0,0 +1,30 @@
+import { SpawnOptions } from "child_process"
+import { exec, ExecOptions, ExtraSpawnOptions, spawn } from "builder-util"
+import { VmManager } from "./vm"
+
+export class MonoVmManager extends VmManager {
+ constructor(private readonly currentDirectory: string) {
+ super()
+ }
+
+ exec(file: string, args: Array, options?: ExecOptions, isLogOutIfDebug = true): Promise {
+ return exec("mono", [file].concat(args), {
+ cwd: this.currentDirectory,
+ ...options,
+ }, isLogOutIfDebug)
+ }
+
+ spawn(file: string, args: Array, options?: SpawnOptions, extraOptions?: ExtraSpawnOptions): Promise {
+ return spawn("mono", [file].concat(args), options, extraOptions)
+ }
+
+ toVmFile(file: string): string {
+ const parentPathLengthWithSlash = this.currentDirectory.length + 1
+ if (parentPathLengthWithSlash < file.length && file[this.currentDirectory.length] === "/" && file.startsWith(this.currentDirectory)) {
+ return file.substring(parentPathLengthWithSlash)
+ }
+ else {
+ return super.toVmFile(file)
+ }
+ }
+}
\ No newline at end of file
diff --git a/packages/electron-builder/src/parallels.ts b/packages/electron-builder/src/vm/parallels.ts
similarity index 71%
rename from packages/electron-builder/src/parallels.ts
rename to packages/electron-builder/src/vm/parallels.ts
index 8f89e5173e2..8780b7745e2 100644
--- a/packages/electron-builder/src/parallels.ts
+++ b/packages/electron-builder/src/vm/parallels.ts
@@ -1,8 +1,9 @@
import { exec, spawn, ExecOptions, DebugLogger, ExtraSpawnOptions } from "builder-util"
import { SpawnOptions, execFileSync } from "child_process"
-import * as path from "path"
+import { VmManager } from "./vm"
-async function parseVmList(debugLogger: DebugLogger) {
+/** @internal */
+export async function parseVmList(debugLogger: DebugLogger) {
// do not log output if debug - it is huge, logged using debugLogger
let rawList = await exec("prlctl", ["list", "-i", "-s", "name"], undefined, false)
debugLogger.add("parallels.list", rawList)
@@ -29,35 +30,8 @@ async function parseVmList(debugLogger: DebugLogger) {
return result
}
-export async function getWindowsVm(debugLogger: DebugLogger): Promise {
- const vmList = (await parseVmList(debugLogger)).filter(it => it.os === "win-10")
- if (vmList.length === 0) {
- throw new Error("Cannot find suitable Parallels Desktop virtual machine (Windows 10 is required)")
- }
-
- // prefer running or suspended vm
- return new ParallelsVmManager(vmList.find(it => it.state === "running") || vmList.find(it => it.state === "suspended") || vmList[0])
-}
-
-export class VmManager {
- get pathSep(): string {
- return path.sep
- }
-
- exec(file: string, args: Array, options?: ExecOptions, isLogOutIfDebug = true): Promise {
- return exec(file, args, options, isLogOutIfDebug)
- }
-
- spawn(command: string, args: Array, options?: SpawnOptions, extraOptions?: ExtraSpawnOptions): Promise {
- return spawn(command, args)
- }
-
- toVmFile(file: string): string {
- return file
- }
-}
-
-class ParallelsVmManager extends VmManager {
+/** @internal */
+export class ParallelsVmManager extends VmManager {
private startPromise: Promise
private isExitHookAdded = false
@@ -86,9 +60,9 @@ class ParallelsVmManager extends VmManager {
.catch(error => this.handleExecuteError(error))
}
- async spawn(command: string, args: Array, options?: SpawnOptions, extraOptions?: ExtraSpawnOptions): Promise {
+ async spawn(file: string, args: Array, options?: SpawnOptions, extraOptions?: ExtraSpawnOptions): Promise {
await this.ensureThatVmStarted()
- return await spawn("prlctl", ["exec", this.vm.id, command].concat(args), options, extraOptions)
+ return await spawn("prlctl", ["exec", this.vm.id, file].concat(args), options, extraOptions)
.catch(error => this.handleExecuteError(error))
}
@@ -135,7 +109,8 @@ export function macPathToParallelsWindows(file: string) {
if (file.startsWith("C:\\")) {
return file
}
- return "\\\\Mac\\Host\\" + file.replace(/\//g, "\\")
+ // return "\\\\Mac\\Host\\" + file.replace(/\//g, "\\")
+ return "Z:" + file.replace(/\//g, "\\")
}
export interface ParallelsVm {
diff --git a/packages/electron-builder/src/vm/vm.ts b/packages/electron-builder/src/vm/vm.ts
new file mode 100644
index 00000000000..7542284f174
--- /dev/null
+++ b/packages/electron-builder/src/vm/vm.ts
@@ -0,0 +1,32 @@
+import * as path from "path"
+import { SpawnOptions } from "child_process"
+import { DebugLogger, exec, ExecOptions, ExtraSpawnOptions, spawn } from "builder-util"
+import { ParallelsVmManager, parseVmList } from "./parallels"
+
+export class VmManager {
+ get pathSep(): string {
+ return path.sep
+ }
+
+ exec(file: string, args: Array, options?: ExecOptions, isLogOutIfDebug = true): Promise {
+ return exec(file, args, options, isLogOutIfDebug)
+ }
+
+ spawn(file: string, args: Array, options?: SpawnOptions, extraOptions?: ExtraSpawnOptions): Promise {
+ return spawn(file, args, options, extraOptions)
+ }
+
+ toVmFile(file: string): string {
+ return file
+ }
+}
+
+export async function getWindowsVm(debugLogger: DebugLogger): Promise {
+ const vmList = (await parseVmList(debugLogger)).filter(it => it.os === "win-10")
+ if (vmList.length === 0) {
+ throw new Error("Cannot find suitable Parallels Desktop virtual machine (Windows 10 is required)")
+ }
+
+ // prefer running or suspended vm
+ return new ParallelsVmManager(vmList.find(it => it.state === "running") || vmList.find(it => it.state === "suspended") || vmList[0])
+}
\ No newline at end of file
diff --git a/packages/electron-builder/src/vm/wine.ts b/packages/electron-builder/src/vm/wine.ts
new file mode 100644
index 00000000000..8c7111c6d19
--- /dev/null
+++ b/packages/electron-builder/src/vm/wine.ts
@@ -0,0 +1,23 @@
+import { SpawnOptions } from "child_process"
+import { ExecOptions, ExtraSpawnOptions, execWine } from "builder-util"
+import { VmManager } from "./vm"
+import * as path from "path"
+
+/** @internal */
+export class WineVmManager extends VmManager {
+ constructor() {
+ super()
+ }
+
+ exec(file: string, args: Array, options?: ExecOptions, isLogOutIfDebug = true): Promise {
+ return execWine(file, args, options)
+ }
+
+ spawn(file: string, args: Array, options?: SpawnOptions, extraOptions?: ExtraSpawnOptions): Promise {
+ throw new Error("Unsupported")
+ }
+
+ toVmFile(file: string): string {
+ return path.win32.join("Z:", file)
+ }
+}
diff --git a/packages/electron-builder/src/winPackager.ts b/packages/electron-builder/src/winPackager.ts
index 2f57cfe6d55..72981f75aa5 100644
--- a/packages/electron-builder/src/winPackager.ts
+++ b/packages/electron-builder/src/winPackager.ts
@@ -22,7 +22,7 @@ import { BuildCacheManager, digest } from "./util/cacheManager"
import { isBuildCacheEnabled } from "./util/flags"
import { time } from "./util/timer"
import { CertificateFromStoreInfo, FileCodeSigningInfo, getCertificateFromStoreInfo, getSignVendorPath, sign, WindowsSignOptions } from "./windowsCodeSign"
-import { VmManager, getWindowsVm } from "./parallels"
+import { VmManager, getWindowsVm } from "./vm/vm"
export class WinPackager extends PlatformPackager {
readonly cscInfo = new Lazy(() => {
diff --git a/packages/electron-builder/src/windowsCodeSign.ts b/packages/electron-builder/src/windowsCodeSign.ts
index 6cb6b191705..97ec3fdb66f 100644
--- a/packages/electron-builder/src/windowsCodeSign.ts
+++ b/packages/electron-builder/src/windowsCodeSign.ts
@@ -8,7 +8,7 @@ import * as path from "path"
import { WindowsConfiguration } from "./options/winOptions"
import { resolveFunction } from "./platformPackager"
import { isUseSystemSigncode } from "./util/flags"
-import { VmManager } from "./parallels"
+import { VmManager } from "./vm/vm"
import { WinPackager } from "./winPackager"
export function getSignVendorPath() {
diff --git a/packages/electron-builder/templates/msi/template.wxs b/packages/electron-builder/templates/msi/template.wxs
index dc97624899d..ab4a8b1d9e5 100644
--- a/packages/electron-builder/templates/msi/template.wxs
+++ b/packages/electron-builder/templates/msi/template.wxs
@@ -2,29 +2,56 @@
-
+
- ${uiRef}
+ = 601]]>
-
-
+ <% if (iconPath) { %>
+
+
+ <% } -%>
+
+ <% if (isAssisted) { %>
+
+
+
+ <% } -%>
+
+ <% if (isRunAfterFinish) { %>
+
+
+
+
+
+ <% } -%>
+
+
+
+
-
-
+
+
+
-${dirs}
+ ${dirs}
-${files}
+ ${files}
\ No newline at end of file
diff --git a/packages/electron-publish/package.json b/packages/electron-publish/package.json
index 3c1000ef78d..c7753bfb873 100644
--- a/packages/electron-publish/package.json
+++ b/packages/electron-publish/package.json
@@ -16,7 +16,7 @@
"bluebird-lst": "^1.0.5",
"builder-util-runtime": "^0.0.0-semantic-release",
"builder-util": "^0.0.0-semantic-release",
- "chalk": "2.1.0"
+ "chalk": "^2.3.0"
},
"typings": "./out/publisher.d.ts"
}
diff --git a/packages/electron-publish/src/publisher.ts b/packages/electron-publish/src/publisher.ts
index 48efe25c620..dceb3792a6d 100644
--- a/packages/electron-publish/src/publisher.ts
+++ b/packages/electron-publish/src/publisher.ts
@@ -1,6 +1,6 @@
import { Arch, log } from "builder-util"
import { CancellationToken, ProgressCallbackTransform } from "builder-util-runtime"
-import { green } from "chalk"
+import chalk from "chalk"
import { createReadStream, stat, Stats } from "fs-extra-p"
import { ClientRequest } from "http"
import { basename } from "path"
@@ -47,7 +47,7 @@ export abstract class Publisher {
return null
}
else {
- return this.context.progress.createBar(`[:bar] :percent :etas | ${green(fileName)} to ${this.providerName}`, {total: size, ...progressBarOptions})
+ return this.context.progress.createBar(`[:bar] :percent :etas | ${chalk.green(fileName)} to ${this.providerName}`, {total: size, ...progressBarOptions})
}
}
diff --git a/packages/electron-publisher-s3/package.json b/packages/electron-publisher-s3/package.json
index 3f42a6707a8..0f80e28ea2b 100644
--- a/packages/electron-publisher-s3/package.json
+++ b/packages/electron-publisher-s3/package.json
@@ -12,7 +12,7 @@
],
"dependencies": {
"fs-extra-p": "^4.4.4",
- "aws-sdk": "^2.138.0",
+ "aws-sdk": "^2.139.0",
"mime": "^2.0.3",
"electron-publish": "~0.0.0-semantic-release",
"builder-util": "^0.0.0-semantic-release",
diff --git a/scripts/publish.sh b/scripts/publish.sh
index a7e35696ccb..f6d915f8b7d 100755
--- a/scripts/publish.sh
+++ b/scripts/publish.sh
@@ -11,6 +11,9 @@ set -e
cd _book
+mkdir sponsor-logos
+cp ../scripts/sponsor-logos/*.svg sponsor-logos/
+
# do not use force push - netlify doesn't trigger deploy for forced push
git clone --no-checkout --branch en --single-branch git@github.com:develar/generated-gitbook-electron-builder.git ./repo.tmp
mv ./repo.tmp/.git ./
diff --git a/scripts/sponsor-logos/Tidepool_Logo_Light.svg b/scripts/sponsor-logos/Tidepool_Logo_Light.svg
new file mode 100644
index 00000000000..c09080c2e90
--- /dev/null
+++ b/scripts/sponsor-logos/Tidepool_Logo_Light.svg
@@ -0,0 +1,107 @@
+
+
+
+
diff --git a/test/out/windows/__snapshots__/msiTest.js.snap b/test/out/windows/__snapshots__/msiTest.js.snap
index b025ad70922..6c362a48d38 100644
--- a/test/out/windows/__snapshots__/msiTest.js.snap
+++ b/test/out/windows/__snapshots__/msiTest.js.snap
@@ -5,7 +5,7 @@ Object {
"win": Array [
Object {
"arch": "x64",
- "file": "Test App ßW-1.1.0.msi",
+ "file": "Test MSI-1.1.0.msi",
"safeArtifactName": "TestApp-1.1.0.msi",
},
],
diff --git a/test/src/helpers/checkDeps.ts b/test/src/helpers/checkDeps.ts
index 9fabda36d46..87a36723294 100644
--- a/test/src/helpers/checkDeps.ts
+++ b/test/src/helpers/checkDeps.ts
@@ -1,5 +1,5 @@
import BluebirdPromise from "bluebird-lst"
-import { bold } from "chalk"
+import chalk from "chalk"
import depCheck, { DepCheckResult } from "depcheck"
import { readdir, readJson } from "fs-extra-p"
import * as path from "path"
@@ -29,13 +29,13 @@ async function check(projectDir: string, devPackageData: any): Promise
// console.log(result)
if (result.dependencies.length > 0) {
- console.error(`${bold(packageName)} Unused dependencies: ${JSON.stringify(result.dependencies, null, 2)}`)
+ console.error(`${chalk.bold(packageName)} Unused dependencies: ${JSON.stringify(result.dependencies, null, 2)}`)
return false
}
const unusedDevDependencies = result.devDependencies.filter(it => !it.startsWith("@types/") && !knownUnusedDevDependencies.has(it))
if (unusedDevDependencies.length > 0) {
- console.error(`${bold(packageName)} Unused devDependencies: ${JSON.stringify(unusedDevDependencies, null, 2)}`)
+ console.error(`${chalk.bold(packageName)} Unused devDependencies: ${JSON.stringify(unusedDevDependencies, null, 2)}`)
return false
}
@@ -52,7 +52,7 @@ async function check(projectDir: string, devPackageData: any): Promise
}
if (Object.keys(result.missing).length > 0) {
- console.error(`${bold(packageName)} Missing dependencies: ${JSON.stringify(result.missing, null, 2)}`)
+ console.error(`${chalk.bold(packageName)} Missing dependencies: ${JSON.stringify(result.missing, null, 2)}`)
return false
}
@@ -69,7 +69,7 @@ async function check(projectDir: string, devPackageData: any): Promise
for (const file of usages) {
if (file.startsWith(path.join(projectDir, "src") + path.sep)) {
- console.error(`${bold(packageName)} Dev dependency ${name} is used in the sources`)
+ console.error(`${chalk.bold(packageName)} Dev dependency ${name} is used in the sources`)
return false
}
}
diff --git a/test/src/windows/msiTest.ts b/test/src/windows/msiTest.ts
index 6caf7fa86ab..bc7eb57ee91 100644
--- a/test/src/windows/msiTest.ts
+++ b/test/src/windows/msiTest.ts
@@ -1,6 +1,27 @@
import { app } from "../helpers/packTester"
import { Platform } from "electron-builder"
-test.ifAll.ifNotCi("msi", app({
+test.ifAll("msi", app({
targets: Platform.WINDOWS.createTarget("msi"),
+ config: {
+ extraMetadata: {
+ // version: "1.0.0",
+ },
+ productName: "Test MSI",
+ }
+}))
+
+test.ifAll("assisted", app({
+ targets: Platform.WINDOWS.createTarget("msi"),
+ config: {
+ extraMetadata: {
+ // version: "1.0.0",
+ },
+ productName: "Test MSI Assisted",
+ // test lzx (currently, doesn't work on wine)
+ compression: "maximum",
+ msi: {
+ oneClick: false,
+ },
+ }
}))
\ No newline at end of file
diff --git a/yarn.lock b/yarn.lock
index 552a9bffcb9..4d1fcad6504 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -75,10 +75,6 @@
tmp "^0.0.33"
urijs "1.18.12"
-"@types/chalk@^0.4.31":
- version "0.4.31"
- resolved "https://registry.yarnpkg.com/@types/chalk/-/chalk-0.4.31.tgz#a31d74241a6b1edbb973cf36d97a2896834a51f9"
-
"@types/debug@^0.0.30":
version "0.0.30"
resolved "https://registry.yarnpkg.com/@types/debug/-/debug-0.0.30.tgz#dc1e40f7af3b9c815013a7860e6252f6352a84df"
@@ -443,9 +439,9 @@ asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
-aws-sdk@^2.138.0:
- version "2.138.0"
- resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.138.0.tgz#acb923132b51fafe8a464aa757f65d61ac30bd77"
+aws-sdk@^2.139.0:
+ version "2.139.0"
+ resolved "https://registry.yarnpkg.com/aws-sdk/-/aws-sdk-2.139.0.tgz#5eb93d0c16fd12a5be9ddf5db053f0dad677237f"
dependencies:
buffer "4.9.1"
crypto-browserify "1.0.9"
@@ -904,14 +900,6 @@ chainsaw@~0.1.0:
dependencies:
traverse ">=0.3.0 <0.4"
-chalk@2.1.0:
- version "2.1.0"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.1.0.tgz#ac5becf14fa21b99c6c92ca7a7d7cfd5b17e743e"
- dependencies:
- ansi-styles "^3.1.0"
- escape-string-regexp "^1.0.5"
- supports-color "^4.0.0"
-
chalk@^1.1.3:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
@@ -922,9 +910,9 @@ chalk@^1.1.3:
strip-ansi "^3.0.0"
supports-color "^2.0.0"
-chalk@^2.0.1, chalk@^2.1.0:
- version "2.2.0"
- resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.2.0.tgz#477b3bf2f9b8fd5ca9e429747e37f724ee7af240"
+chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0:
+ version "2.3.0"
+ resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.3.0.tgz#b5ea48efc9c1793dccc9b4767c93914d3f2d52ba"
dependencies:
ansi-styles "^3.1.0"
escape-string-regexp "^1.0.5"