From f143bad38a490e94a4df2a4003fe6c964b69f746 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Thu, 4 Jun 2020 14:29:09 -0700 Subject: [PATCH 1/7] localLambdaRunner.test.ts: avoid ExtensionDisposableFiles.initialize() #1133 Use FakeExtensionContext.getNew() instead, which forces re-initialization of ExtensionDisposableFiles and avoids an exception if it was already initialized. ref: https://github.com/aws/aws-toolkit-vscode/pull/1097/files#r435476880 Other tests may call ExtensionDisposableFiles.initialize(), which causes an error (all tests run in the same process): Error: ExtensionDisposableFiles already initialized at Function. (dist/src/shared/utilities/disposableFiles.js:9:4556) at Generator.next () at /codebuild/output/src753373494/src/github.com/aws/aws-toolkit-vscode/dist/src/shared/utilities/disposableFiles.js:9:1746 at new Promise () at __awaiter (dist/src/shared/utilities/disposableFiles.js:9:662) at Function.initialize (dist/src/shared/utilities/disposableFiles.js:9:4311) at /codebuild/output/src753373494/src/github.com/aws/aws-toolkit-vscode/src/test/shared/codelens/localLambdaRunner.test.ts:23:40 at Generator.next () at /codebuild/output/src753373494/src/github.com/aws/aws-toolkit-vscode/dist/src/test/shared/codelens/localLambdaRunner.test.js:12:71 at new Promise () at __awaiter (dist/src/test/shared/codelens/localLambdaRunner.test.js:8:12) at Context. (src/test/shared/codelens/localLambdaRunner.test.ts:22:23) at processImmediate (internal/timers.js:439:21) at process.topLevelDomainCallback (domain.js:131:23) --- src/test/fakeExtensionContext.ts | 17 +++++++++++++++++ .../shared/codelens/localLambdaRunner.test.ts | 3 +-- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/test/fakeExtensionContext.ts b/src/test/fakeExtensionContext.ts index 7bf0434f1ba..1dad7efbc75 100644 --- a/src/test/fakeExtensionContext.ts +++ b/src/test/fakeExtensionContext.ts @@ -4,6 +4,7 @@ */ import { ExtensionContext, Memento } from 'vscode' +import { ExtensionDisposableFiles } from '../shared/utilities/disposableFiles' export interface FakeMementoStorage { [key: string]: any @@ -43,6 +44,22 @@ export class FakeExtensionContext implements ExtensionContext { public asAbsolutePath(relativePath: string): string { return relativePath } + + /** + * Creates a fake `vscode.ExtensionContext` for use in tests. + * + * Disposes any existing `ExtensionDisposableFiles` and creates a new one + * with the new `ExtContext`. + */ + public static async getNew(): Promise { + const ctx = new FakeExtensionContext() + try { + ExtensionDisposableFiles.getInstance().dispose() + } catch { + await ExtensionDisposableFiles.initialize(ctx) + } + return ctx + } } class FakeMemento implements Memento { diff --git a/src/test/shared/codelens/localLambdaRunner.test.ts b/src/test/shared/codelens/localLambdaRunner.test.ts index 431779f99ee..e99acfa1c79 100644 --- a/src/test/shared/codelens/localLambdaRunner.test.ts +++ b/src/test/shared/codelens/localLambdaRunner.test.ts @@ -12,7 +12,6 @@ import { DebugConfiguration } from '../../../lambda/local/debugConfiguration' import * as localLambdaRunner from '../../../shared/codelens/localLambdaRunner' import * as fsUtils from '../../../shared/filesystemUtilities' import { ChildProcessResult } from '../../../shared/utilities/childProcess' -import { ExtensionDisposableFiles } from '../../../shared/utilities/disposableFiles' import { FakeExtensionContext } from '../../fakeExtensionContext' import { FakeChannelLogger } from '../fakeChannelLogger' import { assertRejects } from '../utilities/assertUtils' @@ -20,7 +19,7 @@ import { assertRejects } from '../utilities/assertUtils' describe('localLambdaRunner', async () => { let tempDir: string before(async () => { - await ExtensionDisposableFiles.initialize(new FakeExtensionContext()) + await FakeExtensionContext.getNew() }) beforeEach(async () => { From 9231bf0f5499448a715f3747a763700d41e10f9d Mon Sep 17 00:00:00 2001 From: Christopher Christou <39839589+awschristou@users.noreply.github.com> Date: Mon, 8 Jun 2020 09:57:17 -0700 Subject: [PATCH 2/7] Add Toolkit Initialization metric (#1136) Emit a metric indicating how long the toolkit takes to activate. This helps us find out the current performance, and long term try to drive it down below 250ms (per guidance from the VS Code team) --- package-lock.json | 6 +++--- package.json | 2 +- src/extension.ts | 20 +++++++++++++++++++- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6da8bd3f82d..1d3e80de49b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,9 +5,9 @@ "requires": true, "dependencies": { "@aws-toolkits/telemetry": { - "version": "0.0.20", - "resolved": "https://registry.npmjs.org/@aws-toolkits/telemetry/-/telemetry-0.0.20.tgz", - "integrity": "sha512-hFIOsXcFaoaNFv3qKH8H70n8R+kFyOJWlgN05aFe7wf7PhkEFALZyVGQjQzDbsSbjPZL2Yk3lGKoM47o+XIG/A==", + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@aws-toolkits/telemetry/-/telemetry-0.0.30.tgz", + "integrity": "sha512-F07BHqPWgB5Q1gZbIJup3v8j3d07ke4Gchhiu2M64KGgBy/fZNOypHRygjyzsgWfXM92nAXUvZm3cGvGz/HNKQ==", "dev": true, "requires": { "ajv": "^6.10.2", diff --git a/package.json b/package.json index 49f973633bc..b5869f3723e 100644 --- a/package.json +++ b/package.json @@ -858,7 +858,7 @@ "createRelease": "ts-node ./build-scripts/createRelease.ts" }, "devDependencies": { - "@aws-toolkits/telemetry": "0.0.20", + "@aws-toolkits/telemetry": "0.0.30", "@types/adm-zip": "^0.4.32", "@types/async-lock": "^1.1.0", "@types/cross-spawn": "^6.0.0", diff --git a/src/extension.ts b/src/extension.ts index 85c430036ff..9f8bbef86b6 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -35,7 +35,7 @@ import { showQuickStartWebview, toastNewUser, } from './shared/extensionUtilities' -import { getLogger } from './shared/logger' +import { getLogger, Logger } from './shared/logger' import { activate as activateLogger } from './shared/logger/activation' import { DefaultRegionProvider } from './shared/regions/defaultRegionProvider' import { EndpointsProvider } from './shared/regions/endpointsProvider' @@ -50,6 +50,7 @@ import { recordAwsHelpQuickstart, recordAwsReportPluginIssue, recordAwsShowExtensionSource, + recordToolkitInit, } from './shared/telemetry/telemetry' import { ExtensionDisposableFiles } from './shared/utilities/disposableFiles' import { getChannelLogger } from './shared/utilities/vsCodeUtils' @@ -58,6 +59,8 @@ import { activate as activateStepFunctions } from './stepFunctions/activation' let localize: nls.LocalizeFunc export async function activate(context: vscode.ExtensionContext) { + const activationStartedOn = Date.now() + localize = nls.loadMessageBundle() ext.context = context @@ -194,6 +197,8 @@ export async function activate(context: vscode.ExtensionContext) { toastNewUser(context) await loginWithMostRecentCredentials(toolkitSettings, loginManager) + + recordToolkitInitialization(activationStartedOn, getLogger()) } catch (error) { const channelLogger = getChannelLogger(toolkitOutputChannel) channelLogger.error('AWS.channel.aws.toolkit.activation.error', 'Error Activating AWS Toolkit', error as Error) @@ -262,6 +267,19 @@ function makeEndpointsProvider(): EndpointsProvider { return provider } +function recordToolkitInitialization(activationStartedOn: number, logger?: Logger) { + try { + const activationFinishedOn = Date.now() + const duration = activationFinishedOn - activationStartedOn + + recordToolkitInit({ + duration: duration, + }) + } catch (err) { + logger?.error(err) + } +} + // Unique extension entrypoint names, so that they can be obtained from the webpack bundle export const awsToolkitActivate = activate export const awsToolkitDeactivate = deactivate From 76c88fd45f4298e4f7c878650ee957da2a360abf Mon Sep 17 00:00:00 2001 From: Garret Sweetwood Date: Thu, 11 Jun 2020 09:45:21 -0700 Subject: [PATCH 3/7] Gsweet/remove default sentiment (#1147) * Removed default sentiment from quick feedback, made it required * removed unnecessary commas * attempting to remove commas --- media/js/submitFeedbackVue.js | 10 +++++----- src/feedback/templates/feedbackTemplates.ts | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/media/js/submitFeedbackVue.js b/media/js/submitFeedbackVue.js index c725d651f9c..72481a9201e 100644 --- a/media/js/submitFeedbackVue.js +++ b/media/js/submitFeedbackVue.js @@ -5,9 +5,9 @@ console.log('Loaded!') el: '#app', data: { comment: '', - sentiment: 'Positive', + sentiment: '', isSubmitting: false, - error: '' + error: '', }, mounted() { this.$nextTick(function() { @@ -32,9 +32,9 @@ console.log('Loaded!') vscode.postMessage({ command: 'submitFeedback', comment: this.comment, - sentiment: this.sentiment + sentiment: this.sentiment, }) - } - } + }, + }, }) })() diff --git a/src/feedback/templates/feedbackTemplates.ts b/src/feedback/templates/feedbackTemplates.ts index ac669793908..24d7a39a159 100644 --- a/src/feedback/templates/feedbackTemplates.ts +++ b/src/feedback/templates/feedbackTemplates.ts @@ -30,7 +30,7 @@ export class FeedbackTemplates { Talk to us on GitHub instead!

- +
{{ error }} From 6718ae9673acafb774c81e952a73b7797fd49814 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 16 Jun 2020 16:34:14 -0700 Subject: [PATCH 4/7] build: introduce "packageAlpha" task - `npm run packageAlpha` creates an artifact that can be delivered to users for testing alpha builds. It creates artifact: aws-toolkit-vscode-1.99.0-SNAPSHOT.vsix - Show a warning message on startup if the extension version is such an alpha artifact. --- .gitignore | 1 + CONTRIBUTING.md | 18 ++++++++++++++++-- package.json | 1 + package.nls.json | 1 + src/extension.ts | 4 ++-- src/shared/extensionUtilities.ts | 28 ++++++++++++++++++++++------ src/shared/extensions.ts | 5 +++++ 7 files changed, 48 insertions(+), 10 deletions(-) diff --git a/.gitignore b/.gitignore index 8d6b3b6dedf..ef76e49c9f3 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ telemetryCache quickStart.html .gitcommit media/libs/ +package.json.bk # Auto generated definitions src/**/*.gen.ts diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index d5c78756ea4..aed6ed429f0 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -32,8 +32,22 @@ When you launch the extension or run tests from Visual Studio Code, it will auto If you prefer, you can build from the command line: -- To build one time: `npm run compile` -- To build and watch for file changes: `npm run watch` +- To build one time: + ``` + npm run compile + ``` +- To build and watch for file changes: + ``` + npm run watch + ``` +- To build a release artifact: + ``` + npm run package + ``` +- To build an "alpha" artifact (useful for letting others test a particular build): + ``` + npm run packageAlpha + ``` #### If you run out of memory while building diff --git a/package.json b/package.json index b5869f3723e..75bc2043867 100644 --- a/package.json +++ b/package.json @@ -851,6 +851,7 @@ "lint": "eslint -c .eslintrc.js --ext .ts .", "lintfix": "eslint -c .eslintrc.js --fix --ext .ts .", "package": "vsce package", + "packageAlpha": "sed -i .bk 's/\\( \"version\":\\) .*/\\1 \"1.99.0-SNAPSHOT\",/' package.json && vsce package && mv package.json.bk package.json", "install-plugin": "vsce package -o aws-toolkit-vscode-test.vsix && code --install-extension aws-toolkit-vscode-test.vsix", "generateTelemetry": "node node_modules/@aws-toolkits/telemetry/lib/generateTelemetry.js --extraInput=src/shared/telemetry/vscodeTelemetry.json --output=src/shared/telemetry/telemetry.gen.ts", "generateConfigurationAttributes": "ts-node ./build-scripts/generateConfigurationAttributes.ts", diff --git a/package.nls.json b/package.nls.json index 3b1273b0ffb..20ca041fd90 100644 --- a/package.nls.json +++ b/package.nls.json @@ -3,6 +3,7 @@ "AWS.title.createCredentialProfile": "Create a new AWS credential profile", "AWS.title.creatingCredentialProfile": "Saving new credential profile {0}", "AWS.title.selectCredentialProfile": "Select an AWS credential profile", + "AWS.startup.toastIfAlpha": "AWS Toolkit PREVIEW. (To get the latest STABLE version, uninstall this version.)", "AWS.cdk.explorerTitle": "AWS CDK Explorer (Preview)", "Aws.cdk.explorerNode.noApps": "[No CDK Apps found in Workspaces]", "Aws.cdk.explorerNode.app.noConstructTree": "[Unable to load construct tree for this App. Run `cdk synth`]", diff --git a/src/extension.ts b/src/extension.ts index 9f8bbef86b6..d1a48ae5161 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -33,7 +33,7 @@ import { aboutToolkit, getToolkitEnvironmentDetails, showQuickStartWebview, - toastNewUser, + showWelcomeMessage, } from './shared/extensionUtilities' import { getLogger, Logger } from './shared/logger' import { activate as activateLogger } from './shared/logger/activation' @@ -194,7 +194,7 @@ export async function activate(context: vscode.ExtensionContext) { await activateStepFunctions(context, awsContext, toolkitOutputChannel) }) - toastNewUser(context) + showWelcomeMessage(context) await loginWithMostRecentCredentials(toolkitSettings, loginManager) diff --git a/src/shared/extensionUtilities.ts b/src/shared/extensionUtilities.ts index bd824f9de4c..7a5d20d734a 100644 --- a/src/shared/extensionUtilities.ts +++ b/src/shared/extensionUtilities.ts @@ -12,6 +12,7 @@ import { ext } from '../shared/extensionGlobals' import { mostRecentVersionKey, pluginVersion } from './constants' import { readFileAsString } from './filesystemUtilities' import { getLogger } from './logger' +import { VSCODE_EXTENSION_ID, EXTENSION_ALPHA_VERSION } from './extensions' const localize = nls.loadMessageBundle() @@ -156,9 +157,9 @@ export function setMostRecentVersion(context: vscode.ExtensionContext): void { } /** - * Publishes a toast with a link to the welcome page + * Shows a message with a link to the quickstart page. */ -async function promptQuickStart(): Promise { +async function showQuickstartPrompt(): Promise { const view = localize('AWS.command.quickStart', 'View Quick Start') const prompt = await vscode.window.showInformationMessage( localize( @@ -174,18 +175,33 @@ async function promptQuickStart(): Promise { } /** - * Checks if a user is new to this version - * If so, pops a toast with a link to a quick start page + * Shows a "new version" or "alpha version" message. + * + * - If extension version is "alpha", shows a warning message. + * - If extension version was not previously run on this machine, shows a toast + * with a link to the quickstart page. + * - Otherwise does nothing. * * @param context VS Code Extension Context */ -export function toastNewUser(context: vscode.ExtensionContext): void { +export function showWelcomeMessage(context: vscode.ExtensionContext): void { + const version = vscode.extensions.getExtension(VSCODE_EXTENSION_ID.awstoolkit)?.packageJSON.version + if (version === EXTENSION_ALPHA_VERSION) { + vscode.window.showWarningMessage( + localize( + 'AWS.startup.toastIfAlpha', + 'AWS Toolkit PREVIEW. (To get the latest STABLE version, uninstall this version.)' + ) + ) + return + } + try { if (isDifferentVersion(context)) { setMostRecentVersion(context) // the welcome toast should be nonblocking. // tslint:disable-next-line: no-floating-promises - promptQuickStart() + showQuickstartPrompt() } } catch (err) { // swallow error and don't block extension load diff --git a/src/shared/extensions.ts b/src/shared/extensions.ts index 642352ab5b8..345d6c4eb4f 100644 --- a/src/shared/extensions.ts +++ b/src/shared/extensions.ts @@ -7,3 +7,8 @@ export const VSCODE_EXTENSION_ID = { awstoolkit: 'amazonwebservices.aws-toolkit-vscode', python: 'ms-python.python', } + +/** + * Version of the .vsix produced by the `packageAlpha` script. + */ +export const EXTENSION_ALPHA_VERSION = '1.99.0-SNAPSHOT' From 6dccc6468c39d606107cba6bf38d6fe5e061f2bd Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Tue, 16 Jun 2020 18:08:33 -0700 Subject: [PATCH 5/7] build: cross-platform "packageAlpha" task Use typescript instead of shell so that the task runs on Windows. --- build-scripts/packageAlpha.ts | 32 ++++++++++++++++++++++++++++++++ package.json | 2 +- 2 files changed, 33 insertions(+), 1 deletion(-) create mode 100644 build-scripts/packageAlpha.ts diff --git a/build-scripts/packageAlpha.ts b/build-scripts/packageAlpha.ts new file mode 100644 index 00000000000..d30e8bb66e5 --- /dev/null +++ b/build-scripts/packageAlpha.ts @@ -0,0 +1,32 @@ +/*! + * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0 + */ + +// +// Creates an artifact that can be given to users for testing alpha builds: +// +// aws-toolkit-vscode-1.99.0-SNAPSHOT.vsix +// +// The script works like this: +// 1. temporarily change `version` in package.json +// 2. invoke `vsce package` +// 3. restore the original package.json +// + +import * as child_process from 'child_process' +import * as fs from 'fs-extra' + +const packageJsonFile = './package.json' +// Create a backup so that we can restore the original later. +fs.copyFileSync(packageJsonFile, `${packageJsonFile}.bk`) + +const packageJson = JSON.parse(fs.readFileSync('./package.json', { encoding: 'UTF-8' }).toString()) +packageJson.version = '1.99.0-SNAPSHOT' + +fs.writeFileSync(packageJsonFile, JSON.stringify(packageJson, undefined, ' ')) + +child_process.execSync(`vsce package`) + +// Restore the original package.json. +fs.copyFileSync(`${packageJsonFile}.bk`, packageJsonFile) diff --git a/package.json b/package.json index 75bc2043867..7f5518912e9 100644 --- a/package.json +++ b/package.json @@ -851,7 +851,7 @@ "lint": "eslint -c .eslintrc.js --ext .ts .", "lintfix": "eslint -c .eslintrc.js --fix --ext .ts .", "package": "vsce package", - "packageAlpha": "sed -i .bk 's/\\( \"version\":\\) .*/\\1 \"1.99.0-SNAPSHOT\",/' package.json && vsce package && mv package.json.bk package.json", + "packageAlpha": "ts-node ./build-scripts/packageAlpha.ts", "install-plugin": "vsce package -o aws-toolkit-vscode-test.vsix && code --install-extension aws-toolkit-vscode-test.vsix", "generateTelemetry": "node node_modules/@aws-toolkits/telemetry/lib/generateTelemetry.js --extraInput=src/shared/telemetry/vscodeTelemetry.json --output=src/shared/telemetry/telemetry.gen.ts", "generateConfigurationAttributes": "ts-node ./build-scripts/generateConfigurationAttributes.ts", From 5e124643aec69a3cc4c40b6c7fedcb4be10a334a Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 17 Jun 2020 15:29:28 -0700 Subject: [PATCH 6/7] build: update dependencies (#1157) fix vulnerability in transitive "minimist" dependency $ rm -rf node_modules $ npm audit fix fixed 111 of 112 vulnerabilities in 1233 scanned packages 1 vulnerability required manual review and could not be updated $ npm audit $ npm update kind-of --depth 14 --- package-lock.json | 382 ++++++++++++++++++++++++++++++---------------- package.json | 2 +- 2 files changed, 253 insertions(+), 131 deletions(-) diff --git a/package-lock.json b/package-lock.json index 1d3e80de49b..e5660511266 100644 --- a/package-lock.json +++ b/package-lock.json @@ -775,6 +775,7 @@ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", "dev": true, + "optional": true, "requires": { "micromatch": "^3.1.4", "normalize-path": "^2.1.1" @@ -784,13 +785,15 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true + "dev": true, + "optional": true }, "braces": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, + "optional": true, "requires": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -809,6 +812,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, + "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -820,6 +824,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", "dev": true, + "optional": true, "requires": { "assign-symbols": "^1.0.0", "is-extendable": "^1.0.1" @@ -830,6 +835,7 @@ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", "dev": true, + "optional": true, "requires": { "is-plain-object": "^2.0.4" } @@ -841,6 +847,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, + "optional": true, "requires": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -853,6 +860,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, + "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -864,6 +872,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, + "optional": true, "requires": { "kind-of": "^3.0.2" }, @@ -873,6 +882,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, + "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -883,13 +893,15 @@ "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true + "dev": true, + "optional": true }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", "dev": true, + "optional": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -911,6 +923,7 @@ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", "dev": true, + "optional": true, "requires": { "remove-trailing-separator": "^1.0.1" } @@ -920,6 +933,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, + "optional": true, "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" @@ -1277,8 +1291,7 @@ }, "kind-of": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "resolved": "", "dev": true } } @@ -1677,6 +1690,7 @@ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", "dev": true, + "optional": true, "requires": { "anymatch": "^2.0.0", "async-each": "^1.0.1", @@ -1697,6 +1711,7 @@ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", "dev": true, + "optional": true, "requires": { "arr-flatten": "^1.1.0", "array-unique": "^0.3.2", @@ -1715,6 +1730,7 @@ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", "dev": true, + "optional": true, "requires": { "is-extendable": "^0.1.0" } @@ -1724,6 +1740,7 @@ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", "dev": true, + "optional": true, "requires": { "extend-shallow": "^2.0.1", "is-number": "^3.0.0", @@ -1736,6 +1753,7 @@ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", "dev": true, + "optional": true, "requires": { "kind-of": "^3.0.2" } @@ -1745,6 +1763,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", "dev": true, + "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -1754,6 +1773,7 @@ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", "dev": true, + "optional": true, "requires": { "is-number": "^3.0.0", "repeat-string": "^1.6.1" @@ -1997,8 +2017,7 @@ "commander": { "version": "2.20.3", "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==" }, "commondir": { "version": "1.0.1", @@ -3447,8 +3466,7 @@ }, "kind-of": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "resolved": "", "dev": true } } @@ -3993,13 +4011,6 @@ "concat-map": "0.0.1" } }, - "chownr": { - "version": "1.1.1", - "resolved": false, - "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", - "dev": true, - "optional": true - }, "code-point-at": { "version": "1.1.0", "resolved": false, @@ -4059,16 +4070,6 @@ "dev": true, "optional": true }, - "fs-minipass": { - "version": "1.2.5", - "resolved": false, - "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, "fs.realpath": { "version": "1.0.0", "resolved": false, @@ -4188,41 +4189,20 @@ } }, "minimist": { - "version": "0.0.8", - "resolved": false, - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true, "optional": true }, - "minipass": { - "version": "2.3.5", - "resolved": false, - "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "resolved": false, - "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, "mkdirp": { - "version": "0.5.1", - "resolved": false, - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "optional": true, "requires": { - "minimist": "0.0.8" + "minimist": "^1.2.5" } }, "ms": { @@ -4382,9 +4362,9 @@ }, "dependencies": { "minimist": { - "version": "1.2.0", - "resolved": false, - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true, "optional": true } @@ -4497,22 +4477,6 @@ "dev": true, "optional": true }, - "tar": { - "version": "4.4.8", - "resolved": false, - "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, "util-deprecate": { "version": "1.0.2", "resolved": false, @@ -4536,13 +4500,6 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true, "optional": true - }, - "yallist": { - "version": "3.0.3", - "resolved": false, - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", - "dev": true, - "optional": true } } }, @@ -4644,6 +4601,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", "dev": true, + "optional": true, "requires": { "is-glob": "^3.1.0", "path-dirname": "^1.0.0" @@ -4654,6 +4612,7 @@ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", "dev": true, + "optional": true, "requires": { "is-extglob": "^2.1.0" } @@ -4758,14 +4717,22 @@ "dev": true }, "handlebars": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.3.tgz", - "integrity": "sha512-3yPecJoJHK/4c6aZhSvxOyG4vJKDshV36VHp0iVCDVh7o9w2vwi3NSnL2MMPj3YdduqaBcu7cGbggJQM0br9xA==", + "version": "4.7.6", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.6.tgz", + "integrity": "sha512-1f2BACcBfiwAfStCKZNrUCgqNZkGsAT7UM3kkYtXuLo0KnaVfjKOyf7PRzB6++aK9STyT1Pd2ZCPe3EGOXleXA==", "requires": { + "minimist": "^1.2.5", "neo-async": "^2.6.0", - "optimist": "^0.6.1", "source-map": "^0.6.1", - "uglify-js": "^3.1.4" + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + } } }, "har-schema": { @@ -6283,11 +6250,6 @@ "brace-expansion": "^1.1.7" } }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, "minipass": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.1.tgz", @@ -6332,6 +6294,36 @@ "minipass": "^3.0.0" } }, + "minizlib": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.3.3.tgz", + "integrity": "sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==", + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.9.0" + }, + "dependencies": { + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "optional": true + } + } + }, "mississippi": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", @@ -6372,11 +6364,18 @@ } }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "requires": { - "minimist": "0.0.8" + "minimist": "^1.2.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" + } } }, "mocha": { @@ -7097,15 +7096,6 @@ "format-util": "^1.0.3" } }, - "optimist": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", - "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=", - "requires": { - "minimist": "~0.0.1", - "wordwrap": "~0.0.2" - } - }, "optionator": { "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", @@ -7358,7 +7348,8 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true + "dev": true, + "optional": true }, "path-exists": { "version": "3.0.0", @@ -8565,8 +8556,7 @@ }, "kind-of": { "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "resolved": "", "dev": true } } @@ -8946,6 +8936,52 @@ "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", "dev": true }, + "tar": { + "version": "4.4.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.13.tgz", + "integrity": "sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==", + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.8.6", + "minizlib": "^1.2.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.3" + }, + "dependencies": { + "fs-minipass": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.7.tgz", + "integrity": "sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==", + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.6.0" + } + }, + "minipass": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.9.0.tgz", + "integrity": "sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "optional": true + } + } + }, "tar-stream": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.1.2.tgz", @@ -9386,21 +9422,12 @@ "dev": true }, "uglify-js": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.7.1.tgz", - "integrity": "sha512-pnOF7jY82wdIhATVn87uUY/FHU+MDUdPLkmGFvGoclQmeu229eTkbG5gjGGBi3R7UuYYSEeYXY/TTY5j2aym2g==", + "version": "3.9.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.9.4.tgz", + "integrity": "sha512-8RZBJq5smLOa7KslsNsVcSH+KOXf1uDU8yqLeNuVKwmT0T3FA0ZoXlinQfRad7SDcbZZRZE4ov+2v71EnxNyCA==", "optional": true, "requires": { - "commander": "~2.20.3", - "source-map": "~0.6.1" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "optional": true - } + "commander": "~2.20.3" } }, "underscore": { @@ -9496,7 +9523,8 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", - "dev": true + "dev": true, + "optional": true }, "uri-js": { "version": "4.2.2", @@ -9788,14 +9816,108 @@ "integrity": "sha512-/ffmsiVuPC8PsWcFkZngdpas19ABm5mh2wA7iDqcltyCTwlgZjHGeJYOXkBMo422iPwIcviOtrTCUpSfXmToLQ==" }, "watchpack": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", - "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz", + "integrity": "sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g==", "dev": true, "requires": { - "chokidar": "^2.0.2", + "chokidar": "^3.4.0", "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" + "neo-async": "^2.5.0", + "watchpack-chokidar2": "^2.0.0" + }, + "dependencies": { + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "optional": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "dev": true, + "optional": true + }, + "chokidar": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", + "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "optional": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "dev": true, + "optional": true, + "requires": { + "picomatch": "^2.2.1" + }, + "dependencies": { + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true, + "optional": true + } + } + } + } + }, + "watchpack-chokidar2": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", + "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", + "dev": true, + "optional": true, + "requires": { + "chokidar": "^2.1.8" } }, "webpack": { @@ -10564,9 +10686,9 @@ "dev": true }, "wordwrap": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", - "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" }, "worker-farm": { "version": "1.7.0", @@ -10723,9 +10845,9 @@ } }, "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", diff --git a/package.json b/package.json index 7f5518912e9..2c69a4d5085 100644 --- a/package.json +++ b/package.json @@ -924,7 +924,7 @@ "cross-spawn": "^6.0.5", "del": "^3.0.0", "fs-extra": "^8.1.0", - "handlebars": "^4.5.3", + "handlebars": "^4.7.6", "immutable": "^4.0.0-rc.12", "js-yaml": "^3.13.1", "jsonc-parser": "^2.0.2", From 267df92de6492f9486438e02410e05f12802be28 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Mon, 22 Jun 2020 10:10:01 -0700 Subject: [PATCH 7/7] disposableFiles: fix edge cases again (#1163) * disposableFiles: fix edge cases again PROBLEM: some tests implicitly depend on the global `ExtensionDisposableFiles.INSTANCE`, other tests clear it, but it is not correctly re-initialized. SOLUTION: use `clearInstance()`, and rearrange its logic to avoid a race condition. Hoist `TestExtensionDisposableFiles` into `FakeExtensionContext` so it can use `clearInstance()`. ANALYSIS: Previous attempt to fix this in f143bad38a49 was incomplete, and only "worked" by accident. Problem resurfaces in `feature/debugconfig` because it has more tests that depend on `ExtensionDisposableFiles.INSTANCE`. Rearrange `clearInstance()` so that ExtensionDisposableFiles.INSTANCE = undefined is the first step. Because `del.sync()` does file IO, node may switch to another context while it waits on the file IO. Fixes this error (among others): 1) localLambdaRunner "before all" hook in "localLambdaRunner": Error: ExtensionDisposableFiles already initialized at Function. (/Volumes/workplace/aws-toolkit-vscode/src/shared/utilities/disposableFiles.ts:78:19) at Generator.next () at /Volumes/workplace/aws-toolkit-vscode/dist/src/shared/utilities/disposableFiles.js:12:71 at new Promise () at /Volumes/workplace/aws-toolkit-vscode/dist/src/shared/utilities/disposableFiles.js:8:12 at Function.initialize (/Volumes/workplace/aws-toolkit-vscode/dist/src/shared/utilities/disposableFiles.js:79:16) at Function. (/Volumes/workplace/aws-toolkit-vscode/src/test/fakeExtensionContext.ts:72:44) at Generator.next () at /Volumes/workplace/aws-toolkit-vscode/dist/src/test/fakeExtensionContext.js:12:71 at new Promise () at /Volumes/workplace/aws-toolkit-vscode/dist/src/test/fakeExtensionContext.js:8:12 at Function.getNew (/Volumes/workplace/aws-toolkit-vscode/dist/src/test/fakeExtensionContext.js:54:16) at /Volumes/workplace/aws-toolkit-vscode/src/test/shared/codelens/localLambdaRunner.test.ts:22:36 at Generator.next () at /Volumes/workplace/aws-toolkit-vscode/dist/src/test/shared/codelens/localLambdaRunner.test.js:12:71 at new Promise () at /Volumes/workplace/aws-toolkit-vscode/dist/src/test/shared/codelens/localLambdaRunner.test.js:8:12 at Context. (/Volumes/workplace/aws-toolkit-vscode/src/test/shared/codelens/localLambdaRunner.test.ts:21:23) at processImmediate (internal/timers.js:439:21) at process.topLevelDomainCallback (domain.js:131:23) * fixup! disposableFiles: fix edge cases again --- src/shared/utilities/disposableFiles.ts | 8 +++- src/test/fakeExtensionContext.ts | 37 +++++++++++++++---- .../shared/utilities/disposableFiles.test.ts | 17 +-------- 3 files changed, 37 insertions(+), 25 deletions(-) diff --git a/src/shared/utilities/disposableFiles.ts b/src/shared/utilities/disposableFiles.ts index 069e87ad816..874949b5eae 100644 --- a/src/shared/utilities/disposableFiles.ts +++ b/src/shared/utilities/disposableFiles.ts @@ -26,6 +26,10 @@ export class DisposableFiles implements vscode.Disposable { return this } + public isDisposed(): boolean { + return this._disposed + } + public dispose(): void { const logger: Logger = getLogger() if (!this._disposed) { @@ -70,7 +74,7 @@ export class ExtensionDisposableFiles extends DisposableFiles { } public static async initialize(extensionContext: vscode.ExtensionContext): Promise { - if (!!ExtensionDisposableFiles.INSTANCE) { + if (ExtensionDisposableFiles.INSTANCE && !ExtensionDisposableFiles.INSTANCE.isDisposed()) { throw new Error('ExtensionDisposableFiles already initialized') } @@ -82,7 +86,7 @@ export class ExtensionDisposableFiles extends DisposableFiles { } public static getInstance(): ExtensionDisposableFiles { - if (!ExtensionDisposableFiles.INSTANCE) { + if (!ExtensionDisposableFiles.INSTANCE || ExtensionDisposableFiles.INSTANCE.isDisposed()) { throw new Error('ExtensionDisposableFiles not initialized') } diff --git a/src/test/fakeExtensionContext.ts b/src/test/fakeExtensionContext.ts index 1dad7efbc75..9771d439e33 100644 --- a/src/test/fakeExtensionContext.ts +++ b/src/test/fakeExtensionContext.ts @@ -3,7 +3,8 @@ * SPDX-License-Identifier: Apache-2.0 */ -import { ExtensionContext, Memento } from 'vscode' +import * as vscode from 'vscode' +import * as del from 'del' import { ExtensionDisposableFiles } from '../shared/utilities/disposableFiles' export interface FakeMementoStorage { @@ -15,12 +16,12 @@ export interface FakeExtensionState { workspaceState?: FakeMementoStorage } -export class FakeExtensionContext implements ExtensionContext { +export class FakeExtensionContext implements vscode.ExtensionContext { public subscriptions: { dispose(): any }[] = [] - public workspaceState: Memento = new FakeMemento() - public globalState: Memento = new FakeMemento() + public workspaceState: vscode.Memento = new FakeMemento() + public globalState: vscode.Memento = new FakeMemento() public storagePath: string | undefined public globalStoragePath: string = '.' public logPath: string = '' @@ -54,15 +55,37 @@ export class FakeExtensionContext implements ExtensionContext { public static async getNew(): Promise { const ctx = new FakeExtensionContext() try { - ExtensionDisposableFiles.getInstance().dispose() + TestExtensionDisposableFiles.clearInstance() } catch { - await ExtensionDisposableFiles.initialize(ctx) + // Ignore. } + await TestExtensionDisposableFiles.initialize(ctx) return ctx } } -class FakeMemento implements Memento { +export class TestExtensionDisposableFiles extends ExtensionDisposableFiles { + public static ORIGINAL_INSTANCE = ExtensionDisposableFiles.INSTANCE + + public static clearInstance() { + // XXX: INSTANCE=undefined is done first, to avoid a race: + // 1. del.sync() does file IO + // 2. the Node scheduler looks for pending handlers to execute while waiting on IO + // 3. other async handlers may try to use ExtensionDisposableFiles.getInstance() + const instance = ExtensionDisposableFiles.INSTANCE + ExtensionDisposableFiles.INSTANCE = undefined + if (instance) { + del.sync([instance.toolkitTempFolder], { force: true }) + instance.dispose() + } + } + + public static resetOriginalInstance() { + ExtensionDisposableFiles.INSTANCE = TestExtensionDisposableFiles.ORIGINAL_INSTANCE + } +} + +class FakeMemento implements vscode.Memento { public constructor(private readonly _storage: FakeMementoStorage = {}) {} public get(key: string): T | undefined public get(key: string, defaultValue: T): T diff --git a/src/test/shared/utilities/disposableFiles.test.ts b/src/test/shared/utilities/disposableFiles.test.ts index 63bc41387ce..a9c1bc956ac 100644 --- a/src/test/shared/utilities/disposableFiles.test.ts +++ b/src/test/shared/utilities/disposableFiles.test.ts @@ -11,6 +11,7 @@ import * as vscode from 'vscode' import { mkdir } from '../../../shared/filesystem' import { fileExists, makeTemporaryToolkitFolder } from '../../../shared/filesystemUtilities' import { DisposableFiles, ExtensionDisposableFiles } from '../../../shared/utilities/disposableFiles' +import { TestExtensionDisposableFiles } from '../../fakeExtensionContext' describe('DisposableFiles', async () => { let tempFolder: string @@ -87,22 +88,6 @@ describe('DisposableFiles', async () => { }) describe('ExtensionDisposableFiles', async () => { - class TestExtensionDisposableFiles extends ExtensionDisposableFiles { - public static ORIGINAL_INSTANCE = ExtensionDisposableFiles.INSTANCE - - public static clearInstance() { - if (ExtensionDisposableFiles.INSTANCE) { - del.sync([ExtensionDisposableFiles.INSTANCE.toolkitTempFolder], { force: true }) - } - - ExtensionDisposableFiles.INSTANCE = undefined - } - - public static resetOriginalInstance() { - ExtensionDisposableFiles.INSTANCE = TestExtensionDisposableFiles.ORIGINAL_INSTANCE - } - } - let extensionContext: vscode.ExtensionContext beforeEach(() => {