Compare commits

...

25 Commits

Author SHA1 Message Date
jcreedcmu
07f96bf43e Merge pull request #178 from adityasharad/add-changelog
Some checks failed
Build Extension / Build (ubuntu-latest) (push) Has been cancelled
Build Extension / Build (windows-latest) (push) Has been cancelled
Build Extension / Test (ubuntu-latest) (push) Has been cancelled
Build Extension / Test (windows-latest) (push) Has been cancelled
Release / Release (push) Has been cancelled
Add changelog.
2019-11-21 13:21:33 -05:00
Aditya Sharad
5d8e12865d Add changelog. 2019-11-21 10:11:04 -08:00
Alexander Eyers-Taylor
36fedac2ca Merge pull request #174 from henrymercer/settings-scope
Change distribution settings to machine scope
2019-11-21 15:10:03 +00:00
Henry Mercer
8400f75bb5 Change distribution settings to machine scope 2019-11-21 12:43:54 +00:00
jcreedcmu
a5594043e1 Merge pull request #164 from asgerf/asgerf/decorate-selected-path-node
Add decoration to focused item
2019-11-20 09:04:23 -05:00
Asger F
1fc5e77de6 Fix typo in comment 2019-11-20 11:13:45 +00:00
Asger F
0c45210021 Treat single-line and multi-line ranges differently 2019-11-20 10:22:56 +00:00
Aditya Sharad
4287f4d01b Merge pull request #169 from jcreedcmu/no-selected-class
Simplify selected results table handling
2019-11-19 08:47:42 -08:00
Aditya Sharad
cfcbdcd3d0 Merge pull request #170 from jcreedcmu/fix-upgrades
Fix auto-upgrade script path
2019-11-18 13:08:27 -08:00
Jason Reed
a1f0af9086 Fix auto-upgrade script path
This was a simple case of passing entirely the wrong data as an
argument to the `upgradeDatabase` call in `queries.ts`. We were
passing the list of search paths for upgrades, when we should have
been passing the list of directories directly containing upgrade
scripts to be applied.
2019-11-18 15:56:45 -05:00
Jason Reed
155a235cf1 Simplify selected results table handling
We don't need to render all tables and use css to hide the ones we
don't currently want to see. Instead have `render` return the dom that
should be visible given the current state.
2019-11-18 09:20:32 -05:00
Aditya Sharad
1dffeb97d3 Merge pull request #167 from dbartol/dbartol/version
A few versioning fixes
2019-11-15 15:05:41 -08:00
Dave Bartolomeo
27c171c5c9 Add missing escape 2019-11-15 15:07:58 -07:00
Aditya Sharad
d29f7492a8 Merge pull request #166 from shati-patel/docs/anchor
Readme: Fix anchor link
2019-11-15 13:13:50 -08:00
Dave Bartolomeo
822b565d6f A few versioning fixes
- Bumps the version of the extension to 1.0.1. We should bump the version immediately after every official release, so that any builds that happen after the release are treated as prerelease versions of the next release.

- Separates the components of the timestamp in the version number for non-release builds. This just makes it easier to read. I also left off the milliseconds, which were kind of overkill, and switched to using UTC time to avoid time-zone ambiguity.

- Updates the version number in the copy of the extension's `package.json` that winds up in the actual .vsix, so VS Code actually sees the version as being the proper prelease version.
2019-11-15 13:24:37 -07:00
shati-patel
5f90ea5304 Readme: Fix anchor link 2019-11-15 18:15:03 +00:00
Dave Bartolomeo
f1e44ef7f3 Merge pull request #165 from jcreedcmu/remove-items
Allow removing items from query history
2019-11-15 11:08:36 -07:00
Jason Reed
0e53afc19b Allow removing items from query history 2019-11-15 09:27:29 -05:00
Alexander Eyers-Taylor
a5da556496 Merge pull request #163 from henrymercer/remove-dead-code
Remove dead code from archive filesystem provider
2019-11-15 13:38:19 +00:00
Henry Mercer
76531a0cfc Remove dead code from archive filesystem provider 2019-11-15 11:54:42 +00:00
Asger F
4f8b12b13a Add decoration to focused item 2019-11-15 11:53:31 +00:00
Alexander Eyers-Taylor
9e9b49c1e3 Merge pull request #162 from henrymercer/remove-cast-after-fixed-typedef
Remove cast now unzipper typedef fix is merged
2019-11-15 10:58:58 +00:00
Henry Mercer
59e0ceec9a Remove cast now unzipper typedef fix is merged
Related PR fixing typedef: DefinitelyTyped/DefinitelyTyped#40240
2019-11-15 10:14:39 +00:00
Aditya Sharad
69b0dd7eb3 Merge pull request #161 from dbartol/dbartol/TypeScript37
Update to TypeScript 3.7.2
2019-11-14 14:41:12 -08:00
Dave Bartolomeo
b6e7fb1219 Update to TypeScript 3.7.2 2019-11-14 14:45:40 -07:00
20 changed files with 234 additions and 181 deletions

14
CHANGELOG.md Normal file
View File

@@ -0,0 +1,14 @@
# CodeQL for Visual Studio Code: Changelog
## 1.0.1 - 21 November 2019
- Change `codeQL.cli.executablePath` to a per-machine setting, so it can no longer be set at the user or workspace level. This helps prevent arbitrary code execution when using a VS Code workspace from an untrusted source.
- Improve the highlighting of the selected query result within the source code.
- Improve the performance of switching between result tables in the CodeQL Query Results view.
- Fix the automatic upgrading of CodeQL databases when using upgrade scripts from the workspace.
- Allow removal of items from the CodeQL Query History view.
## 1.0.0 - 14 November 2019
Initial release of CodeQL for Visual Studio Code.

View File

@@ -26,7 +26,7 @@ dependencies:
'@types/sarif': 2.1.2
'@types/through2': 2.0.34
'@types/tmp': 0.1.0
'@types/unzipper': 0.10.0
'@types/unzipper': 0.10.1
'@types/vinyl': 2.0.3
'@types/vscode': 1.39.0
'@types/webpack': 4.32.1
@@ -39,7 +39,6 @@ dependencies:
fs-extra: 8.1.0
glob: 7.1.4
glob-promise: 3.4.0
google-protobuf: 3.9.1
gulp: 4.0.2
gulp-sourcemaps: 2.6.5
gulp-typescript: 5.0.1
@@ -54,14 +53,13 @@ dependencies:
react: 16.8.6
react-dom: 16.8.6
reflect-metadata: 0.1.13
resolve: 1.11.1
style-loader: 0.23.1
through2: 3.0.1
tmp: 0.1.0
ts-loader: 5.4.5
ts-node: 8.3.0
ts-protoc-gen: 0.9.0
typescript: 3.5.3
typescript: 3.7.2
typescript-formatter: 7.2.2
unzipper: 0.10.5
vinyl: 2.2.0
@@ -71,7 +69,6 @@ dependencies:
vscode-test: 1.2.0
webpack: 4.39.1
webpack-cli: 3.3.6
xml2js: 0.4.19
packages:
/@gulp-sourcemaps/identity-map/1.0.2:
dependencies:
@@ -339,6 +336,10 @@ packages:
dev: false
resolution:
integrity: sha512-dsfE4BHJkLQW+reOS6b17xhZ/6FB1rB8eRRvO08nn5o+voxf3i74tuyFWNH6djdfgX7Sm5s6LD8t6mJug4dpDw==
/@types/node/12.12.7:
dev: false
resolution:
integrity: sha512-E6Zn0rffhgd130zbCbAr/JdXfXkoOUFAKNs/rF8qnafSJ8KYaA/j3oz7dcwal+lYjLA7xvdd5J4wdYpCTlP8+w==
/@types/node/12.7.0:
dev: false
resolution:
@@ -516,12 +517,12 @@ packages:
dev: false
resolution:
integrity: sha512-j4iepCSuY2JGW/hShVtUBagic0klYNFIXP7VweavnYnNC2EjiKxJFeaS9uaJmAT0ty9sQSqTS1aagWMZMV0HyA==
/@types/unzipper/0.10.0:
/@types/unzipper/0.10.1:
dependencies:
'@types/node': 12.11.2
'@types/node': 12.12.7
dev: false
resolution:
integrity: sha512-GZL5vt0o9ZAST+7ge1Sirzc14EEJFbq6kib24nS0UglY6BHX8ERhA8cBq4XsYWcGK212FtMBZyJz6AwPvrhGLQ==
integrity: sha512-I53zUuPGMR/ry/s61qdlk/NkJHwhekycCqI7IXWFcJHOK+oIFUhnCPT26Wbf4UYNLpFjeujFioXGH+SWY4yUUQ==
/@types/vinyl-fs/2.4.11:
dependencies:
'@types/glob-stream': 6.1.0
@@ -2751,13 +2752,13 @@ packages:
typescript: ~2.7.1 || >=2.8.0-dev || >=2.9.0-dev || ~3.0.0 || >=3.0.0-dev || >=3.1.0-dev || >= 3.2.0-dev || >= 3.3.0-dev
resolution:
integrity: sha512-YuMMlylyJtUSHG1/wuSVTrZp60k1dMEFKYOvDf7OvbAJWrDtxxD4oZon4ancdWwzjj30ztiidhe4VXJniF0pIQ==
/gulp-typescript/5.0.1/typescript@3.5.3:
/gulp-typescript/5.0.1/typescript@3.7.2:
dependencies:
ansi-colors: 3.2.4
plugin-error: 1.0.1
source-map: 0.7.3
through2: 3.0.1
typescript: 3.5.3
typescript: 3.7.2
vinyl: 2.2.0
vinyl-fs: 3.0.3
dev: false
@@ -5705,14 +5706,14 @@ packages:
typescript: '*'
resolution:
integrity: sha512-XYsjfnRQCBum9AMRZpk2rTYSVpdZBpZK+kDh0TeT3kxmQNBDVIeUjdPjY5RZry4eIAb8XHc4gYSUiUWPYvzSRw==
/ts-loader/5.4.5/typescript@3.5.3:
/ts-loader/5.4.5/typescript@3.7.2:
dependencies:
chalk: 2.4.2
enhanced-resolve: 4.1.0
loader-utils: 1.2.3
micromatch: 3.1.10
semver: 5.7.0
typescript: 3.5.3
typescript: 3.7.2
dev: false
engines:
node: '>=6.11.5'
@@ -5736,13 +5737,13 @@ packages:
typescript: '>=2.0'
resolution:
integrity: sha512-dyNS/RqyVTDcmNM4NIBAeDMpsAdaQ+ojdf0GOLqE6nwJOgzEkdRNzJywhDfwnuvB10oa6NLVG1rUJQCpRN7qoQ==
/ts-node/8.3.0/typescript@3.5.3:
/ts-node/8.3.0/typescript@3.7.2:
dependencies:
arg: 4.1.1
diff: 4.0.1
make-error: 1.3.5
source-map-support: 0.5.13
typescript: 3.5.3
typescript: 3.7.2
yn: 3.1.1
dev: false
engines:
@@ -5805,11 +5806,11 @@ packages:
typescript: ^2.1.6 || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev
resolution:
integrity: sha512-V7vfI9XArVhriOTYHPzMU2WUnm5IMdu9X/CPxs8mIMGxmTBFpDABlbkBka64PZJ9/xgQeRpK8KzzAG4MPzxBDQ==
/typescript-formatter/7.2.2/typescript@3.5.3:
/typescript-formatter/7.2.2/typescript@3.7.2:
dependencies:
commandpost: 1.4.0
editorconfig: 0.15.3
typescript: 3.5.3
typescript: 3.7.2
dev: false
engines:
node: '>= 4.2.0'
@@ -5819,13 +5820,13 @@ packages:
typescript: ^2.1.6 || >=2.7.0-dev || >=2.8.0-dev || >=2.9.0-dev || >=3.0.0-dev
resolution:
integrity: sha512-V7vfI9XArVhriOTYHPzMU2WUnm5IMdu9X/CPxs8mIMGxmTBFpDABlbkBka64PZJ9/xgQeRpK8KzzAG4MPzxBDQ==
/typescript/3.5.3:
/typescript/3.7.2:
dev: false
engines:
node: '>=4.2.0'
hasBin: true
resolution:
integrity: sha512-ACzBtm/PhXBDId6a6sDJfroT2pOWt/oOnk4/dElG5G33ZL776N3Y6/6bKZJBFpd+b05F3Ct9qDjMeJmRWtE2/g==
integrity: sha512-ml7V7JfiN2Xwvcer+XAf2csGO1bPBdRbFCkYBczNZggrBZ9c7G3riSUeJmqEU5uOtXNPMhE3n+R4FA/3YOAWOQ==
/uc.micro/1.0.6:
dev: false
resolution:
@@ -6432,23 +6433,23 @@ packages:
child-process-promise: 2.2.1
fs-extra: 8.1.0
glob: 7.1.4
glob-promise: /glob-promise/3.4.0/glob@7.1.4
glob-promise: 3.4.0
gulp: 4.0.2
gulp-sourcemaps: 2.6.5
gulp-typescript: /gulp-typescript/5.0.1/typescript@3.5.3
gulp-typescript: /gulp-typescript/5.0.1/typescript@3.7.2
js-yaml: 3.13.1
jsonc-parser: 2.1.0
npm-packlist: 1.4.4
plugin-error: 1.0.1
resolve: 1.11.1
through2: 3.0.1
typescript: 3.5.3
typescript-formatter: /typescript-formatter/7.2.2/typescript@3.5.3
typescript: 3.7.2
typescript-formatter: /typescript-formatter/7.2.2/typescript@3.7.2
vinyl: 2.2.0
dev: false
name: '@rush-temp/build-tasks'
resolution:
integrity: sha512-BUyDoHgX1TYQw+gqSHLp/jt669EpGoAxdYk7xJsUQ4LKBumy0+nMRtj/nUhluUP4o8PTAOh8JXhOEPYHmvWpNA==
integrity: sha512-ta2kXnX7phnKrO7rxdJl5A9Vtd8B4RDyoae3vhdI1d+COeITaXDd9xdPxo8lvduPSJTw2+HnzOgOu2pMAKSjTw==
tarball: 'file:projects/build-tasks.tgz'
version: 0.0.0
'file:projects/semmle-bqrs.tgz':
@@ -6460,7 +6461,7 @@ packages:
dev: false
name: '@rush-temp/semmle-bqrs'
resolution:
integrity: sha512-sQXalSHsqeFO2hKsaWCj2rZYQmMc28YMnNmG1VTcvc/v8trkJQSqCZs1J7rgZpG+Uj05s5iBbgAa1C0uAXtgbw==
integrity: sha512-24GdnvMbGfQIWMfgDhift+kYJDnG7dX03NrpX4ajZ2rckteysvq2/K7XI1OXGvUuqrt3m0/+GRDHpSI9XKDJJA==
tarball: 'file:projects/semmle-bqrs.tgz'
version: 0.0.0
'file:projects/semmle-io-node.tgz':
@@ -6472,7 +6473,7 @@ packages:
dev: false
name: '@rush-temp/semmle-io-node'
resolution:
integrity: sha512-MD9edC5HjrCfPmhktw6XmWotUmperj27/hDZiuMbuSlJ4jRKyiBtJ8Vk2Y4U41TrzsBlJfAwZW8tetPw5ujiLg==
integrity: sha512-Bj0ax/bASrHV7tamOuXZZdd3UOB4NBKdjdszIRaDvDRTu8RlEst+TVoUhkfy30qb2/6ePp3/juOJyyiBJN7u8Q==
tarball: 'file:projects/semmle-io-node.tgz'
version: 0.0.0
'file:projects/semmle-io.tgz':
@@ -6483,26 +6484,26 @@ packages:
dev: false
name: '@rush-temp/semmle-io'
resolution:
integrity: sha512-ta1lLi1COIeFwpwH523cWheWx6OE8GTqguQmOA7G6CwRF41RYbbREf/4KlOLKO/uG2akhhl+3gcWY2c5/VDC/A==
integrity: sha512-NtyviDSevxbd+hj4J66LucOzo8LU2hJ1Jh0eHw0Qu3tRZPUT8HcQlseyy29AvZR8n8eppfEZiAm/JdiHfmRPMA==
tarball: 'file:projects/semmle-io.tgz'
version: 0.0.0
'file:projects/semmle-vscode-utils.tgz':
dependencies:
'@types/node': 12.7.0
'@types/vscode': 1.39.0
typescript: 3.5.3
typescript-formatter: /typescript-formatter/7.2.2/typescript@3.5.3
typescript: 3.7.2
typescript-formatter: /typescript-formatter/7.2.2/typescript@3.7.2
dev: false
name: '@rush-temp/semmle-vscode-utils'
resolution:
integrity: sha512-Q4k2As+HBO0XM+/LuwUHc8BNAXoDNadmrxy3nlVmvv5UTq8oTsRR2l58GzFxcjS2IDTW1x2o+GYA+PfwXsC34Q==
integrity: sha512-5y5r8SDoN9Fp44naC9gUe8rOexeckXg2T0h9QCJAIcEgnFqOxzRc6Rv9gbMUStFKNh+rFlvmYmgPAdg5QkfgUg==
tarball: 'file:projects/semmle-vscode-utils.tgz'
version: 0.0.0
'file:projects/typescript-config.tgz':
dev: false
name: '@rush-temp/typescript-config'
resolution:
integrity: sha512-qJbtY2jvt6LKkmUt/seiYyXSEB6Oip/rW+SxofQEnpyplgIQv7whTZb6g5pwlSLGl8goTaQFm4NfazKhFmxXvQ==
integrity: sha512-XuUIySaNoooIduvehnlKYaHqZJmmQoCqB1RtKhNszjCYZaSSJAnKVucViWBf5oNLKSNP7NchrD7gcoBlQ3xYvw==
tarball: 'file:projects/typescript-config.tgz'
version: 0.0.0
'file:projects/vscode-codeql.tgz':
@@ -6521,7 +6522,7 @@ packages:
'@types/react-dom': 16.8.5
'@types/sarif': 2.1.2
'@types/tmp': 0.1.0
'@types/unzipper': 0.10.0
'@types/unzipper': 0.10.1
'@types/vscode': 1.39.0
'@types/webpack': 4.32.1
'@types/xml2js': 0.4.4
@@ -6535,7 +6536,7 @@ packages:
google-protobuf: 3.9.1
gulp: 4.0.2
gulp-sourcemaps: 2.6.5
gulp-typescript: /gulp-typescript/5.0.1/typescript@3.5.3
gulp-typescript: /gulp-typescript/5.0.1/typescript@3.7.2
js-yaml: 3.13.1
jszip: 3.2.2
leb: 0.3.0
@@ -6547,11 +6548,11 @@ packages:
style-loader: 0.23.1
through2: 3.0.1
tmp: 0.1.0
ts-loader: /ts-loader/5.4.5/typescript@3.5.3
ts-node: /ts-node/8.3.0/typescript@3.5.3
ts-loader: /ts-loader/5.4.5/typescript@3.7.2
ts-node: /ts-node/8.3.0/typescript@3.7.2
ts-protoc-gen: 0.9.0
typescript: 3.5.3
typescript-formatter: /typescript-formatter/7.2.2/typescript@3.5.3
typescript: 3.7.2
typescript-formatter: /typescript-formatter/7.2.2/typescript@3.7.2
unzipper: 0.10.5
vinyl: 2.2.0
vsce: 1.66.0
@@ -6564,7 +6565,7 @@ packages:
dev: false
name: '@rush-temp/vscode-codeql'
resolution:
integrity: sha512-3CqFyt5JivXlc2/dJaWxAsgt+IQAJ0GaYvCD9JNyobV2gvB3jlODLgYKtnO3OL56QgBDNVdi5nHhtNst1BSZJQ==
integrity: sha512-DE97bdxda65gVLZne73QzBpj2hyCbyzvQiRZxrJqDP1rkF62EGNohBSmlEQs8H2Jp8hxh5RhPhm/yUx70G7KEA==
tarball: 'file:projects/vscode-codeql.tgz'
version: 0.0.0
registry: 'https://registry.npmjs.org/'
@@ -6598,7 +6599,7 @@ specifiers:
'@types/sarif': ~2.1.2
'@types/through2': ~2.0.34
'@types/tmp': ^0.1.0
'@types/unzipper': ~0.10.0
'@types/unzipper': ~0.10.1
'@types/vinyl': ~2.0.3
'@types/vscode': ^1.39.0
'@types/webpack': ^4.32.1
@@ -6611,7 +6612,6 @@ specifiers:
fs-extra: ^8.1.0
glob: ^7.1.4
glob-promise: ^3.4.0
google-protobuf: ^3.7.1
gulp: ^4.0.2
gulp-sourcemaps: ^2.6.5
gulp-typescript: ^5.0.1
@@ -6626,14 +6626,13 @@ specifiers:
react: ^16.8.6
react-dom: ^16.8.6
reflect-metadata: ~0.1.13
resolve: ~1.11.1
style-loader: ~0.23.1
through2: ^3.0.1
tmp: ^0.1.0
ts-loader: ^5.4.5
ts-node: ^8.3.0
ts-protoc-gen: ^0.9.0
typescript: ^3.5.2
typescript: ^3.7.2
typescript-formatter: ^7.2.2
unzipper: ~0.10.5
vinyl: ^2.2.0
@@ -6643,4 +6642,3 @@ specifiers:
vscode-test: ^1.0.0
webpack: ^4.38.0
webpack-cli: ^3.3.2
xml2js: ~0.4.19

View File

@@ -20,7 +20,7 @@ For information about other configurations, see the separate [CodeQL help](https
**Quick start: Using CodeQL**
1. [Import a database from LGTM.com](#importing-a-database-from-lgtmcom).
1. [Import a database from LGTM](#importing-a-database-from-lgtm).
1. [Run a query](#running-a-query).
-----
@@ -56,7 +56,7 @@ For information about configuring an existing workspace for CodeQL, [see the doc
You can find all the commands contributed by the extension in the Command Palette (**Ctrl+Shift+P** or **Cmd+Shift+P**) by typing `CodeQL`, many of them are also accessible through the interface, and via keyboard shortcuts.
### Importing a database from LGTM.com
### Importing a database from LGTM
While you can use the [CodeQL CLI to create your own databases](https://help.semmle.com/codeql/codeql-cli/procedures/create-codeql-database.html), the simplest way to start is by downloading a database from LGTM.com.

View File

@@ -4,7 +4,7 @@
"description": "CodeQL for Visual Studio Code",
"author": "GitHub",
"private": true,
"version": "1.0.0",
"version": "1.0.1",
"publisher": "GitHub",
"license": "MIT",
"icon": "media/VS-marketplace-CodeQL-icon.png",
@@ -82,7 +82,7 @@
"title": "CodeQL",
"properties": {
"codeQL.cli.executablePath": {
"scope": "window",
"scope": "machine",
"type": "string",
"default": "",
"description": "Path to the CodeQL executable that should be used by the CodeQL extension. The executable is named `codeql` on Linux/Mac and `codeql.cmd` on Windows. This overrides all other CodeQL CLI settings."
@@ -161,7 +161,11 @@
},
{
"command": "codeQLQueryHistory.openQuery",
"title": "CodeQL: Open Query"
"title": "Open Query"
},
{
"command": "codeQLQueryHistory.removeHistoryItem",
"title": "Remove History Item"
},
{
"command": "codeQLQueryHistory.itemClicked",
@@ -196,6 +200,11 @@
"command": "codeQLQueryHistory.openQuery",
"group": "9_qlCommands",
"when": "view == codeQLQueryHistory"
},
{
"command": "codeQLQueryHistory.removeHistoryItem",
"group": "9_qlCommands",
"when": "view == codeQLQueryHistory"
}
],
"explorer/context": [
@@ -235,6 +244,10 @@
"command": "codeQLQueryHistory.openQuery",
"when": "false"
},
{
"command": "codeQLQueryHistory.removeHistoryItem",
"when": "false"
},
{
"command": "codeQLQueryHistory.itemClicked",
"when": "false"
@@ -314,7 +327,7 @@
"@types/react-dom": "^16.8.4",
"@types/sarif": "~2.1.2",
"@types/tmp": "^0.1.0",
"@types/unzipper": "~0.10.0",
"@types/unzipper": "~0.10.1",
"@types/vscode": "^1.39.0",
"@types/webpack": "^4.32.1",
"@types/xml2js": "~0.4.4",
@@ -333,7 +346,7 @@
"ts-loader": "^5.4.5",
"ts-node": "^8.3.0",
"ts-protoc-gen": "^0.9.0",
"typescript": "^3.5.2",
"typescript": "^3.7.2",
"typescript-config": "^0.0.1",
"typescript-formatter": "^7.2.2",
"vsce": "^1.65.0",

View File

@@ -238,14 +238,6 @@ export class ArchiveFileSystemProvider implements vscode.FileSystemProvider {
throw vscode.FileSystemError.FileNotFound(uri);
}
private async _lookupAsDirectory(uri: vscode.Uri, silent: boolean): Promise<Directory> {
let entry = await this._lookup(uri, silent);
if (entry instanceof Directory) {
return entry;
}
throw vscode.FileSystemError.FileNotADirectory(uri);
}
private async _lookupAsFile(uri: vscode.Uri, silent: boolean): Promise<File> {
let entry = await this._lookup(uri, silent);
if (entry instanceof File) {
@@ -254,16 +246,9 @@ export class ArchiveFileSystemProvider implements vscode.FileSystemProvider {
throw vscode.FileSystemError.FileIsADirectory(uri);
}
private _lookupParentDirectory(uri: vscode.Uri): Promise<Directory> {
const dirname = uri.with({ path: path.dirname(uri.path) });
return this._lookupAsDirectory(dirname, false);
}
// file events
private _emitter = new vscode.EventEmitter<vscode.FileChangeEvent[]>();
private _bufferedEvents: vscode.FileChangeEvent[] = [];
private _fireSoonHandle?: NodeJS.Timer;
readonly onDidChangeFile: vscode.Event<vscode.FileChangeEvent[]> = this._emitter.event;
@@ -271,19 +256,6 @@ export class ArchiveFileSystemProvider implements vscode.FileSystemProvider {
// ignore, fires for all changes...
return new vscode.Disposable(() => { });
}
private _fireSoon(...events: vscode.FileChangeEvent[]): void {
this._bufferedEvents.push(...events);
if (this._fireSoonHandle) {
clearTimeout(this._fireSoonHandle);
}
this._fireSoonHandle = setTimeout(() => {
this._emitter.fire(this._bufferedEvents);
this._bufferedEvents.length = 0;
}, 5);
}
}
/**

View File

@@ -37,18 +37,16 @@ const DISTRIBUTION_SETTING = new Setting('cli', ROOT_SETTING);
const CUSTOM_CODEQL_PATH_SETTING = new Setting('executablePath', DISTRIBUTION_SETTING);
const INCLUDE_PRERELEASE_SETTING = new Setting('includePrerelease', DISTRIBUTION_SETTING);
const PERSONAL_ACCESS_TOKEN_SETTING = new Setting('personalAccessToken', DISTRIBUTION_SETTING);
const OWNER_NAME_SETTING = new Setting('owner', DISTRIBUTION_SETTING);
const REPOSITORY_NAME_SETTING = new Setting('repository', DISTRIBUTION_SETTING);
/** When these settings change, the distribution should be updated. */
const DISTRIBUTION_CHANGE_SETTINGS = [CUSTOM_CODEQL_PATH_SETTING, INCLUDE_PRERELEASE_SETTING, PERSONAL_ACCESS_TOKEN_SETTING, OWNER_NAME_SETTING, REPOSITORY_NAME_SETTING];
const DISTRIBUTION_CHANGE_SETTINGS = [CUSTOM_CODEQL_PATH_SETTING, INCLUDE_PRERELEASE_SETTING, PERSONAL_ACCESS_TOKEN_SETTING];
export interface DistributionConfig {
customCodeQlPath?: string;
includePrerelease: boolean;
personalAccessToken?: string;
ownerName: string;
repositoryName: string;
ownerName?: string;
repositoryName?: string;
onDidChangeDistributionConfiguration?: Event<void>;
}
@@ -114,14 +112,6 @@ export class DistributionConfigListener extends ConfigListener implements Distri
return PERSONAL_ACCESS_TOKEN_SETTING.getValue() ? PERSONAL_ACCESS_TOKEN_SETTING.getValue() : undefined;
}
public get ownerName(): string {
return OWNER_NAME_SETTING.getValue();
}
public get repositoryName(): string {
return REPOSITORY_NAME_SETTING.getValue();
}
public get onDidChangeDistributionConfiguration(): Event<void> {
return this._onDidChangeConfiguration.event;
}

View File

@@ -2,7 +2,7 @@ import * as path from 'path';
import { DisposableObject } from "semmle-vscode-utils";
import { commands, Event, EventEmitter, ExtensionContext, ProviderResult, TreeDataProvider, TreeItem, Uri, window } from "vscode";
import * as cli from './cli';
import { DatabaseItem, DatabaseManager } from "./databases";
import { DatabaseItem, DatabaseManager, getUpgradesDirectories } from "./databases";
import { logger } from "./logging";
import { clearCacheInDatabase, upgradeDatabase, UserCancellationException } from "./queries";
import * as qsClient from './queryserver-client';
@@ -189,15 +189,10 @@ export class DatabaseUI extends DisposableObject {
logger.log('Could not determine target dbscheme to upgrade to.');
return;
}
const parentDirs = scripts.map(dir => path.dirname(dir));
const uniqueParentDirs = new Set(parentDirs);
const targetDbSchemeUri = Uri.file(finalDbscheme);
const upgradesDirectories = Array.from(uniqueParentDirs).map(filePath => Uri.file(filePath));
try {
await upgradeDatabase(this.queryServer, databaseItem, targetDbSchemeUri, upgradesDirectories);
await upgradeDatabase(this.queryServer, databaseItem, targetDbSchemeUri, getUpgradesDirectories(scripts));
}
catch (e) {
if (e instanceof UserCancellationException) {

View File

@@ -629,3 +629,13 @@ export class DatabaseManager extends DisposableObject {
this.ctx.workspaceState.update(DB_LIST, this._databaseItems.map(item => item.getPersistedState()));
}
}
/**
* Get the set of directories containing upgrades, given a list of
* scripts returned by the cli's upgrade resolution.
*/
export function getUpgradesDirectories(scripts: string[]): vscode.Uri[] {
const parentDirs = scripts.map(dir => path.dirname(dir));
const uniqueParentDirs = new Set(parentDirs);
return Array.from(uniqueParentDirs).map(filePath => vscode.Uri.file(filePath));
}

View File

@@ -443,12 +443,10 @@ export class ReleasesApiConsumer {
export async function extractZipArchive(archivePath: string, outPath: string): Promise<void> {
const archive = await unzipper.Open.file(archivePath);
// This cast is necessary as the type definition for unzipper.Open.file(...).extract() is incorrect.
// It can be removed when https://github.com/DefinitelyTyped/DefinitelyTyped/pull/40240 is merged.
await (archive.extract({
await archive.extract({
concurrency: 4,
path: outPath
}) as unknown as Promise<void>);
});
// Set file permissions for extracted files
await Promise.all(archive.files.map(async file => {
// Only change file permissions if within outPath (path.join normalises the path)

View File

@@ -98,6 +98,7 @@ export class InterfaceManager extends DisposableObject {
super();
this.push(this._diagnosticCollection);
this.push(vscode.window.onDidChangeTextEditorSelection(this.handleSelectionChange.bind(this)));
}
// Returns the webview panel, creating it if it doesn't already
@@ -398,16 +399,54 @@ export class InterfaceManager extends DisposableObject {
sortState: info.sortState
};
}
private handleSelectionChange(event: vscode.TextEditorSelectionChangeEvent) {
if (event.kind === vscode.TextEditorSelectionChangeKind.Command) {
return; // Ignore selection events we caused ourselves.
}
let editor = vscode.window.activeTextEditor;
if (editor !== undefined) {
editor.setDecorations(shownLocationDecoration, []);
editor.setDecorations(shownLocationLineDecoration, []);
}
}
}
const findMatchBackground = new vscode.ThemeColor('editor.findMatchBackground');
const findRangeHighlightBackground = new vscode.ThemeColor('editor.findRangeHighlightBackground');
const shownLocationDecoration = vscode.window.createTextEditorDecorationType({
backgroundColor: findMatchBackground,
});
const shownLocationLineDecoration = vscode.window.createTextEditorDecorationType({
backgroundColor: findRangeHighlightBackground,
isWholeLine: true
});
async function showLocation(loc: ResolvableLocationValue, databaseItem: DatabaseItem): Promise<void> {
const resolvedLocation = tryResolveLocation(loc, databaseItem);
if (resolvedLocation) {
const doc = await workspace.openTextDocument(resolvedLocation.uri);
const editor = await Window.showTextDocument(doc, vscode.ViewColumn.One);
const sel = new vscode.Selection(resolvedLocation.range.start, resolvedLocation.range.end);
editor.selection = sel;
editor.revealRange(sel, vscode.TextEditorRevealType.InCenter);
let range = resolvedLocation.range;
// When highlighting the range, vscode's occurrence-match and bracket-match highlighting will
// trigger based on where we place the cursor/selection, and will compete for the user's attention.
// For reference:
// - Occurences are highlighted when the cursor is next to or inside a word or a whole word is selected.
// - Brackets are highlighted when the cursor is next to a bracket and there is an empty selection.
// - Multi-line selections explicitly highlight line-break characters, but multi-line decorators do not.
//
// For single-line ranges, select the whole range, mainly to disable bracket highlighting.
// For multi-line ranges, place the cursor at the beginning to avoid visual artifacts from selected line-breaks.
// Multi-line ranges are usually large enough to overshadow the noise from bracket highlighting.
let selectionEnd = (range.start.line === range.end.line)
? range.end
: range.start;
editor.selection = new vscode.Selection(range.start, selectionEnd);
editor.revealRange(range, vscode.TextEditorRevealType.InCenter);
editor.setDecorations(shownLocationDecoration, [range]);
editor.setDecorations(shownLocationLineDecoration, [range]);
}
}

View File

@@ -5,7 +5,7 @@ import * as sarif from 'sarif';
import * as tmp from 'tmp';
import * as vscode from 'vscode';
import * as cli from './cli';
import { DatabaseItem } from './databases';
import { DatabaseItem, getUpgradesDirectories } from './databases';
import * as helpers from './helpers';
import { DatabaseInfo, SortState, ResultsInfo, SortedResultSetInfo } from './interface-types';
import { logger } from './logging';
@@ -388,18 +388,18 @@ export async function clearCacheInDatabase(qs: qsClient.QueryServerClient, dbIte
title: "Clearing Cache",
cancellable: false,
}, (progress, token) =>
qs.sendRequest(messages.clearCache, params, token, progress)
qs.sendRequest(messages.clearCache, params, token, progress)
);
}
/**
*
*
* @param filePath This needs to be equivalent to java Path.toRealPath(NO_FOLLOW_LINKS)
*
*
*/
async function convertToQlPath(filePath: string): Promise<string> {
if (process.platform === "win32") {
if (path.parse(filePath).root === filePath) {
// Java assumes uppercase drive letters are canonical.
return filePath.toUpperCase();
@@ -447,7 +447,7 @@ async function checkDbschemeCompatibility(
const searchPath = helpers.getOnDiskWorkspaceFolders();
if (query.dbItem.contents !== undefined && query.dbItem.contents.dbSchemeUri !== undefined) {
const info = await cliServer.resolveUpgrades(query.dbItem.contents.dbSchemeUri.fsPath, searchPath);
const { scripts, finalDbscheme } = await cliServer.resolveUpgrades(query.dbItem.contents.dbSchemeUri.fsPath, searchPath);
async function hash(filename: string): Promise<string> {
return crypto.createHash('sha256').update(await fs.readFile(filename)).digest('hex');
}
@@ -463,7 +463,7 @@ async function checkDbschemeCompatibility(
const dbschemeOfLib = await hash(query.queryDbscheme);
// info.finalDbscheme is which database we're able to upgrade to
const upgradableTo = await hash(info.finalDbscheme);
const upgradableTo = await hash(finalDbscheme);
if (upgradableTo != dbschemeOfLib) {
logger.log(`Query ${query.program.queryPath} expects database scheme ${query.queryDbscheme}, but database has scheme ${query.program.dbschemePath}, and no upgrade path found`);
@@ -476,8 +476,8 @@ async function checkDbschemeCompatibility(
await upgradeDatabase(
qs,
query.dbItem,
vscode.Uri.file(info.finalDbscheme),
searchPath.map(file => vscode.Uri.file(file))
vscode.Uri.file(finalDbscheme),
getUpgradesDirectories(scripts)
);
}
}

View File

@@ -115,6 +115,21 @@ class HistoryTreeDataProvider implements vscode.TreeDataProvider<QueryHistoryIte
setCurrentItem(item: QueryHistoryItem) {
this.current = item;
}
remove(item: QueryHistoryItem) {
if (this.current === item)
this.current = undefined;
const index = this.history.findIndex(i => i === item);
if (index >= 0) {
this.history.splice(index, 1);
if (this.current === undefined && this.history.length > 0) {
// Try to keep a current item, near the deleted item if there
// are any available.
this.current = this.history[Math.min(index, this.history.length - 1)];
}
this._onDidChangeTreeData.fire();
}
}
}
/**
@@ -130,11 +145,27 @@ export class QueryHistoryManager {
selectedCallback: ((item: QueryHistoryItem) => void) | undefined;
lastItemClick: { time: Date, item: QueryHistoryItem } | undefined;
async invokeCallbackOn(queryHistoryItem: QueryHistoryItem) {
if (this.selectedCallback !== undefined) {
const sc = this.selectedCallback;
await sc(queryHistoryItem);
}
}
async handleOpenQuery(queryHistoryItem: QueryHistoryItem) {
const textDocument = await vscode.workspace.openTextDocument(vscode.Uri.file(queryHistoryItem.info.query.program.queryPath));
await vscode.window.showTextDocument(textDocument, vscode.ViewColumn.One);
}
async handleRemoveHistoryItem(queryHistoryItem: QueryHistoryItem) {
this.treeDataProvider.remove(queryHistoryItem);
const current = this.treeDataProvider.getCurrent();
if (current !== undefined) {
this.treeView.reveal(current);
await this.invokeCallbackOn(current);
}
}
async handleItemClicked(queryHistoryItem: QueryHistoryItem) {
this.treeDataProvider.setCurrentItem(queryHistoryItem);
@@ -150,10 +181,7 @@ export class QueryHistoryManager {
}
else {
// show results on single click
if (this.selectedCallback !== undefined) {
const sc = this.selectedCallback;
await sc(queryHistoryItem);
}
await this.invokeCallbackOn(queryHistoryItem);
}
}
@@ -170,6 +198,7 @@ export class QueryHistoryManager {
}
});
ctx.subscriptions.push(vscode.commands.registerCommand('codeQLQueryHistory.openQuery', this.handleOpenQuery));
ctx.subscriptions.push(vscode.commands.registerCommand('codeQLQueryHistory.removeHistoryItem', this.handleRemoveHistoryItem.bind(this)));
ctx.subscriptions.push(vscode.commands.registerCommand('codeQLQueryHistory.itemClicked', async (item) => {
return this.handleItemClicked(item);
}));

View File

@@ -1,10 +1,9 @@
import cx from 'classnames';
import * as path from 'path';
import * as React from 'react';
import * as Sarif from 'sarif';
import { LocationStyle, ResolvableLocationValue } from 'semmle-bqrs';
import * as octicons from './octicons';
import { className, renderLocation, ResultTableProps, selectedClassName, zebraStripe } from './result-table-utils';
import { className, renderLocation, ResultTableProps, zebraStripe } from './result-table-utils';
import { PathTableResultSet } from './results';
export type PathTableProps = ResultTableProps & { resultSet: PathTableResultSet };
@@ -99,11 +98,7 @@ export class PathTable extends React.Component<PathTableProps, PathTableState> {
}
render(): JSX.Element {
const { selected, databaseUri, resultSet } = this.props;
const tableClassName = cx(className, {
[selectedClassName]: selected
});
const { databaseUri, resultSet } = this.props;
const rows: JSX.Element[] = [];
const { numTruncatedResults, sourceLocationPrefix } = resultSet;
@@ -342,7 +337,7 @@ export class PathTable extends React.Component<PathTableProps, PathTableState> {
</td></tr>);
}
return <table className={tableClassName}>
return <table className={className}>
<tbody>{rows}</tbody>
</table>;
}

View File

@@ -1,6 +1,5 @@
import cx from 'classnames';
import * as React from "react";
import { className, renderLocation, ResultTableProps, selectedClassName, zebraStripe } from "./result-table-utils";
import { renderLocation, ResultTableProps, zebraStripe, className } from "./result-table-utils";
import { RawTableResultSet, ResultValue, vscode } from "./results";
import { assertNever } from "../helpers-pure";
import { SortDirection, SortState, RAW_RESULTS_LIMIT } from "../interface-types";
@@ -16,11 +15,7 @@ export class RawTable extends React.Component<RawTableProps, {}> {
}
render(): React.ReactNode {
const { resultSet, selected, databaseUri } = this.props;
const tableClassName = cx(className, {
[selectedClassName]: selected
});
const { resultSet, databaseUri } = this.props;
let dataRows = this.props.resultSet.rows;
let numTruncatedResults = 0;
@@ -52,7 +47,7 @@ export class RawTable extends React.Component<RawTableProps, {}> {
</td></tr>);
}
return <table className={tableClassName}>
return <table className={className}>
<thead>
<tr>
{

View File

@@ -4,7 +4,6 @@ import { SortState } from '../interface-types';
import { ResultSet, vscode } from './results';
export interface ResultTableProps {
selected: boolean;
resultSet: ResultSet;
databaseUri: string;
resultsPath: string | undefined;
@@ -14,8 +13,6 @@ export interface ResultTableProps {
export const className = 'vscode-codeql__result-table';
export const tableSelectionHeaderClassName = 'vscode-codeql__table-selection-header';
export const toggleDiagnosticsClassName = `${className}-toggle-diagnostics`;
export const selectedClassName = `${className}--selected`;
export const toggleDiagnosticsSelectedClassName = `${toggleDiagnosticsClassName}--selected`;
export const evenRowClassName = 'vscode-codeql__result-table-row--even';
export const oddRowClassName = 'vscode-codeql__result-table-row--odd';
export const pathRowClassName = 'vscode-codeql__result-table-row--path';

View File

@@ -1,9 +1,8 @@
import cx from 'classnames';
import * as React from 'react';
import { DatabaseInfo, Interpretation, SortState } from '../interface-types';
import { PathTable } from './alert-table';
import { RawTable } from './raw-results-table';
import { ResultTableProps, toggleDiagnosticsClassName, toggleDiagnosticsSelectedClassName, tableSelectionHeaderClassName } from './result-table-utils';
import { ResultTableProps, tableSelectionHeaderClassName, toggleDiagnosticsClassName } from './result-table-utils';
import { ResultSet, vscode } from './results';
/**
@@ -76,14 +75,26 @@ export class ResultTables
}
render(): React.ReactNode {
const selectedTable = this.state.selectedTable;
const { selectedTable } = this.state;
const resultSets = this.getResultSets();
const { database, resultsPath, kind } = this.props;
// Only show the Problems view display checkbox for the alerts table.
const toggleDiagnosticsClass = cx(toggleDiagnosticsClassName, {
[toggleDiagnosticsSelectedClassName]: selectedTable === ALERTS_TABLE_NAME
});
const diagnosticsCheckBox = selectedTable === ALERTS_TABLE_NAME ?
<div className={toggleDiagnosticsClassName}>
<input type="checkbox" id="toggle-diagnostics" name="toggle-diagnostics" onChange={(e) => {
if (resultsPath !== undefined) {
vscode.postMessage({
t: 'toggleDiagnostics',
resultsPath: resultsPath,
databaseUri: database.databaseUri,
visible: e.target.checked,
kind: kind
});
}
}} />
<label htmlFor="toggle-diagnostics">Show results in Problems view</label>
</div> : undefined;
return <div>
<div className={tableSelectionHeaderClassName}>
@@ -96,20 +107,7 @@ export class ResultTables
)
}
</select>
<div className={toggleDiagnosticsClass}>
<input type="checkbox" id="toggle-diagnostics" name="toggle-diagnostics" onChange={(e) => {
if (resultsPath !== undefined) {
vscode.postMessage({
t: 'toggleDiagnostics',
resultsPath: resultsPath,
databaseUri: database.databaseUri,
visible: e.target.checked,
kind: kind
});
}
}} />
<label htmlFor="toggle-diagnostics">Show results in Problems view</label>
</div>
{diagnosticsCheckBox}
{
this.props.isLoadingNewResults ?
<span className={UPDATING_RESULTS_TEXT_CLASS_NAME}>Updating results</span>
@@ -118,9 +116,12 @@ export class ResultTables
</div>
{
resultSets.map(resultSet =>
<ResultTable key={resultSet.schema.name} resultSet={resultSet}
databaseUri={this.props.database.databaseUri} selected={resultSet.schema.name === selectedTable}
resultsPath={this.props.resultsPath} sortState={this.props.sortStates.get(resultSet.schema.name)} />
resultSet.schema.name === selectedTable ?
<ResultTable key={resultSet.schema.name} resultSet={resultSet}
databaseUri={this.props.database.databaseUri}
resultsPath={this.props.resultsPath}
sortState={this.props.sortStates.get(resultSet.schema.name)} /> :
undefined
)
}
</div>;
@@ -137,10 +138,10 @@ class ResultTable extends React.Component<ResultTableProps, {}> {
const { resultSet } = this.props;
switch (resultSet.t) {
case 'RawResultSet': return <RawTable
selected={this.props.selected} resultSet={resultSet} databaseUri={this.props.databaseUri}
resultSet={resultSet} databaseUri={this.props.databaseUri}
resultsPath={this.props.resultsPath} sortState={this.props.sortState} />;
case 'SarifResultSet': return <PathTable
selected={this.props.selected} resultSet={resultSet} databaseUri={this.props.databaseUri}
resultSet={resultSet} databaseUri={this.props.databaseUri}
resultsPath={this.props.resultsPath} />;
}
}

View File

@@ -1,13 +1,9 @@
.vscode-codeql__result-table {
display: none;
display: table;
border-collapse: collapse;
width: 100%;
}
.vscode-codeql__result-table--selected {
display: table;
}
.vscode-codeql__table-selection-header {
display: flex;
padding: 0.5em 0;
@@ -18,22 +14,18 @@
}
.vscode-codeql__result-table-toggle-diagnostics {
display: none;
display: inline-block;
text-align: left;
margin-left: auto;
}
.vscode-codeql__result-table-toggle-diagnostics--selected {
display: inline-block;
}
/* Keep the checkbox and its label in horizontal alignment. */
.vscode-codeql__result-table-toggle-diagnostics--selected label,
.vscode-codeql__result-table-toggle-diagnostics--selected input {
.vscode-codeql__result-table-toggle-diagnostics label,
.vscode-codeql__result-table-toggle-diagnostics input {
display: inline-block;
vertical-align: middle;
}
.vscode-codeql__result-table-toggle-diagnostics--selected input {
.vscode-codeql__result-table-toggle-diagnostics input {
margin: 3px 3px 1px 3px;
}

View File

@@ -18,7 +18,7 @@
"@types/node": "^12.0.8",
"@types/vscode": "^1.39.0",
"build-tasks": "^0.0.1",
"typescript": "^3.5.2",
"typescript": "^3.7.2",
"typescript-config": "^0.0.1",
"typescript-formatter": "^7.2.2"
},

View File

@@ -40,7 +40,7 @@
"@types/npm-packlist": "~1.1.1",
"@types/through2": "~2.0.34",
"@types/vinyl": "~2.0.3",
"typescript": "^3.5.2",
"typescript": "^3.7.2",
"typescript-config": "^0.0.1",
"typescript-formatter": "^7.2.2"
}

View File

@@ -19,7 +19,19 @@ interface IPackageInfo {
async function copyPackage(packageFiles: IPackageInfo, destPath: string): Promise<void> {
for (const file of packageFiles.files) {
await fs.copy(path.resolve(packageFiles.sourcePath, file), path.resolve(destPath, file));
const sourceFilePath = path.resolve(packageFiles.sourcePath, file);
const destFilePath = path.resolve(destPath, file);
if (packageFiles.isRoot && (file === 'package.json')) {
// For non-release builds, we tweak the version number of the extension to add a prerelease
// suffix. Rather than just copying `package.json`, we'll parse the original copy, update the
// `version` property, and write it out to the new location.
const packageJson = jsonc.parse((await fs.readFile(sourceFilePath)).toString());
packageJson.version = packageFiles.version;
await fs.writeFile(destFilePath, JSON.stringify(packageJson));
}
else {
await fs.copy(sourceFilePath, destFilePath);
}
}
}
@@ -142,14 +154,17 @@ export async function deployPackage(packageJsonPath: string): Promise<DeployedPa
if (isDevBuild) {
// NOTE: rootPackage.name had better not have any regex metacharacters
const oldDevBuildPattern = new RegExp('^' + rootPackage.name + '[^/]+-dev\\d+.vsix$');
const oldDevBuildPattern = new RegExp('^' + rootPackage.name + '[^/]+-dev[0-9.]+\\.vsix$');
// Dev package filenames are of the form
// vscode-codeql-0.0.1-dev20190927195520723.vsix
fs.readdirSync(distDir).filter(name => name.match(oldDevBuildPattern)).map(build => {
// vscode-codeql-0.0.1-dev.2019.9.27.19.55.20.vsix
(await fs.readdir(distDir)).filter(name => name.match(oldDevBuildPattern)).map(build => {
console.log(`Deleting old dev build ${build}...`);
fs.unlinkSync(path.join(distDir, build));
});
rootPackage.version = rootPackage.version + '-dev' + new Date().toISOString().replace(/[^0-9]/g, '');
const now = new Date();
rootPackage.version = rootPackage.version +
`-dev.${now.getUTCFullYear()}.${now.getUTCMonth() + 1}.${now.getUTCDate()}` +
`.${now.getUTCHours()}.${now.getUTCMinutes()}.${now.getUTCSeconds()}`;
}
const distPath = path.join(distDir, rootPackage.name);