Compare commits

...

898 Commits

Author SHA1 Message Date
Shati Patel
4c7c1cb0e6 v1.8.1 (#2216)
Some checks failed
Release / Release (push) Has been cancelled
Release / Publish to VS Code Marketplace (push) Has been cancelled
Release / Publish to Open VSX Registry (push) Has been cancelled
2023-03-23 11:00:29 +00:00
Robert
a3c4c8fb61 Merge pull request #2212 from github/robertbrignull/app_executeCommand
Replace app.executeCommand with app.commands.execute
2023-03-23 10:28:36 +00:00
Koen Vlaswinkel
73b0a0565f Merge pull request #2214 from github/koesie10/remove-command-runner-with-progress
Remove `commandRunnerWithProgress`
2023-03-23 11:26:20 +01:00
Robert
8fbde9fba1 Limit setContext keys 2023-03-23 10:12:20 +00:00
Koen Vlaswinkel
aca0489fdc Remove commandRunnerWithProgress
The `commandRunnerWithProgress` is unused because all commands have been
converted to using `commandRunner` in combination with `withProgress`.
2023-03-23 11:09:32 +01:00
Koen Vlaswinkel
dae472ca05 Merge pull request #2213 from github/koesie10/check-for-updates-typed-command
Add `codeQL.checkForUpdatesToCLI` type for command
2023-03-23 10:49:18 +01:00
Koen Vlaswinkel
20f85f2b81 Merge pull request #2210 from github/koesie10/base-typed-commands
Convert some base commands to typed commands
2023-03-23 10:03:53 +01:00
Koen Vlaswinkel
81cce9fa8b Add codeQL.checkForUpdatesToCLI type for command
The `codeQL.checkForUpdatesToCLI` command is registered pre-activation,
and we don't really want to create the command manager before
activation, so this will just add the correct type without registering
it using the command manager.
2023-03-23 09:58:27 +01:00
Koen Vlaswinkel
a27ca2e177 Merge remote-tracking branch 'origin/main' into koesie10/base-typed-commands 2023-03-23 09:51:24 +01:00
Robert
3e9c2c85d3 Remove app.executeCommand 2023-03-22 17:13:12 +00:00
Robert
297fa2ebd3 Merge pull request #2207 from github/robertbrignull/extension_commands
Start using app.commands.execute for all commands called from extension.ts
2023-03-22 16:59:53 +00:00
Shati Patel
844e58a1b1 Tidy up recent changelog entries (#2211) 2023-03-22 16:54:17 +00:00
Robert
9948b93b76 Merge branch 'main' into robertbrignull/extension_commands 2023-03-22 16:35:56 +00:00
Koen Vlaswinkel
e1d5a4ddaa Merge remote-tracking branch 'origin/main' into koesie10/base-typed-commands 2023-03-22 17:22:26 +01:00
Koen Vlaswinkel
7059f46141 Merge pull request #2209 from github/koesie10/query-editor-typed-commands
Convert query editing commands to typed commands
2023-03-22 17:21:31 +01:00
Koen Vlaswinkel
fe6ff6801a Convert some base commands to typed commands 2023-03-22 17:02:16 +01:00
Koen Vlaswinkel
be3459c1aa Convert query editing commands to typed commands 2023-03-22 16:52:59 +01:00
Koen Vlaswinkel
5ac5de8a5b Move query editing commands to separate file 2023-03-22 16:50:44 +01:00
Koen Vlaswinkel
322c1a8835 Merge pull request #2206 from github/koesie10/test-ui-typed-commands
Convert test UI commands to typed commands
2023-03-22 16:42:18 +01:00
Robert
5d6a2e6d7f rename types 2023-03-22 15:37:39 +00:00
Robert
0e79b92829 Merge branch 'main' into robertbrignull/extension_commands 2023-03-22 15:36:31 +00:00
Koen Vlaswinkel
59378daff3 Merge remote-tracking branch 'origin/main' into koesie10/test-ui-typed-commands 2023-03-22 16:29:36 +01:00
Koen Vlaswinkel
125af1139b Merge pull request #2208 from github/koesie10/mock-server-typed-commands
Convert mock API server commands to typed commands
2023-03-22 16:28:28 +01:00
Robert
6afdf6357b Merge pull request #2202 from github/robertbrignull/extract_progress
Move withProgress and associated code to a separate file
2023-03-22 15:19:50 +00:00
Koen Vlaswinkel
fd7013f754 Convert mock API server commands to typed commands 2023-03-22 16:04:49 +01:00
Robert
408c042b3b Fix remaining imports 2023-03-22 14:49:04 +00:00
Koen Vlaswinkel
b2fceb9b2d Merge pull request #2205 from github/koesie10/results-view-typed-commands
Convert results view commands to typed commands
2023-03-22 15:46:08 +01:00
Robert
819e596b9b Merge branch 'main' into robertbrignull/extract_progress 2023-03-22 14:31:55 +00:00
Robert
31af28e73b Add link to docs 2023-03-22 14:28:10 +00:00
Koen Vlaswinkel
c6d8a09f19 Add support for Partial in the command manager
The command manager types didn't fully support commands defined with
`Partial` because it deduced that the command function was `undefined`
when the function was not defined. However, if the command is not
present, the command registration will not be called. This fixes the
types by specifying that the command definition will never be
`undefined`.
2023-03-22 15:27:18 +01:00
Robert
39d4675b44 Start using app.commands.execute for all commands called from extension.ts 2023-03-22 14:16:55 +00:00
Koen Vlaswinkel
e74a2e4a15 Remove UIService
This class seems to have been introduced at some point to reduce the
dependency on VS Code from the test UI service. However, none of its
methods are being used anymore, and by using typed commands we have
already reduced the dependency on VS Code. Therefore, we can simply
remove this class.
2023-03-22 15:14:22 +01:00
Koen Vlaswinkel
9f85f56055 Convert test UI commands to typed commands 2023-03-22 15:13:05 +01:00
Koen Vlaswinkel
ac57f5005d Convert results view commands to typed commands 2023-03-22 15:06:15 +01:00
Koen Vlaswinkel
88a9ecbeab Merge pull request #2204 from github/koesie10/summary-language-support-typed-commands
Convert summary language commands to typed commands
2023-03-22 14:52:45 +01:00
Koen Vlaswinkel
9f7c7b2ed8 Merge pull request #2203 from github/koesie10/ast-viewer-typed-commands
Convert AST viewer commands to typed commands
2023-03-22 14:44:04 +01:00
Koen Vlaswinkel
1f8070c8b5 Convert summary language commands to typed commands 2023-03-22 14:26:06 +01:00
Koen Vlaswinkel
bc29231fec Convert AST viewer commands to typed commands 2023-03-22 14:11:43 +01:00
Koen Vlaswinkel
e724577d82 Merge pull request #2196 from github/koesie10/ast-cfg-typed-commands
Convert AST and CFG commands to typed commands
2023-03-22 13:32:34 +01:00
Robert
b914b97be7 Pull progress to separate file 2023-03-22 12:07:16 +00:00
Koen Vlaswinkel
9d4b19f91f Merge remote-tracking branch 'origin/main' into koesie10/ast-cfg-typed-commands 2023-03-22 13:03:21 +01:00
Koen Vlaswinkel
8a66bb4017 Merge pull request #2198 from github/koesie10/packaging-typed-commands
Convert packaging to typed commands
2023-03-22 13:02:21 +01:00
Robert
e55fb8c7a7 Merge pull request #2191 from github/robertbrignull/variant_analysis_commands
Convert all variant analysis commands to typed commands
2023-03-22 11:56:31 +00:00
Robert
a6fefdbabb Merge branch 'main' into robertbrignull/variant_analysis_commands 2023-03-22 11:44:25 +00:00
Robert
2334e4e7b2 Merge pull request #2192 from github/robertbrignull/export_selected_results_command
Move codeQL.exportSelectedVariantAnalysisResults to query history manager
2023-03-22 11:41:13 +00:00
Koen Vlaswinkel
5c06bcc6bd Merge remote-tracking branch 'origin/main' into koesie10/packaging-typed-commands 2023-03-22 12:39:36 +01:00
Koen Vlaswinkel
3240809d11 Merge pull request #2200 from github/koesie10/restart-typed-command
Convert codeQL.restartQueryServer to a typed command
2023-03-22 12:37:20 +01:00
Koen Vlaswinkel
3e66e7aaf3 Merge remote-tracking branch 'origin/main' into koesie10/restart-typed-command 2023-03-22 12:10:54 +01:00
Koen Vlaswinkel
71831fe460 Merge pull request #2201 from github/koesie10/eval-log-viewer-typed-command
Convert codeQLEvalLogViewer.clear to a typed command
2023-03-22 12:07:34 +01:00
Robert
0983733a67 fix typo 2023-03-22 10:51:03 +00:00
Robert
0166f9a557 Merge branch 'main' into robertbrignull/variant_analysis_commands 2023-03-22 10:50:17 +00:00
Robert
5af0ebcb24 convert to type imports 2023-03-22 10:49:50 +00:00
Koen Vlaswinkel
9d6c78b656 Merge branch 'main' into koesie10/ast-cfg-typed-commands 2023-03-22 11:37:23 +01:00
Koen Vlaswinkel
56c83eb480 Merge pull request #2195 from github/koesie10/move-database-commands
Move remaining local database commands to databases UI
2023-03-22 11:36:56 +01:00
Koen Vlaswinkel
aa0d011daa Convert codeQLEvalLogViewer.clear to a typed command 2023-03-22 11:34:39 +01:00
Koen Vlaswinkel
76558b8d41 Merge pull request #2194 from github/koesie10/typed-local-query-commands
Convert local query commands to typed commands
2023-03-22 11:34:34 +01:00
Koen Vlaswinkel
eb5659a628 Merge branch 'main' into koesie10/move-database-commands 2023-03-22 11:22:48 +01:00
Koen Vlaswinkel
11b4de1820 Merge branch 'main' into koesie10/typed-local-query-commands 2023-03-22 11:20:02 +01:00
Koen Vlaswinkel
2c8c7cec8f Convert codeQL.restartQueryServer to a typed command 2023-03-22 10:29:09 +01:00
Koen Vlaswinkel
1c6d9f3f22 Use commandRunner for codeQL.restartQueryServer 2023-03-22 10:26:29 +01:00
Elena Tanasoiu
f196e34fa5 Merge pull request #2188 from github/elena/force-workspace-in-codespace
Codespace: Open tutorial workspace on extension start
2023-03-22 08:30:31 +00:00
Koen Vlaswinkel
7c7a64ca5b Convert packaging commands to typed commands 2023-03-22 09:22:07 +01:00
Koen Vlaswinkel
dfff7ae8de Move packaging commands to withProgress 2023-03-22 09:22:07 +01:00
Koen Vlaswinkel
ef267f87bb Move packaging command registration to separate file 2023-03-22 09:22:07 +01:00
Elena Tanasoiu
a7800ce3bc Merge branch 'main' into elena/force-workspace-in-codespace 2023-03-22 07:46:19 +00:00
github-actions[bot]
168af11e00 Bump CLI version from v2.12.4 to v2.12.5 for integration tests (#2197)
Co-authored-by: github-actions[bot] <github-actions@github.com>
2023-03-21 16:27:58 +00:00
Koen Vlaswinkel
17bab1c09c Remove unnecessary viewAst function 2023-03-21 16:10:05 +01:00
Koen Vlaswinkel
b3092be5d3 Convert AST and CFG commands to typed commands 2023-03-21 16:09:15 +01:00
Koen Vlaswinkel
1909fee91f Remove use of commandRunnerWithProgress in AST and CFG commands 2023-03-21 16:04:41 +01:00
Koen Vlaswinkel
6ff2670ec2 Remove duplication of AST and CFG command implementations 2023-03-21 16:02:05 +01:00
Koen Vlaswinkel
0379575256 Move AST and CFG commands to separate file 2023-03-21 15:58:12 +01:00
Elena Tanasoiu
8fd9ebf2d8 Limit comparison to Uri path
We attempted to specify exactly which URI we're expecting here.

However, `Uri.parse` behaves differently in the test than it does in
the code so we've inadvertently created a flakey test [1]. The URI we
generate in the test has a `scheme: 'c'` while the one in the code has
a `scheme: 'C'` property.

This only happens on windows, not ubuntu.

Let's narrow the comparison to just the path of the URI.

[1]: https://github.com/github/vscode-codeql/actions/runs/4478429334/jobs/7871178529#step:7:231
2023-03-21 14:26:22 +00:00
Koen Vlaswinkel
bed56ef648 Make public methods private in local databases UI
Some of the methods in the `DatabaseUI` were public because they were
used in the `extension.ts` file. We have moved these method calls into
this file, so they do not need to be public anymore. We can also get rid
of the separation between some of these methods, so I've moved them into
the function that calls them.
2023-03-21 14:50:24 +01:00
Koen Vlaswinkel
7ab986fabe Move codeQL.chooseDatabaseGithub command 2023-03-21 14:48:14 +01:00
Koen Vlaswinkel
15d30d5342 Move codeQL.chooseDatabaseInternet command 2023-03-21 14:47:26 +01:00
Koen Vlaswinkel
71f22b9a7a Move codeQL.chooseDatabaseArchive command 2023-03-21 14:45:54 +01:00
Koen Vlaswinkel
32b6ad53cf Move codeQL.chooseDatabaseFolder command 2023-03-21 14:44:46 +01:00
Koen Vlaswinkel
ac2f4475c0 Group local database commands by type 2023-03-21 14:40:04 +01:00
Elena Tanasoiu
108943d135 existsSync -> pathExists
Use async version of file check.
2023-03-21 13:19:33 +00:00
Gulshan Singh
bb0c53d65d Display EntityValue labels in CSV export (#2170) 2023-03-21 11:59:18 +00:00
Nora
82d03091d0 Merge pull request #2193 from github/nora/query-history-data-model
Move query-serialization
2023-03-21 12:23:18 +01:00
Elena Tanasoiu
c1a515ed82 Open tutorial before extension activation
To reduce lag when checking for the existence of the tutorial workspace.
2023-03-21 11:20:14 +00:00
Elena Tanasoiu
0368d537ad Ask the user for permission to reload workspace
To make this a nicer experience for the user, we're adding a prompt
to let them know we're about to reload the workspace.
2023-03-21 11:20:14 +00:00
Elena Tanasoiu
7059802a25 Add more logging before attempting to open tutorial workspace 2023-03-21 11:20:14 +00:00
Elena Tanasoiu
0f4fcdf676 Add comment with PR description
This adds the explanation from the PR description in a comment and
removes comment that's no longer helpful.
2023-03-21 11:20:14 +00:00
Elena Tanasoiu
ce413a6385 Stub isCodespaceTemplate correctly
Now that we fixed our expectation in the previous commit, we could see we
were stubbing this to false instead of true.

So now the test is checking the right scenario.
2023-03-21 11:20:13 +00:00
Elena Tanasoiu
8db9f52df3 Adjust the rest of the test expectations
Our expectation was quite narrow: we expect to not call an `openFolder`
command. We didn't specify any params for it, which might mean this
expectation wasn't working like it should.

Let's just check that `executeCommand` isn't called at all.
2023-03-21 11:20:13 +00:00
Elena Tanasoiu
782e413c64 Add workspace filepath to test expectation 2023-03-21 11:20:13 +00:00
Elena Tanasoiu
fade710f95 Call it commandSpy everywhere 2023-03-21 11:20:13 +00:00
Elena Tanasoiu
737a1f5c37 Use existing file path consistently 2023-03-21 11:19:56 +00:00
Koen Vlaswinkel
7950c1c982 Convert local query commands to typed commands
The local query commands are using a separate logger, and this is not
supported by the command manager because it is quite specific to this
extension. Therefore, we create a separate command manager which uses
a different logger to separate the commands.
2023-03-21 12:08:44 +01:00
Koen Vlaswinkel
f37a6c5e9e Convert commandRunnerWithProgress to commandRunner 2023-03-21 12:08:44 +01:00
Koen Vlaswinkel
649179f62e Rename local queries manager variable names 2023-03-21 12:08:44 +01:00
Koen Vlaswinkel
8a2630d1b7 Move local queries commands to separate file 2023-03-21 12:08:44 +01:00
Nora
fa29bcc5fd Rename serializer 2023-03-21 11:03:58 +00:00
Nora
5cd50a67e7 Move query-serialization 2023-03-21 10:39:02 +00:00
Koen Vlaswinkel
f7b6d4c4a4 Merge pull request #2189 from github/koesie10/typed-local-database-ui-commands
Convert local database commands to typed commands
2023-03-21 10:39:57 +01:00
Koen Vlaswinkel
58bffe1edf Merge remote-tracking branch 'origin/main' into koesie10/typed-local-database-ui-commands 2023-03-21 10:27:31 +01:00
Robert
0c9df6edba Convert the codeQL.openVariantAnalysisView command 2023-03-20 17:41:23 +00:00
Robert
ac0d920156 Convert the codeQL.loadVariantAnalysisRepoResults command 2023-03-20 17:41:23 +00:00
Robert
5f2a8fa1d5 Convert the codeQL.autoDownloadVariantAnalysisResult command 2023-03-20 17:41:21 +00:00
Robert
b55910d2b9 Convert the codeQL.monitorVariantAnalysis command 2023-03-20 17:32:35 +00:00
Robert
e586f3de53 Move codeQL.exportSelectedVariantAnalysisResults to query history manager 2023-03-20 16:59:51 +00:00
Robert
08849c1df4 Convert codeQL.copyVariantAnalysisRepoList command 2023-03-20 16:50:53 +00:00
Robert
aa64459353 Convert existing variant analysis commands to bind(this) 2023-03-20 16:50:53 +00:00
Robert
3c229d244e Merge pull request #2186 from github/robertbrignull/export_results_telemetry
Add telemetry for exporting variant analysis results
2023-03-20 16:47:49 +00:00
Robert
fb70382929 Fix tests to not reference deleted command 2023-03-20 16:33:55 +00:00
Robert
f49314f6f3 Merge branch 'main' into robertbrignull/export_results_telemetry 2023-03-20 15:46:41 +00:00
Koen Vlaswinkel
9044d11d2b Merge pull request #2190 from github/koesie10/typed-new-database-panel-commands
Convert new database panel to typed commands
2023-03-20 16:25:04 +01:00
Elena Tanasoiu
5444a9e55e Fail gracefully if we can't set up code tour
We're running this at the extension start-up. We don't want it to block the extension
from completing activation, so let's swallow any errors from the code tour and output
them, instead of letting this affect the rest of the extension activation.
2023-03-20 15:01:04 +00:00
Elena Tanasoiu
4fa3c459a1 Open tutorial workspace on extension start
When opening https://github.com/github/codespaces-codeql/ in a
codespace, it's easy to miss the prompt that tells you to open the
tutorial.code-workspace file.

In fact people actively dismiss the alert to get it out of the way.

If you miss that prompt, you end up with a single-rooted workspace,
which causes various other problems.

While there is an open issue to allow VS Code to open a default
workspace [1], there doesn't seem to have been any progress on it
in the last two years.

So we're taking matters into our own hands and forcing the extension
to open the tutorial workspace, if it detects it.

This will only happen if the following three conditions are met:
- the .tours folder exists
- the tutorial.code-workspace file exists
- the CODESPACES_TEMPLATE setting hasn't been set

NB: the `CODESPACES_TEMPLATE` setting can only be found if the
tutorial.code-workspace has already been opened. So it's a good
indicator that we're in the folder, but the user has ignored the prompt.

[1]: https://github.com/microsoft/vscode-remote-release/issues/3665
2023-03-20 13:31:20 +00:00
Koen Vlaswinkel
2e9a22e86d Convert new database panel to typed commands
This converts the new database panel to use typed commands. There should
be no changes in behaviour.
2023-03-20 13:52:32 +01:00
Robert
b76bef4246 Remove the codeQL.exportVariantAnalysisResults command 2023-03-20 12:33:51 +00:00
Koen Vlaswinkel
e603de41c1 Convert local database commands to typed commands 2023-03-20 11:39:53 +01:00
Koen Vlaswinkel
dbd832f1a0 Switch local databases to function definitions
The local databases UI was essentially the only class which was defining
methods using assignment to a class property rather than using function
definitions and binding them. This switches it to use function
definitions and binding, which is more consistent with the rest of the
codebase.
2023-03-20 11:29:45 +01:00
Robert
5b2093df8f Merge pull request #2185 from github/robertbrignull/remove_internal_commands
Remove two more internal-only commands
2023-03-20 10:24:31 +00:00
Koen Vlaswinkel
af63e5094f Convert commandRunnerWithProgress invocations to withProgress 2023-03-20 11:19:32 +01:00
Robert
94db1dff73 Remove codeQL.openVariantAnalysisQueryText command 2023-03-17 16:13:21 +00:00
Robert
a44ecadae5 Add telemetry for exporting variant analysis results 2023-03-17 16:09:00 +00:00
Robert
a375afd61b Remove codeQL.cancelVariantAnalysis command 2023-03-17 15:48:00 +00:00
Charis Kyriakou
42ce27b112 Merge pull request #2183 from github/charis/remove-primer
Remove primer packages and make styled-components a top-level dependency
2023-03-17 14:46:02 +00:00
Koen Vlaswinkel
f86c0b826a Merge pull request #2176 from github/koesie10/query-history-commands-typed
Convert query history commands to typed commands
2023-03-17 15:28:21 +01:00
Charis Kyriakou
2d46365406 Add styled-components as a top level dependency 2023-03-17 14:19:22 +00:00
Charis Kyriakou
50e89ba1a3 Remove primer packages 2023-03-17 13:46:43 +00:00
Charis Kyriakou
7914403da0 Wire up data flow paths view (#2182) 2023-03-17 13:30:32 +00:00
Koen Vlaswinkel
5be08d7c92 Revert change to context menu name 2023-03-17 12:29:25 +01:00
Robert
df24a705b0 Merge pull request #2179 from github/robertbrignull/remove_openVariantAnalysisQueryFile_command
Remove codeQL.openVariantAnalysisQueryFile command
2023-03-17 11:23:31 +00:00
Koen Vlaswinkel
fce51ca9a2 Convert query history commands to typed commands 2023-03-17 10:54:40 +01:00
Charis Kyriakou
8a5273058b Add new data flow paths view (empty) (#2172) 2023-03-17 09:25:03 +00:00
Koen Vlaswinkel
f3274b39d2 Merge pull request #2015 from github/dependabot/npm_and_yarn/extensions/ql-vscode/glob-promise-6.0.2
Bump glob-promise from 4.2.2 to 6.0.2 in /extensions/ql-vscode
2023-03-17 09:49:53 +01:00
Koen Vlaswinkel
38e551bb2a Merge pull request #1930 from github/dependabot/npm_and_yarn/extensions/ql-vscode/tar-stream-3.0.0
Bump tar-stream from 2.2.0 to 3.0.0 in /extensions/ql-vscode
2023-03-17 09:48:52 +01:00
dependabot[bot]
cc53cd54c4 Bump webpack-cli from 4.6.0 to 5.0.1 in /extensions/ql-vscode (#2181)
Bumps [webpack-cli](https://github.com/webpack/webpack-cli) from 4.6.0 to 5.0.1.
- [Release notes](https://github.com/webpack/webpack-cli/releases)
- [Changelog](https://github.com/webpack/webpack-cli/blob/master/CHANGELOG.md)
- [Commits](https://github.com/webpack/webpack-cli/compare/webpack-cli@4.6.0...webpack-cli@5.0.1)

---
updated-dependencies:
- dependency-name: webpack-cli
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-16 09:38:00 -07:00
Robert
61cc9191f9 Merge pull request #2139 from github/robertbrignull/webview_error_telemetry
Add listeners for unhandled errors to web views
2023-03-16 11:18:52 +00:00
Robert
f2f1b1d6a3 Collect common messages 2023-03-16 10:59:02 +00:00
Robert
64531f5a6f Check undefined instead of using typeof 2023-03-16 10:54:29 +00:00
Robert
29bb7ce01e Emit telemetry when opening variant analysis query file 2023-03-16 10:39:02 +00:00
Robert
9045253624 Merge pull request #2178 from github/robertbrignull/split-commands/codeQLQueryHistory.openQuery
Split up codeQLQueryHistory.openQuery command
2023-03-15 17:12:06 +00:00
Robert
34ab409050 Remove codeQL.openVariantAnalysisQueryFile command 2023-03-15 17:06:17 +00:00
Robert
e6f543670a Split up codeQLQueryHistory.openQuery command 2023-03-15 16:54:46 +00:00
Robert
04c24d0996 Merge pull request #2177 from github/robertbrignull/split-commands/codeQLQueryHistory.removeHistoryItem
Split up the codeQLQueryHistory.removeHistoryItem command
2023-03-15 16:54:24 +00:00
Koen Vlaswinkel
41ca0ffba6 Merge pull request #2175 from github/dependabot/npm_and_yarn/extensions/ql-vscode/lint-staged-13.2.0
Bump lint-staged from 10.2.11 to 13.2.0 in /extensions/ql-vscode
2023-03-15 17:16:03 +01:00
Robert
84f60ccb8c Avoid duplicate use of the codeQLQueryHistory.removeHistoryItem command 2023-03-15 16:11:40 +00:00
dependabot[bot]
0fa0fa3523 Bump tar-stream from 2.2.0 to 3.0.0 in /extensions/ql-vscode
Bumps [tar-stream](https://github.com/mafintosh/tar-stream) from 2.2.0 to 3.0.0.
- [Release notes](https://github.com/mafintosh/tar-stream/releases)
- [Commits](https://github.com/mafintosh/tar-stream/compare/v2.2.0...v3.0.0)

---
updated-dependencies:
- dependency-name: tar-stream
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-15 16:10:41 +00:00
dependabot[bot]
fe554ee2a7 Bump glob-promise from 4.2.2 to 6.0.2 in /extensions/ql-vscode
Bumps [glob-promise](https://github.com/ahmadnassri/node-glob-promise) from 4.2.2 to 6.0.2.
- [Release notes](https://github.com/ahmadnassri/node-glob-promise/releases)
- [Commits](https://github.com/ahmadnassri/node-glob-promise/compare/v4.2.2...v6.0.2)

---
updated-dependencies:
- dependency-name: glob-promise
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-15 16:09:35 +00:00
Koen Vlaswinkel
019af98f40 Merge pull request #2171 from github/koesie10/commands-with-progress
Convert run variant analysis command to new commands package
2023-03-15 16:39:35 +01:00
Koen Vlaswinkel
c853bafb91 Merge remote-tracking branch 'origin/main' into koesie10/commands-with-progress 2023-03-15 15:43:34 +01:00
Robert
c632c38220 Merge pull request #2087 from github/robertbrignull/no-nested-functions
Avoid having functions that aren't at the top level in extension.ts
2023-03-15 14:21:23 +00:00
Robert
fd570abdcd Merge branch 'main' into robertbrignull/no-nested-functions 2023-03-15 13:37:35 +00:00
Robert
e81d585336 Swap arguments so command arg comes last 2023-03-15 13:36:57 +00:00
Anders Starcke Henriksen
dc55ef9985 Merge pull request #2157 from github/starcke/commands-registration
Commands registration
2023-03-15 14:05:25 +01:00
Robert
3fe069975a Avoid reporting errors twice 2023-03-15 12:26:58 +00:00
Anders Starcke Henriksen
5303ec67cb Name updates. 2023-03-15 12:04:52 +01:00
Robert
969fdb6337 Make type checking all use typeof 2023-03-15 10:21:25 +00:00
Robert
47fa752c5c Merge branch 'main' into robertbrignull/webview_error_telemetry 2023-03-15 09:56:58 +00:00
dependabot[bot]
639c8728dd Bump lint-staged from 10.2.11 to 13.2.0 in /extensions/ql-vscode
Bumps [lint-staged](https://github.com/okonet/lint-staged) from 10.2.11 to 13.2.0.
- [Release notes](https://github.com/okonet/lint-staged/releases)
- [Commits](https://github.com/okonet/lint-staged/compare/v10.2.11...v13.2.0)

---
updated-dependencies:
- dependency-name: lint-staged
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-15 09:22:59 +00:00
Koen Vlaswinkel
3d9f55ffea Merge pull request #2174 from github/dependabot/npm_and_yarn/extensions/ql-vscode/webpack-5.76.0
Bump webpack from 5.73.0 to 5.76.0 in /extensions/ql-vscode
2023-03-15 10:20:43 +01:00
dependabot[bot]
ebd18cd245 Bump webpack from 5.73.0 to 5.76.0 in /extensions/ql-vscode
Bumps [webpack](https://github.com/webpack/webpack) from 5.73.0 to 5.76.0.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Commits](https://github.com/webpack/webpack/compare/v5.73.0...v5.76.0)

---
updated-dependencies:
- dependency-name: webpack
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
2023-03-15 02:21:22 +00:00
Robert
7571304fb2 Move viewAst to top level 2023-03-14 17:57:23 +00:00
Robert
764830e69d Move runVariantAnalysis to top level 2023-03-14 17:55:35 +00:00
Robert
9d59abd0a8 Move openReferencedFile to top level 2023-03-14 17:53:50 +00:00
Robert
165542d115 Move previewQueryHelp to top level 2023-03-14 17:51:57 +00:00
Robert
d8371708b3 Move compileAndRunQueryOnMultipleDatabases to top level 2023-03-14 17:49:58 +00:00
Robert
c3f4a012a9 Move DatabaseQuickPickItem to top level 2023-03-14 17:49:07 +00:00
Robert
e2e197f4d9 Move compileAndRunQuery to top level 2023-03-14 17:46:37 +00:00
Robert
c366342f95 Move showResultsForCompletedQuery to top level 2023-03-14 17:43:58 +00:00
Robert
b05977516e Move showResultsForComparison to top level 2023-03-14 17:43:07 +00:00
Andrew Eisenberg
444de8cc3d Merge pull request #2072 from github/aeisenberg/mrva-extension-packs
Inject extension pack dependencies into MRVA packs
2023-03-14 10:41:35 -07:00
Robert
ee759abea9 Move installOrUpdateThenTryActivate to top level 2023-03-14 17:40:39 +00:00
Robert
a8f67d72f5 Move getDistributionDisplayingDistributionWarnings to top level 2023-03-14 17:38:36 +00:00
Robert
118be4a19a Move installOrUpdateDistribution to top level 2023-03-14 17:36:30 +00:00
Robert
8d3ae78db2 Move installOrUpdateDistributionWithProgressTitle to top level 2023-03-14 17:34:10 +00:00
Robert
ada5f51e85 Move codeQlVersionRange to top level 2023-03-14 17:31:11 +00:00
Robert
82f4941415 Move shouldUpdateOnNextActivationKey to top level 2023-03-14 17:30:49 +00:00
Robert
23e1715c4a Move DistributionUpdateConfig to top level 2023-03-14 17:27:48 +00:00
Andrew Eisenberg
250dc15fe5 Add extension packs to variant analysis queries
This change allows the `codeQL.runningQueries.useExtensionPacks`
setting to be respected when running variant analysis queries. When
set to `all`, before uploading the generated query pack, all extension
packs in the workspace will be injected as dependencies into the qlpack
file.
2023-03-14 08:55:01 -07:00
Koen Vlaswinkel
c3b023cf4b Convert run variant analysis command to new commands package 2023-03-14 13:09:31 +01:00
Koen Vlaswinkel
52b00fe434 Merge branch 'main' into starcke/commands-registration 2023-03-14 12:55:25 +01:00
Koen Vlaswinkel
64d97aaf7e Merge pull request #2165 from github/koesie10/simpler-progress-task
Simpler `withProgress` calls
2023-03-14 12:06:59 +01:00
Koen Vlaswinkel
964640c757 Remove default location values in withProgress calls 2023-03-14 11:00:59 +01:00
Koen Vlaswinkel
3d354e1fb4 Merge pull request #2164 from github/koesie10/unify-command-runners
Unify `commandRunner` implementations
2023-03-14 09:54:16 +01:00
Koen Vlaswinkel
d92708e4a4 Merge pull request #2166 from github/koesie10/remove-babel-loader
Remove direct dependency on babel-loader
2023-03-14 09:54:06 +01:00
Dave Bartolomeo
6c3698bfb3 Merge pull request #2169 from github/dbartol/tee-logger
Use `TeeLogger` instead of `additionalLogLocation:` option
2023-03-13 17:49:13 -04:00
Dave Bartolomeo
a1d8aac391 Better handling of I/O errors when writing to side log 2023-03-13 17:34:53 -04:00
Dave Bartolomeo
56095d365c Fix test code 2023-03-13 17:28:53 -04:00
Dave Bartolomeo
fc8b13b8be Use TeeLogger instead of additionalLogLocation: option 2023-03-13 15:10:30 -04:00
Koen Vlaswinkel
3aa24ebb2c Remove direct dependency on babel-loader
The extension Webpack config does not use `babel-loader`, so we can
remove it as a direct dependency. `babel-loader` is still included in
our `node_modules` because Storybook depends on it, but the version is
now completely managed by Storybook rather than us.
2023-03-13 16:17:23 +01:00
Andrew Eisenberg
205327d8aa Merge pull request #2162 from github/aeisenberg/variant-analysis-tests 2023-03-13 07:37:26 -07:00
Koen Vlaswinkel
4969a08531 Make progress options optional
This will make the progress options passed to `withProgress` optional by
moving it to be the second argument and setting a default value for the
`location`. This will make it much easier to use from a variety of
commands.
2023-03-13 15:13:55 +01:00
Koen Vlaswinkel
2646716261 Remove args from ProgressTask
This removes the `args` from the `ProgressTask` passed to
`withProgress`. The `args` is only used by the
`commandRunnerWithProgress` and can easily be replaced by an anonymous
function that passes the `args` instead. This will simplify the
`ProgressTask` interface and make it easier to use.
2023-03-13 14:51:32 +01:00
Anders Starcke Henriksen
79d15cc602 Add comments. 2023-03-13 14:36:28 +01:00
Koen Vlaswinkel
a7bb74190f Unify commandRunner implementations
The `commandRunnerWithProgress` implementation isn't actually any
different from `commandRunner`, except for the call to `withProgress`
and support for an `outputLogger` argument. Therefore, this will simply
make `commandRunnerWithProgress` a wrapper around `commandRunner`,
removing quite some duplication in the process.
2023-03-13 14:10:00 +01:00
Anders Starcke Henriksen
d990f316d1 Fix tests. 2023-03-13 12:16:38 +01:00
Andrew Eisenberg
fe123b3187 Inject extension pack dependencies into MRVA packs
If the user requests that extension packs be included in their MRVA run,
then do the following:

1. Search the workspace for all extension packs
2. Add each extension pack as an explicit and direct dependency on
   the generated pack.

It is ok to use `*` as a dependency since we are guaranteed that
exactly one version of each injected extension pack dependency is
available when the pack is being compiled.

If we find multiple paths to an extension pack of the same name, this
is an error since it is ambiguous which path to use.
2023-03-10 11:15:36 -08:00
Andrew Eisenberg
5d85da5526 Refactor generateQueryPack
Creates a handful of new functions and adds documentation. This commit
has no behavioural changes.
2023-03-10 11:15:36 -08:00
Andrew Eisenberg
b3e642a2b4 Remove any references 2023-03-10 11:11:25 -08:00
Andrew Eisenberg
0d8df9ad88 Merge pull request #2065 from github/aeisenberg/run-with-all-data-extensions
Add ability to run query with data extensions
2023-03-10 08:09:19 -08:00
Koen Vlaswinkel
2457d4bd9d Remove command manager argument to variant analysis view 2023-03-10 16:56:06 +01:00
Koen Vlaswinkel
df86adbbfa Split variant analysis and extension commands 2023-03-10 16:49:30 +01:00
Koen Vlaswinkel
e97ffd2f27 Use command manager executeCommand 2023-03-10 16:37:20 +01:00
Koen Vlaswinkel
088e9aa958 Add command manager to app 2023-03-10 16:35:22 +01:00
Robert
e3d8dbc484 Merge pull request #2147 from github/robertbrignull/release-indenting
Fix indenting for sub-lists
2023-03-10 11:41:54 +00:00
Robert
6daa780fbe Merge branch 'main' into robertbrignull/release-indenting 2023-03-10 10:48:11 +00:00
Robert
c0f3adc5ff Merge pull request #2156 from github/robertbrignull/remoteResultsItemWithoutLogs
Introduce cancelledRemoteResultsItemWithoutLogs context value
2023-03-10 10:39:26 +00:00
Robert
0ab482a389 Merge branch 'main' into robertbrignull/remoteResultsItemWithoutLogs 2023-03-10 10:29:47 +00:00
Koen Vlaswinkel
103017d717 Merge pull request #2150 from github/koesie10/no-node-modules-copy
Do not copy `node_modules` when packaging
2023-03-10 10:34:00 +01:00
Koen Vlaswinkel
9048dfd251 Merge pull request #2151 from github/koesie10/packaging-error-message
Add check for error message for packaging.test.ts
2023-03-10 10:33:51 +01:00
Koen Vlaswinkel
807069e0c1 Merge pull request #2148 from github/koesie10/commands-package
Add commands package inside src directory
2023-03-10 10:32:32 +01:00
Nora
1fa976757c Merge pull request #2153 from github/nora/remove-unnecessary-activation-events
Remove unnecessary commands from `activationEvents`
2023-03-10 10:23:10 +01:00
Nora
694dcea49a Merge pull request #2154 from github/nora/split-commands-b
Extension Telemetry: Split `viewCfg`,`quickEval`, `openReferencedFile` command
2023-03-10 10:22:33 +01:00
Nora
83d14501fd Merge pull request #2142 from github/nora/split-commands-a
Extension Telemetry: Split `runVariantAnalysis` and `viewAst` command
2023-03-10 10:22:22 +01:00
Koen Vlaswinkel
555d99ca33 Merge branch 'main' into koesie10/commands-package 2023-03-10 10:19:58 +01:00
Koen Vlaswinkel
9dc3df74bb Merge branch 'main' into koesie10/no-node-modules-copy 2023-03-10 10:19:57 +01:00
Koen Vlaswinkel
877d11dbe6 Merge branch 'main' into koesie10/packaging-error-message 2023-03-10 10:19:41 +01:00
Nora
c0c7574891 Split openReferencedFile command 2023-03-10 08:55:55 +00:00
Nora
4fda4f71dd Split quickEval command 2023-03-10 08:55:54 +00:00
Nora
6356149e54 Split viewCfg command 2023-03-10 08:55:54 +00:00
Nora
7f32439786 split viewAst command 2023-03-10 08:55:33 +00:00
Nora
27434862c3 split runVariantAnalysis command 2023-03-10 08:55:33 +00:00
Nora
275c16d5b0 Remove codeQLDatabases.chooseDatabase command 2023-03-10 08:54:36 +00:00
Nora
5586a02b44 Remove not necessary commands from activation event 2023-03-10 08:54:36 +00:00
Andrew Eisenberg
baba68d0df Add back variant analysis tests
This commit adds back the variant analysis tests that were inadvertently
deleted after this commit

82ada54103/extensions/ql-vscode/src/vscode-tests/cli-integration/remote-queries/run-remote-query.test.ts (L67)

They are not identical to the removed tests. I refactored them so that
there is a single test function invoked three times with different
parameters.
2023-03-09 15:53:13 -08:00
Andrew Eisenberg
790a152f42 Merge branch 'main' into aeisenberg/run-with-all-data-extensions 2023-03-09 09:42:30 -08:00
Andrew Eisenberg
1db2bc048a Merge pull request #2159 from github/github-action/bump-cli
Bump CLI Version to v2.12.4 for integration tests
2023-03-09 08:17:19 -08:00
Charis Kyriakou
d9917cbe8b Fix date of last release on changelog (#2158) 2023-03-09 15:58:24 +00:00
Andrew Eisenberg
2bd9c8a732 Merge pull request #2149 from github/aeisenberg-patch-1
Add security experimental queries
2023-03-09 07:49:27 -08:00
github-actions[bot]
c8ec661dce Bump CLI version from v2.12.3 to v2.12.4 for integration tests 2023-03-09 15:47:48 +00:00
Charis Kyriakou
1158dfdb89 Merge pull request #2155 from github/version/bump-to-v1.8.1
Bump version to v1.8.1
2023-03-09 15:27:30 +00:00
Anders Starcke Henriksen
61974a7664 Register concrete command from extension. 2023-03-09 16:25:11 +01:00
Robert
155b83b540 Introduce remoteResultsItemWithoutLogs context value 2023-03-09 14:35:10 +00:00
github-actions[bot]
bc8d07bc33 Bump version to v1.8.1 2023-03-09 14:22:57 +00:00
Anders Starcke Henriksen
d87911a803 Basic implementation of command manager. 2023-03-09 14:15:27 +01:00
Koen Vlaswinkel
2d5c339e0e Add check for error message for packaging.test.ts
This will add a check to ensure that `showAndLogExceptionWithTelemetry`
is not called when downloading packs. This expectation is placed before
the check for `showAndLogInformationMessage` so that when the test
fails, the error message will be shown.
2023-03-09 11:16:04 +01:00
Koen Vlaswinkel
d151b2f5f9 Do not copy node_modules when packaging
We are no longer including our dependencies in the VSIX package, so we
can tell VSCE that we don't want it to look at dependencies using
`--no-dependencies`. If we do this, VSCE doesn't require the
`node_modules` directory anymore and we can skip that step, which will
make building significantly faster.

I've confirmed that there are no changes between the two options by
building the extension both without and with the change. This is the
diff of the two outputs (using `diff -r`):

```diff
diff --color -r vscode-codeql-1.8.0-dev.2023.3.8.15.10.13/extension/package.json vscode-codeql-old/extension/package.json
7c7
<   "version": "1.8.0-dev.2023.3.8.15.10.13",
---
>   "version": "1.8.0-dev.2023.3.8.15.6.51",
diff --color -r vscode-codeql-1.8.0-dev.2023.3.8.15.10.13/extension.vsixmanifest vscode-codeql-old/extension.vsixmanifest
4c4
< 			<Identity Language="en-US" Id="vscode-codeql" Version="1.8.0-dev.2023.3.8.15.10.13" Publisher="GitHub" />
---
> 			<Identity Language="en-US" Id="vscode-codeql" Version="1.8.0-dev.2023.3.8.15.6.51" Publisher="GitHub" />
```

The only difference is the version number, which is expected.
2023-03-08 16:18:55 +01:00
Andrew Eisenberg
7bc6276115 Update .github/codeql/codeql-config.yml
Co-authored-by: Charis Kyriakou <charisk@users.noreply.github.com>
2023-03-08 07:10:53 -08:00
Andrew Eisenberg
a5021dc4c9 Add security experimental queries 2023-03-08 07:08:30 -08:00
Koen Vlaswinkel
77dd9bff94 Add commands package inside src directory 2023-03-08 15:35:14 +01:00
Charis Kyriakou
56111b39fc Merge pull request #2146 from github/v1.8.0
Some checks failed
Release / Release (push) Has been cancelled
Release / Publish to VS Code Marketplace (push) Has been cancelled
Release / Publish to Open VSX Registry (push) Has been cancelled
v1.8.0
2023-03-08 13:48:14 +00:00
Robert
0b6d828fa0 Fix indenting for sub-lists 2023-03-08 13:25:38 +00:00
Charis Kyriakou
d22be729be v1.8.0 2023-03-08 13:22:40 +00:00
Charis Kyriakou
9490642522 Merge pull request #2144 from github/charisk/mrva-public-beta
Prepare for MRVA public beta
2023-03-08 12:21:40 +00:00
Charis Kyriakou
643c106fbd Add controller repo 'learn more' link 2023-03-07 16:41:04 +00:00
Charis Kyriakou
9a308f6602 Update CHANGELOG to include MRVA 2023-03-07 16:41:04 +00:00
Charis Kyriakou
582c917541 Update README to include MRVA 2023-03-07 16:41:04 +00:00
Charis Kyriakou
e3625c982f MRVA execution not behind canary 2023-03-07 16:41:04 +00:00
Charis Kyriakou
6f37f176e4 MRVA repositories panel not behind canary 2023-03-07 16:41:04 +00:00
Charis Kyriakou
90b0911ed3 Update release process to lock/unlock the main branch (#2143) 2023-03-07 15:06:43 +00:00
Charis Kyriakou
84506d7340 Merge pull request #2141 from github/charisk/docs-tidy
Tidy up docs
2023-03-07 15:06:03 +00:00
Robert
d8c2562bb1 Move listener registration to webview.tsx 2023-03-07 15:05:49 +00:00
Charis Kyriakou
d480056c68 Move test plan near other docs 2023-03-07 11:40:12 +00:00
Charis Kyriakou
c3d28e395c Move testing docs to separate file 2023-03-07 11:37:00 +00:00
Charis Kyriakou
840cfbf3f6 Move releasing docs to separate doc file 2023-03-07 11:33:46 +00:00
Koen Vlaswinkel
d3466c3a72 Merge pull request #2136 from github/koesie10/upgrade-to-husky-8
Upgrade to Husky 8
2023-03-07 10:16:36 +01:00
Andrew Eisenberg
0ecde78d6e Fix test comments 2023-03-06 18:05:38 -08:00
Andrew Eisenberg
e07208b089 Merge remote-tracking branch 'upstream/main' into aeisenberg/run-with-all-data-extensions 2023-03-06 15:10:19 -08:00
Robert
7176f690f3 Add listeners for unhandled errors to web views 2023-03-06 17:22:06 +00:00
Charis Kyriakou
22aa77ff4c Fix VS Marketplace badge (#2138) 2023-03-06 16:00:49 +00:00
Koen Vlaswinkel
a6f189b144 Upgrade to Husky 8 2023-03-06 11:21:19 +01:00
Alexander Eyers-Taylor
2217d3f21f Give the LanguageClient an easier id to use. (#2135) 2023-03-03 17:26:08 +00:00
Koen Vlaswinkel
9703d10b32 Merge pull request #2122 from github/koesie10/remove-as-unknown-as-quickpickitem
Remove `as unknown as QuickPickItem`
2023-03-03 16:40:21 +01:00
Robert
53492b5202 Merge pull request #2115 from github/robertbrignull/cleanup_new_telemetry
Cleanup config to enabling new telemetry
2023-03-03 14:13:47 +00:00
Robert
082a00e81b Cleanup config to enabling new telemetry 2023-03-03 11:55:12 +00:00
Robert
e9bbf112f3 Merge pull request #2125 from github/robertbrignull/error_listener
Report unhandled errors, but only those that are from our extension
2023-03-03 11:34:31 +00:00
Robert
9386817727 Report unhandled errors from our extension 2023-03-02 17:19:40 +00:00
dependabot[bot]
68ce7c3b53 Bump actions/upload-artifact from 2 to 3 (#2133)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 2 to 3.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v2...v3)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-03-02 15:03:58 +00:00
Koen Vlaswinkel
a0ba1126cb Merge pull request #2131 from github/koesie10/fix-delete-local-query
Fix error while deleting query history item
2023-03-02 14:08:26 +01:00
Koen Vlaswinkel
d574f3d94c Fix error while deleting query history item
When deleting a query history item and the "next" query is still
running, the `completedQuery` is `undefined`. This commit fixes it by
using optional chaining to ensure that the `completedQuery` is defined
before accessing its `successful` property.
2023-03-02 12:32:45 +01:00
Koen Vlaswinkel
b0cc4c28ed Merge remote-tracking branch 'origin/main' into koesie10/remove-as-unknown-as-quickpickitem 2023-03-02 12:27:31 +01:00
Koen Vlaswinkel
11b63f39b4 Merge pull request #2123 from github/koesie10/remove-unknown-database-item
Remove additional `as unknown as` for database items
2023-03-02 12:23:03 +01:00
Koen Vlaswinkel
216413e5d7 Merge pull request #2124 from github/koesie10/move-tests
Move variant analysis tests out from the CLI integration test suite
2023-03-02 12:22:39 +01:00
Charis Kyriakou
5555fcaded Merge pull request #2118 from github/charisk/variant-analysis-scrubbing
Clean up variant analyses from query history
2023-03-02 09:26:49 +00:00
Koen Vlaswinkel
68fb744eab Merge pull request #2085 from github/koesie10/fix-graphviz-wasm
Fix Graphviz WASM module not loading for graph viewer
2023-03-02 10:00:18 +01:00
Andrew Eisenberg
3de6a110ce Merge pull request #2130 from github/version/bump-to-v1.7.12
Bump version to v1.7.12
2023-03-01 13:06:10 -08:00
github-actions[bot]
dd19ebdfdb Bump version to v1.7.12 2023-03-01 19:07:38 +00:00
Andrew Eisenberg
6bbb14edd4 Merge pull request #2129 from github/v1.7.11
Some checks failed
Release / Release (push) Has been cancelled
Release / Publish to VS Code Marketplace (push) Has been cancelled
Release / Publish to Open VSX Registry (push) Has been cancelled
v1.7.11
2023-03-01 10:57:50 -08:00
Andrew Eisenberg
fb5675a7c5 Update extensions/ql-vscode/CHANGELOG.md
Co-authored-by: Aditya Sharad <6874315+adityasharad@users.noreply.github.com>
2023-03-01 10:42:26 -08:00
Andrew Eisenberg
82a2db9fec v1.7.11
Release prep and fix markdown linting warnings in test plan.
2023-03-01 18:33:51 +00:00
Andrew Eisenberg
25d85c3e61 Merge pull request #2128 from github/revert-2120-charisk/learn-more-controller-repo
Revert "Add controller repo 'learn more' link"
2023-03-01 09:43:20 -08:00
Andrew Eisenberg
81e6d8583a Merge pull request #2127 from github/revert-2121-charisk/mrva-public-beta
Revert "Move MRVA out of canary"
2023-03-01 09:35:42 -08:00
Andrew Eisenberg
ea9dede453 Merge pull request #2126 from github/charisk/cli-v2.12.3-hack
Hack to avoid CodeQL CLI v2.12.3
2023-03-01 09:33:21 -08:00
Charis Kyriakou
e9062551ee Revert "Add controller repo 'learn more' link (#2120)"
This reverts commit fd6cd1f2d2.
2023-03-01 17:03:24 +00:00
Charis Kyriakou
dd2e79477f Revert "Move MRVA out of canary " 2023-03-01 17:02:11 +00:00
Charis Kyriakou
e9787c2702 Hack to avoid CodeQL CLI v2.12.3 2023-03-01 16:26:49 +00:00
Koen Vlaswinkel
304330074d Add some additional safety to allowWasmEval 2023-03-01 17:17:27 +01:00
Koen Vlaswinkel
074229e2a0 Clarify some comments 2023-03-01 17:17:06 +01:00
Koen Vlaswinkel
b679c18b0b Move variant analysis results zip to be next to tests 2023-03-01 14:09:09 +01:00
Koen Vlaswinkel
c3799bdb5a Move variant analysis results manager tests to activated extension suite 2023-03-01 14:07:49 +01:00
Koen Vlaswinkel
daaeb5be3f Move some variant analysis manager test to activated extension suite 2023-03-01 14:03:00 +01:00
Koen Vlaswinkel
2b346b6873 Move variant analysis monitor tests to activated extension suite 2023-03-01 13:54:54 +01:00
Koen Vlaswinkel
1c6ecf4a5c Remove as unknown as FullDatabaseOptions 2023-03-01 13:11:32 +01:00
Koen Vlaswinkel
59cc93f94f Remove as unknown as DatabaseItem 2023-03-01 13:11:32 +01:00
Koen Vlaswinkel
db0fea3af5 Remove as unknown as QuickPickItem
This is definitely not a perfect solution since we're essentially just
moving the place where we're casting. However, because we have manually
made the types similar, this provides some type assurances where there
were none before. This also has the cast in only one place, which makes
it easier to find and fix in the future.
2023-03-01 12:21:14 +01:00
Charis Kyriakou
56d283f6d5 Merge pull request #2121 from github/charisk/mrva-public-beta
Move MRVA out of canary
2023-03-01 09:55:28 +00:00
Charis Kyriakou
fd6cd1f2d2 Add controller repo 'learn more' link (#2120) 2023-03-01 09:40:11 +00:00
Koen Vlaswinkel
b3d9804842 Only enable graph viewer in canary mode 2023-03-01 09:52:56 +01:00
Andrew Eisenberg
5843c40a37 Remove mention of search path in coment
Co-authored-by: Robert <robertbrignull@github.com>
2023-02-28 08:29:00 -08:00
Shati Patel
57a4a2f717 Merge pull request #2112 from github/github-action/bump-cli
Bump CLI Version to v2.12.3 for integration tests
2023-02-28 16:25:28 +00:00
Charis Kyriakou
ff0425d889 Update CHANGELOG to include MRVA 2023-02-28 15:02:37 +00:00
Elena Tanasoiu
5fd902257e Merge pull request #2111 from github/elena/update-tutorial-database-path
Update path to codespace tutorial database
2023-02-28 14:51:14 +00:00
Koen Vlaswinkel
d3e64539d0 Only allow WASM execution in results view 2023-02-28 15:22:23 +01:00
Charis Kyriakou
55761aa4ee Update README to include MRVA 2023-02-28 14:06:26 +00:00
Charis Kyriakou
1bf7fc148a MRVA execution not behind canary 2023-02-28 14:04:30 +00:00
Charis Kyriakou
590b839166 MRVA repositories panel not behind canary 2023-02-28 14:04:30 +00:00
Charis Kyriakou
06463a25e6 Clean up variant analyses directory 2023-02-28 13:02:37 +00:00
Charis Kyriakou
7b2ef6bf76 Pass both local queries and variant analyses dirs in query history scrubber 2023-02-28 13:02:01 +00:00
Koen Vlaswinkel
fd57133a41 Merge pull request #2103 from github/koesie10/mock-more-objects
Remove more instances of `as unknown as`
2023-02-28 13:44:41 +01:00
Nora
f39bbd325c Merge pull request #2119 from github/nora/cleanup-split-runquery
Remove new commands from command palette
2023-02-28 13:28:16 +01:00
Nora
9a53b637e8 Remove new commands from comman palette 2023-02-28 11:42:08 +00:00
Nora
eb25f31b9f Merge pull request #2117 from github/nora/split-run-query
Split usage of runQuery and runQueryOnMultipleDatabases
2023-02-28 12:26:39 +01:00
Nora
7188d8df41 reorder command 2023-02-28 11:01:44 +00:00
Robert
badbee1bfb Merge pull request #2101 from github/robertbrignull/unique-command-use-query
Add unique-command-use.ql
2023-02-28 09:15:18 +00:00
Elena Tanasoiu
2f92ea396a Merge pull request #2090 from github/elena/install-csv-depenedencies
Install dependencies for tutorial query in codespace
2023-02-27 20:24:04 +00:00
Elena Tanasoiu
1f4790bbb7 Use join as it's meant to be used
Co-authored-by: Andrew Eisenberg <aeisenberg@github.com>
2023-02-27 20:09:05 +00:00
Elena Tanasoiu
28abc1e3a6 Don't reparse Uri path
I was initially trying to understand why this method was failing due
to an unrelated error [1] so I ended up over-engineering the path
parsing.

We can use the path from the first workspace folder, like we do in
other places in the extension.

[1]: https://github.com/github/vscode-codeql/pull/2104
2023-02-27 20:09:05 +00:00
Elena Tanasoiu
9b7c3bc2bf Install dependencies for tutorial query in codespace
When a user goes through the Code Tour, we select a dummy `csv` database
for them to get them up and running.

Once they complete the code tour and would like to continue writing
queries, they will need to add their own database.

After they do that, we check the language of their new database and
generate a skeleton QL pack for them so that they don't need to create
these files by hand. See [1] for details.

This skeleton pack folder will be called
`codeql-custom-queries-<language>` and it comes with its own example
query: `example.ql`.

When we try to run this example query, the query gets confused about
which `dbscheme` to pick, as it sees a `qlpack.yml` file in the new
skeleton pack folder, as well as one in the existing `tutorial-lib`
folder.

So we'll need to get rid of the `tutorial-lib` folder in order to make room
for new queries to be run once the tour is complete.

This commit introduces a `handleTourDependencies` step which will
trigger a `codeql pack install` command in order to install real library
dependencies for `tutorial-queries`, since we no longer have the dummy
library in `tutorial-lib`.
2023-02-27 20:09:04 +00:00
Robert
4d73e1a068 Remove getLocationOrdinal 2023-02-27 17:46:49 +00:00
Robert
6f5ac5df4f Introduce getAUse 2023-02-27 17:45:24 +00:00
Robert
4c880dfb19 Fix typos 2023-02-27 17:42:43 +00:00
Robert
56e8d8aac7 Merge pull request #2114 from github/robertbrignull/enable_telemetry
Enable new telemetry by default
2023-02-27 16:46:41 +00:00
Robert
ced9f60949 Add documentation 2023-02-27 16:06:38 +00:00
Charis Kyriakou
4fa530d69d Check controller repo before we set it (#2116) 2023-02-27 16:01:39 +00:00
Robert
c0a65c994a Convert to alert only first usage, instead of all other usages 2023-02-27 15:54:38 +00:00
Nora
921d9d22e4 split usage of runQuery and runQueryOnMultipleDatabases 2023-02-27 15:53:00 +00:00
Robert
ead1869a7e Use PackageJson class 2023-02-27 15:30:45 +00:00
Robert
b1ddf89fe3 Update CHANGELOG.md 2023-02-27 15:23:36 +00:00
Robert
c37096bf2c Update changelog 2023-02-27 13:12:28 +00:00
Robert
4127be2905 Enable new telemetry by default 2023-02-27 13:07:10 +00:00
Charis Kyriakou
ce29768796 Minor changes to the test plan (#2113) 2023-02-27 12:59:06 +00:00
Charis Kyriakou
571d9d1424 Merge pull request #2109 from github/version/bump-to-v1.7.11
Bump version to v1.7.11
2023-02-27 11:54:51 +00:00
Koen Vlaswinkel
65e652b5e4 Fix mockResolvedValue not working with mocked objects 2023-02-27 11:59:11 +01:00
Koen Vlaswinkel
fd2b91d4d4 Remove casting to QueryHistoryConfig 2023-02-27 11:59:11 +01:00
Koen Vlaswinkel
dd4df012e9 Remove as unknown as ExtensionContext 2023-02-27 11:59:11 +01:00
Koen Vlaswinkel
af167c6d6e Remove as unknown as DatabaseManager
Unfortunately `Object.defineProperty` doesn't work on proxies, so I've
added an options object to `mockedObject` which allows passing in
methods that will return a value for a specific property.
2023-02-27 11:59:11 +01:00
Koen Vlaswinkel
551ed95fc8 Remove as unknown as QueryHistoryManager 2023-02-27 11:59:11 +01:00
Koen Vlaswinkel
9b1ca5136e Remove as unknown as WorkspaceFolder 2023-02-27 11:59:10 +01:00
Koen Vlaswinkel
fa5bad6946 Remove as unknown as TextEditor/TextDocument 2023-02-27 11:59:10 +01:00
github-actions[bot]
6229de8634 Bump CLI version from v2.12.2 to v2.12.3 for integration tests 2023-02-24 19:18:50 +00:00
Koen Vlaswinkel
4c14db951b Merge pull request #2102 from github/koesie10/mock-objects
Add new `mockedObject` function
2023-02-24 15:43:19 +01:00
Koen Vlaswinkel
bed4e8a060 Rename methods parameter to props 2023-02-24 15:28:01 +01:00
Elena Tanasoiu
2c6dc24525 Update path to codespace tutorial database
In https://github.com/github/codespaces-codeql/pull/12 we moved
the source for our tutorial database into `.tours` in order to
avoid confusing the user when we load the database into the
workspace, since they'd see two databases.

Since this is just the source, we'd like to hide it.
2023-02-23 17:08:20 +00:00
Charis Kyriakou
8d5a00dcc7 Remove obsolete config setting (#2110) 2023-02-23 16:47:30 +00:00
github-actions[bot]
3ea3cd8e9b Bump version to v1.7.11 2023-02-23 08:58:41 +00:00
Charis Kyriakou
a32b0736db Merge pull request #2108 from github/v1.7.10
Some checks failed
Release / Release (push) Has been cancelled
Release / Publish to VS Code Marketplace (push) Has been cancelled
Release / Publish to Open VSX Registry (push) Has been cancelled
v1.7.10
2023-02-23 08:54:39 +00:00
Charis Kyriakou
50b0926390 v1.7.10 2023-02-23 08:38:10 +00:00
Elena Tanasoiu
4be573c805 Merge pull request #2106 from github/elena/change-query
Update skeleton query
2023-02-22 12:14:23 +00:00
Elena Tanasoiu
8bf8adfc74 Fix default query for skeleton pack
We mark this query as `@kind problem`.

We'll need to change the query a bit to make it fit this type of ...
erm... kind.

This means the results view will be formatted to display the file name
next to each of the results.

We're also getting rid of any mentions of an empty block query since
that's no longer what it checks.
2023-02-22 11:57:01 +00:00
Robert
14f58df2fc Merge pull request #2107 from github/revert-2076-robertbrignull/unhandled_rejection
Revert "Add unhandled rejection listener"
2023-02-22 10:53:00 +00:00
Robert
c712b069b1 Revert "Add unhandled rejection listener" 2023-02-22 10:06:37 +00:00
Anders Starcke Henriksen
7b4b491a9d Merge pull request #2099 from github/starcke/qlpack-gen-rename
Starcke/qlpack gen rename
2023-02-21 16:34:47 +01:00
Koen Vlaswinkel
2a43ffb49a Add new mockedObject function
This will remove some instances where we're using `as unknown as T` and
replace them by a call to `mockedObject<T>()`. The `mockedObject`
function is a bit more explicit about what it does and has types which
ensure that the methods that are set on the object actually exist.

Unfortunately, we can't fully get rid of `as unknown as T` in the
`mockedObject` function. However, this construct is more localized and
does not need to be used in as many places. If we do enable an ESLint
rule to prevent the use of `as unknown as T`, I would feel comfortable
with disabling the rule for the `mockedObject` function.
2023-02-21 13:01:28 +01:00
Koen Vlaswinkel
5e51bb57f5 Merge pull request #2098 from github/koesie10/refactor-cli-arguments
Use options objects instead of multiple optional arguments in CLI methods
2023-02-21 12:55:35 +01:00
Robert
70ae7284f3 Add unique-command-use.ql 2023-02-21 11:09:15 +00:00
Charis Kyriakou
396fdb8c5b Update README files for database dirs (#2100) 2023-02-21 09:39:02 +00:00
Charis Kyriakou
51570c3ba3 Remove obsolete config settings (#2097) 2023-02-21 09:09:54 +00:00
Charis Kyriakou
403e893f93 Remove isVariantAnalysisReposPanelEnabled feature flag and old flows (#2096) 2023-02-21 08:52:50 +00:00
Anders Starcke Henriksen
ffd27d4207 Update text to reflect multiple pack names. 2023-02-21 09:41:34 +01:00
Anders Starcke Henriksen
94b81bae71 Rename qlpack.yml -> codeql-pack.yml in generator. 2023-02-21 09:40:49 +01:00
Elena Tanasoiu
61f4ce27da Merge pull request #2074 from github/elena/refactor-query-language
Consolidate the way we define query languages
2023-02-20 18:10:50 +00:00
Elena Tanasoiu
c2f7d38018 Fix spelling 2023-02-20 17:54:20 +00:00
Elena Tanasoiu
b635d914d0 Move types/query-language to common/query-language
And fix imports
2023-02-20 17:54:20 +00:00
Elena Tanasoiu
8b8912bc40 Import QueryLanguage from new file 2023-02-20 15:53:39 +00:00
Elena Tanasoiu
7a5bbb228a Move dbSchemeToLanguage into QueryLanguage file 2023-02-20 15:53:39 +00:00
Elena Tanasoiu
269af3ed23 Move constant in QueryLanguage type file 2023-02-20 15:53:39 +00:00
Elena Tanasoiu
50f50f59b4 Use new type in tests 2023-02-20 15:53:39 +00:00
Elena Tanasoiu
abbc13033d Use new type in dbSchemeToLanguage 2023-02-20 15:53:39 +00:00
Elena Tanasoiu
9508b629f5 Organise required packs by query language 2023-02-20 15:53:39 +00:00
Elena Tanasoiu
aabeba067a Replace VariantAnalysisQueryLanguage -> QueryLanguage 2023-02-20 15:53:37 +00:00
Elena Tanasoiu
73838ffc6c Introduce types folder 2023-02-20 15:48:59 +00:00
Charis Kyriakou
1ab34967a0 Merge pull request #2095 from github/version/bump-to-v1.7.10
Bump version to v1.7.10
2023-02-20 15:46:52 +00:00
Koen Vlaswinkel
0f90319691 Use an options object for runAsyncCodeQlCliCommand
This also removes the type for the `runTests` `options` argument since
it's only used in this definition and don't actually use the type
anywhere else.
2023-02-20 16:40:18 +01:00
Koen Vlaswinkel
8afdabdd53 Use an options object for runJsonCodeQlCliCommand 2023-02-20 16:37:48 +01:00
github-actions[bot]
624e24579e Bump version to v1.7.10 2023-02-20 12:27:39 +00:00
Charis Kyriakou
c6481ca6ff Merge pull request #2094 from github/v1.7.9
Some checks failed
Release / Release (push) Has been cancelled
Release / Publish to VS Code Marketplace (push) Has been cancelled
Release / Publish to Open VSX Registry (push) Has been cancelled
v1.7.9
2023-02-20 12:22:15 +00:00
Charis Kyriakou
3fbfa840ac v1.7.9 2023-02-20 11:58:32 +00:00
Charis Kyriakou
90ba3d4f29 Rename some files around local databases (#2093) 2023-02-20 09:46:10 +00:00
Charis Kyriakou
146f23f929 Cache schema validator for db config (#2092) 2023-02-17 15:32:00 +00:00
Koen Vlaswinkel
207c37c8de Merge pull request #2091 from github/koesie10/rename-remote-queries
Rename `remote-queries` directories to `variant-analysis`
2023-02-17 16:01:27 +01:00
Koen Vlaswinkel
9aff6ee5a9 Remove remaining references to remote-queries 2023-02-17 11:39:22 +01:00
Koen Vlaswinkel
39d91788dc Rename remote-queries directories to variant-analysis 2023-02-17 11:38:24 +01:00
Charis Kyriakou
c309bdc1b7 Unveil new variant analysis repositories panel (#2082) 2023-02-16 17:14:38 +00:00
Charis Kyriakou
f9851a3dbf Pre-select top-10 list in variant analysis repos panel (#2088) 2023-02-16 13:01:34 +00:00
Koen Vlaswinkel
1fad9f6b5e Merge pull request #2083 from github/koesie10/variant-analysis-history-item-label-tests
Add tests for variant analysis history item label
2023-02-16 11:17:57 +01:00
Elena Tanasoiu
d618a4e026 Merge pull request #2080 from github/shati-elena/fix-database-prompt
Don't offer to create skeleton pack for default database in CodeTour
2023-02-16 09:30:03 +00:00
Koen Vlaswinkel
feac82f52e Merge pull request #2084 from github/koesie10/remove-remote-queries
Remove remaining remote queries code
2023-02-16 09:57:09 +01:00
Charis Kyriakou
2c81d3cbb7 Correctly initialize App and DbManager in variant analysis tests (#2086) 2023-02-15 16:36:14 +00:00
Robert
64f1c8e0aa Merge pull request #2076 from github/robertbrignull/unhandled_rejection
Add unhandled rejection listener
2023-02-15 16:09:16 +00:00
Koen Vlaswinkel
bc51e7462b Fix Graphviz WASM module not loading for graph viewer
It seems that when we added the CSP policy to the webview, we did not
take into account that `d3-graphviz` uses `@hpcc-js/wasm` to load
Graphviz as a WASM module. This commit adds `'wasm-unsafe-eval'` to the
CSP policy to allow this.
2023-02-15 15:41:36 +01:00
Robert
2ebfea1292 Add unhandled rejection listener 2023-02-15 14:28:35 +00:00
Koen Vlaswinkel
defc3816e7 Fix test depending on user-specified label 2023-02-15 13:56:53 +01:00
Koen Vlaswinkel
6ff8aad2e9 Simplify query history type checks 2023-02-15 13:53:19 +01:00
Koen Vlaswinkel
4d1e61a94d Remove remote query text provider 2023-02-15 13:53:19 +01:00
Koen Vlaswinkel
8f9e420402 Remove remote queries types 2023-02-15 13:53:19 +01:00
Koen Vlaswinkel
6856d1b6a5 Rename exportSelectedRemoteQueryResults 2023-02-15 13:39:32 +01:00
Koen Vlaswinkel
ebe2f89ca6 Add tests for variant analysis history item label 2023-02-15 13:29:54 +01:00
Elena Tanasoiu
397be15b89 Don't offer to create skeleton pack for default database in CodeTour
This is step 3 in the Code Tour. At this point we don't need to create
the skeleton pack so let's disable that functionality.

Co-authored-by: Shati Patel <shati-patel@github.com>
2023-02-15 12:22:46 +00:00
Elena Tanasoiu
5933f097e7 Merge pull request #2078 from github/shati-elena/update-launch-json
Add an extra line for testing the codespace-codeql tour
2023-02-15 12:20:30 +00:00
Koen Vlaswinkel
0ec30ee854 Merge pull request #2079 from github/koesie10/markdown-generation-tests
Add tests for Markdown generation
2023-02-15 13:17:40 +01:00
Elena Tanasoiu
1b81e8662e Merge pull request #2081 from github/shati-elena/do-not-send-format-option-for-packadd
Don't send `--format` option for `codeql pack add` command
2023-02-15 12:00:00 +00:00
Elena Tanasoiu
993bebe213 Add an extra line for testing the codespace-codeql tour
If you uncomment this, you'll be able to test the codespace locally.

Co-authored-by: Shati Patel <shati-patel@github.com>
2023-02-15 11:35:21 +00:00
Elena Tanasoiu
ef8aa14307 Don't send --format option for codeql pack add command
By default, this is added when we call `runJsonCodeQlCliCommandWithAuthentication`.

However, `codeql pack add` doesn't support this option so we need to turn it off.

Co-authored-by: Shati Patel <shati-patel@github.com>
2023-02-15 11:34:47 +00:00
Robert
c6ee20b7fb Merge pull request #2075 from github/robertbrignull/enable-await-thenable
Enable eslint rule to disallow awaiting a non-thenable type
2023-02-15 11:26:26 +00:00
Koen Vlaswinkel
38eb9bbd89 Add tests for markdown generation 2023-02-15 11:46:09 +01:00
Robert
5f20ef3df1 Fix extra alert from merging in main 2023-02-15 10:30:21 +00:00
Robert
fc7d48bf3a Merge branch 'main' into robertbrignull/enable-await-thenable 2023-02-15 10:28:43 +00:00
Robert
f69a6c523b More unnecessary awaits 2023-02-15 10:24:02 +00:00
Elena Tanasoiu
95f46b3b3a Merge pull request #2055 from github/elena/download-ql-packs
Generate QL pack for CodeTour
2023-02-15 10:19:08 +00:00
Koen Vlaswinkel
47c7e9e101 Move text-utils to pure 2023-02-15 11:18:47 +01:00
Koen Vlaswinkel
c0dc710b30 Rename markdown-generation file 2023-02-15 11:17:09 +01:00
Koen Vlaswinkel
a96265643c Merge pull request #2073 from github/koesie10/remove-remote-queries-react
Remove remote queries React components
2023-02-15 11:15:31 +01:00
Elena Tanasoiu
ab29fb759f Copy changes and remove extra line 2023-02-15 09:59:15 +00:00
Koen Vlaswinkel
754f6b2d49 Merge pull request #2059 from github/koesie10/retry-tests
Retry VSCode integration tests
2023-02-15 10:44:03 +01:00
Koen Vlaswinkel
3a188faf40 Merge branch 'main' into koesie10/retry-tests 2023-02-15 10:17:23 +01:00
Koen Vlaswinkel
b20aeb3e2c Merge pull request #2058 from github/koesie10/improve-test-setup
Improve test setup
2023-02-15 10:15:45 +01:00
Andrew Eisenberg
256b806cd4 Remove skipIfTrue
Also, add a comment to the vscode settings file and describe how to use
it.
2023-02-14 14:47:39 -08:00
Elena Tanasoiu
086df15357 Use file system path
On windows, the `Uri.path` will return an extra folder, as we can see in the tests:

```
ENOENT: no such file or directory, open 'D:\C:\Users\RUNNER~1\AppData\Local\Temp\tmp-4784XPDQPb5jM6IW\test-ql-pack-ruby\qlpack.yml'
```

Let's use `Uri.fsPath` instead.
2023-02-14 19:09:22 +00:00
Andrew Eisenberg
c0c30b48af Merge remote-tracking branch 'upstream/main' into aeisenberg/run-with-all-data-extensions 2023-02-14 18:39:35 +00:00
Elena Tanasoiu
3e87a2d53c Remove directory from workspace by index
We were initially always removing the last folder in the workspace as
we assumed that would be the directory we use.

Now that we've switched to using a temporary directory, this is no longer
the case so we need to find the index of the directory in the list of
workspace folders and then use that index to remove the directory.
2023-02-14 18:05:01 +00:00
Elena Tanasoiu
f1227dd2eb Build directory URI using Uri.file instead of Uri.parse
`Uri.parse` will not work with Windows paths as it will consider `C:\path`
to indicate a file scheme (the "C:" part) and will complain about it.

With `Uri.file` we can build the URI without hitting this complication.
2023-02-14 18:01:05 +00:00
Elena Tanasoiu
a59a008d8e Use temporary directory for generator tests
This will hopefully work with Windows tests as well.
2023-02-14 17:12:31 +00:00
Robert
950a218c29 Enable eslint rule to disallow awaiting a non-thenable type 2023-02-14 17:10:16 +00:00
Elena Tanasoiu
1ae52ef1cc Mock storageUri for workspace in tests
So that we can provide this to the generator.
2023-02-14 15:13:51 +00:00
Andrew Eisenberg
851a42f5e3 Merge pull request #2066 from github/aeisenberg/update-settingsjson
Add some better sample env vars in settings.json
2023-02-14 06:53:36 -08:00
Elena Tanasoiu
d6ccc11135 Update tests to check we call the generator
We don't need to repeat the tests for the generator functionality
here. All we want to check is that the generator is triggered correctly.
2023-02-14 13:02:29 +00:00
Elena Tanasoiu
24eb8fd307 Store QL pack in workspace instead of VSCode storage
We're checking that the skeleton QL pack doesn't exist as a workspace
folder, so we should be creating this folder in the workspace as well.

Initially this was being created in VSCode's local storage.
2023-02-14 13:02:29 +00:00
Elena Tanasoiu
ce3e19a2d7 Mention that the query file is automatically generated 2023-02-14 13:02:29 +00:00
Elena Tanasoiu
c4bed4e8aa Simplify example query to make it work with all languages 2023-02-14 13:02:29 +00:00
Elena Tanasoiu
3464cd0cda Reword dialog box prompt
Co-authored-by: Andrew Eisenberg <aeisenberg@github.com>
2023-02-14 13:02:29 +00:00
Elena Tanasoiu
b04b3bf33e Reword packAdd output
Co-authored-by: Andrew Eisenberg <aeisenberg@github.com>
2023-02-14 13:02:28 +00:00
Elena Tanasoiu
a8f36ee9e8 Generate a QL pack when you add a new database, if one is missing 2023-02-14 13:02:28 +00:00
Elena Tanasoiu
6cda6534d1 Introduce a QlPackGenerator class
This will receive a folder name and language.

It will generate:
- a `codeql-pack.yml` file
- an `example.ql` file
- a `codeql-pack.lock.yml` file

It will also install dependencies listed in `codeql-pack.lock.yml`
file.

We were initially planning to call the `packInstall` command once
we generate `codeql-pack.yml` in order to install dependencies.

However, the `packAdd` command does this for us, as well as
generating a lock file.

Rather than trying to craft the lock file by hand, we're opting
to use the cli command.

NB: We're introducing a new `QueryLanguage` type which is identical
to the `VariantAnalysisQueryLanguage`. In a subsequent PR we'll
unify these two types.
2023-02-14 13:02:28 +00:00
Elena Tanasoiu
5a9d12ea60 Introduce wrapper for codeql pack add CLI command
Similar to what we do with `codeql pack install`.

Tnis will simulate us running `codeql pack add codeql/<language>-all`.

We're going to need in order to:
- generate a lock file (codeql-pack.lock.yaml)
- install the correct packages for our skeleton QL pack based on the
lock file.
2023-02-14 13:02:28 +00:00
Koen Vlaswinkel
f9ef9567cf Merge pull request #2071 from github/koesie10/remove-remote-queries-history-item
Remove remote queries history item
2023-02-14 13:11:04 +01:00
Koen Vlaswinkel
547e18bab9 Merge remote-tracking branch 'origin/main' into koesie10/remove-remote-queries-react 2023-02-14 12:16:41 +01:00
Koen Vlaswinkel
7d7a7060fa Merge pull request #2070 from github/koesie10/remove-remote-query-manager
Remove remote queries manager
2023-02-14 12:16:02 +01:00
Koen Vlaswinkel
16464d5e3a Merge pull request #2069 from github/koesie10/remove-remote-query-commands
Remove remote queries commands
2023-02-14 11:21:12 +01:00
Koen Vlaswinkel
c0ffd795e0 Remove remote queries React components 2023-02-14 10:28:51 +01:00
Koen Vlaswinkel
7508ef2e26 Move components used by MRVA out of remote-queries 2023-02-14 10:27:52 +01:00
Koen Vlaswinkel
fb4d6db03d Remove remote queries history item
This removes the remote queries history item as a supported history
item. This allows us to delete almost all code related to remote
queries except for the React view code which will be removed separately.

In the query serialization code, we now ignore remote queries.
2023-02-14 10:20:04 +01:00
Andrew Eisenberg
39e6b27676 Make linter happy 2023-02-13 21:11:14 -08:00
Andrew Eisenberg
d8435d113a Fix skipIfTrue
Also, update jsdoc for `resolveQlpacks`.
2023-02-13 14:30:29 -08:00
Andrew Eisenberg
d386d42f34 Add back comment 2023-02-13 09:55:25 -08:00
Koen Vlaswinkel
89860d4f84 Remove remote queries view 2023-02-13 16:01:39 +01:00
Koen Vlaswinkel
53ffdc30ce Remove remote queries manager 2023-02-13 15:57:10 +01:00
Koen Vlaswinkel
e5a48fb46f Merge pull request #2068 from github/koesie10/remove-run-remote-query
Remove code to start a remote query run
2023-02-13 15:46:10 +01:00
Koen Vlaswinkel
f6d7ddf5b3 Remove tests for remote query history 2023-02-13 15:44:58 +01:00
Koen Vlaswinkel
dbe9807ccc Remove codeQL.exportRemoteQueryResults command 2023-02-13 14:40:54 +01:00
Koen Vlaswinkel
b2ea12023c Remove codeQL.autoDownloadRemoteQueryResults command 2023-02-13 14:32:50 +01:00
Koen Vlaswinkel
255f1b6a5d Remove codeQL.copyRepoList command 2023-02-13 14:31:50 +01:00
Koen Vlaswinkel
dcdb303da7 Remove codeQL.monitorRemoteQuery command 2023-02-13 14:12:44 +01:00
Koen Vlaswinkel
096e8f6196 Remove code to start a remote query run
This removes the `runRemoteQuery` method on the remote queries manager,
all code that calls it and code which is now dead.
2023-02-13 14:00:35 +01:00
Charis Kyriakou
f7826c3254 Remove some as umknown as X usages (#2067) 2023-02-13 12:47:37 +00:00
Charis Kyriakou
ad03dfa0a9 Optimistically update the UI when user selects db/list (#2063) 2023-02-13 12:29:14 +00:00
Koen Vlaswinkel
930def851d Disable parallelization of tests
This would run the unit, view, integration and CLI integration tests in
parallel, which would cause problems with multiple VSCode instances and
use a lot of memory.
2023-02-13 12:02:21 +01:00
Koen Vlaswinkel
46670cc7d6 Clarify CLI integration test CI runs 2023-02-13 11:39:38 +01:00
Koen Vlaswinkel
b412896d54 Make purpose of no-workspace tests clearer 2023-02-13 11:39:07 +01:00
Koen Vlaswinkel
14eb6b4f89 Only download test DB for CLI integration tests
The test database is not required for activated extension tests, so we
only need to download the test database for CLI integration tests.
2023-02-13 11:37:11 +01:00
Charis Kyriakou
682a1e12bc Update copy for local db select button (#2062) 2023-02-13 09:53:48 +00:00
Charis Kyriakou
366965adbf Remove random capital letters (#2064) 2023-02-13 09:02:45 +00:00
Koen Vlaswinkel
3917b14a58 Merge remote-tracking branch 'origin/main' into koesie10/improve-test-setup 2023-02-13 09:21:39 +01:00
Andrew Eisenberg
722f5c5035 Add some better sample env vars in settings.json 2023-02-10 15:55:16 -08:00
Andrew Eisenberg
6f435300e8 Add ability to run query with data extensions
- Add a new config that toggles between using all data extensions or
  none.
- If using all data extensions, then before a query evaluation, run a
  `codeql resolve qlpacks` command with the new `--kind` option. This
  will return a list of extension packs in the workspace.
- Pass these packs to the cli before evaluation/
- This will only work with CLI v2.12.3 (not yet released) or later.
- Also include some CLI tests to ensure this works.
2023-02-10 15:51:07 -08:00
Charis Kyriakou
57f9ff68f8 Remove remote queries integration tests (#2060) 2023-02-10 14:56:12 +00:00
Charis Kyriakou
b599885b1c Update edit db config icon (#2061) 2023-02-10 14:40:43 +00:00
Charis Kyriakou
514dd7afe3 New db item/list selection UX for variant analysis repo panel (#2053) 2023-02-10 14:38:08 +00:00
Koen Vlaswinkel
ce56e6f038 Retry VSCode integration tests
This will call `jest.retryTimes` to retry the VSCode integration tests
up to 3 times. This should help with the flaky tests.
2023-02-10 10:43:48 +00:00
Koen Vlaswinkel
0138df5da8 Merge pull request #2051 from github/koesie10/filter-vscode-output
Hide VSCode console output
2023-02-09 15:36:59 +01:00
Koen Vlaswinkel
212273791b Merge pull request #2054 from github/koesie10/codeql-pack-yml
Handle `codeql-pack.yml` files everywhere
2023-02-09 15:36:00 +01:00
Koen Vlaswinkel
6ed5c2a583 Merge remote-tracking branch 'origin/main' into koesie10/filter-vscode-output 2023-02-09 09:48:24 +00:00
Koen Vlaswinkel
752b6a7f8a Add tests for getQlPackPath 2023-02-08 17:17:10 +00:00
Koen Vlaswinkel
34bdbd158d Move qlpack functions/constants to pure 2023-02-08 17:12:22 +00:00
Koen Vlaswinkel
c71238c6d2 Merge pull request #2052 from github/koesie10/source-map-script-from-release-asset
Download sourcemaps from release asset if available
2023-02-08 14:49:28 +01:00
Koen Vlaswinkel
202c93b580 Merge pull request #2049 from github/koesie10/upload-sourcemaps-release
Upload sourcemaps as release asset
2023-02-08 14:46:39 +01:00
Koen Vlaswinkel
b03efa4f24 Merge remote-tracking branch 'origin/main' into koesie10/source-map-script-from-release-asset 2023-02-08 13:31:28 +00:00
Koen Vlaswinkel
1198a05776 Merge remote-tracking branch 'origin/main' into koesie10/upload-sourcemaps-release 2023-02-08 13:31:13 +00:00
Koen Vlaswinkel
642b8e5960 Add documentation for new test suite and scripts 2023-02-08 13:28:18 +00:00
Andrew Eisenberg
2b816f9f0f Merge pull request #2056 from github/github-action/bump-cli
Bump CLI Version to v2.12.2 for integration tests
2023-02-08 05:26:49 -08:00
Koen Vlaswinkel
708af3cbb9 Merge pull request #2057 from github/koesie10/version-number-advice
Add recommendation for version number bumps
2023-02-08 14:16:29 +01:00
Koen Vlaswinkel
6b8467fc4e Update test script names 2023-02-08 13:14:00 +00:00
Koen Vlaswinkel
a9c36ea699 Create new activated-extension test suite 2023-02-08 11:52:55 +00:00
Koen Vlaswinkel
ef1fe756cb Add recommendation for version number bumps 2023-02-08 11:21:33 +00:00
github-actions[bot]
977e3c099d Bump CLI version from v2.12.1 to v2.12.2 for integration tests 2023-02-07 21:39:28 +00:00
Koen Vlaswinkel
7d6461a10a Handle codeql-pack.yml files everywhere
This will add support for the `codeql-pack.yml` filename in all places
where we currently support `qlpack.yml`. It centralizes the list of the
supported filenames in a single place and a method that can figure out
the correct filename to use.
2023-02-07 17:55:50 +00:00
Koen Vlaswinkel
f3f8de0e60 Merge remote-tracking branch 'origin/main' into koesie10/source-map-script-from-release-asset 2023-02-07 17:29:07 +00:00
Koen Vlaswinkel
81502fefec Merge pull request #2039 from github/koesie10/source-map-script-stacktrace
Add source map support for full stacktraces
2023-02-07 18:04:14 +01:00
Koen Vlaswinkel
ac127b3a3d Merge remote-tracking branch 'origin/main' into koesie10/source-map-script-from-release-asset 2023-02-07 17:00:48 +00:00
Koen Vlaswinkel
465da69ecf Merge remote-tracking branch 'origin/main' into koesie10/source-map-script-stacktrace 2023-02-07 16:38:44 +00:00
Koen Vlaswinkel
648e6745a8 Merge pull request #2037 from github/koesie10/source-map-script
Add script for retrieving original source location
2023-02-07 17:37:19 +01:00
Koen Vlaswinkel
5b9c09c958 Download sourcemaps from release asset if available
This download download the sourcemaps from the release asset if it is
available. Unfortunately, I'm not able to test this yet because we don't
yet have any releases with sourcemaps attached. As a fallback, it will
still try to download from the workflow run.
2023-02-07 15:16:10 +00:00
Koen Vlaswinkel
943229f065 Merge pull request #2033 from github/koesie10/mocked-config
Mock config instead of writing settings files
2023-02-07 15:50:32 +01:00
Koen Vlaswinkel
c42cd9059d Hide information about VSCode exit code and download 2023-02-07 14:45:50 +00:00
Koen Vlaswinkel
f7fb6a4920 Merge remote-tracking branch 'origin/main' into koesie10/mocked-config 2023-02-07 14:33:53 +00:00
Koen Vlaswinkel
5e8c2fa6db Hide VSCode console output
Most of the warnings that are currently being shown in CI are coming
from VSCode. We can hide the VSCode output to make the CI logs more
readable. This should not influence the tests; the output of tests
(in particular using `console.log`/`console.error` etc.) will still be
shown.

See: 0c98dc12ad/packages/jest-runner-vscode/src/public-types.ts (L58-L68)
2023-02-07 14:30:07 +00:00
Elena Tanasoiu
f7ab8b7ba0 Merge pull request #2042 from github/elena/add-more-test-coverage
Add test coverage for `openDatabase`
2023-02-07 14:03:09 +00:00
Elena Tanasoiu
b2fa85f5c5 Merge pull request #2036 from github/shati-elena/create-skeleton
Introduce command for creating skeleton QL packs
2023-02-07 12:49:13 +00:00
Elena Tanasoiu
72f3847a3e Add tests for openDatabase function 2023-02-07 11:45:01 +00:00
Elena Tanasoiu
f8d0f689a6 Move functions into class so they can be mocked
We'd like to add test coverage for the openDatabase function (which is
public).

At the moment, this relies on `resolveDatabaseContents` which is just
a standalone function.

This means we're unable to mock it using Jest.

So let's move it into its own class.

This method in turn depends on a `resolveDatabase` function, which we've
also moved into the new class.

The only usages I could find for there functions were from within
the `databases.ts` file.
2023-02-07 11:26:33 +00:00
Elena Tanasoiu
235fb83e8c Don't check for specific number of calls on callback
This is unrelated to the changes in this PR but it's causing CI to fail.

```
config listeners › CliConfigListener › should listen for changes to 'codeQL.runningTests.numberOfThreads'

    expect(jest.fn()).toHaveBeenCalledTimes(expected)

    Expected number of calls: 1
    Received number of calls: 2

      109 |           const newValue = listener[setting.property as keyof typeof listener];
      110 |           expect(newValue).toEqual(setting.values[1]);
    > 111 |           expect(onDidChangeConfiguration).toHaveBeenCalledTimes(1);
          |                                            ^
      112 |         });
      113 |       });
      114 |     });
```

We don't need to check that the callback is triggered a certain number of times, just that it works
so we can change this test to be more permissive.
2023-02-07 11:25:11 +00:00
Elena Tanasoiu
5c89952999 "select" -> "add" 2023-02-07 11:23:40 +00:00
Elena Tanasoiu
397aa2befe Mention language in pop-up message 2023-02-07 11:23:40 +00:00
Elena Tanasoiu
63add84bf3 Use triple equals 2023-02-07 11:23:40 +00:00
Elena Tanasoiu
037596cfb4 Create skeleton QL pack if in CodeTour
We'd like to make it easier for a user going through the CodeQL Tour to
write their queries.

To help them along, we can generate skeleton QL packs once we know which
database they're using, instead of expecting them to know how to create
this themselves.

We're then able to download the necessary dependencies for their CodeQL
queries.

This checks that we're running the CodeTour by looking for the
`codeQL.codespacesTemplate` setting.
2023-02-07 11:23:39 +00:00
Elena Tanasoiu
a85281e365 Be able to pass custom db options to mock
We will use this to set/unset the language on a database item.

This will then be used to determine whether we need to create a QL pack.
2023-02-07 11:23:39 +00:00
Elena Tanasoiu
99f3d28640 Introduce helper method to detect folder in workspace 2023-02-07 11:23:39 +00:00
Elena Tanasoiu
41256ec9fd Make it a little clearer which function the tests are checking 2023-02-07 11:23:39 +00:00
Koen Vlaswinkel
74581fb8e3 Merge pull request #2046 from github/koesie10/rename-last-commit-to-last-updated
Rename "Last commit" to "Last updated"
2023-02-07 12:15:04 +01:00
Koen Vlaswinkel
483d674da1 Upload sourcemaps as release asset
This will upload the sourcemaps produced as part of the release as a
release asset. This allows the sourcemaps to be downloaded and used
for decoding stack traces beyond the 90 day artifact limit of GitHub
Actions.
2023-02-07 11:06:03 +00:00
Koen Vlaswinkel
cff3d9508e Merge remote-tracking branch 'origin/main' into koesie10/rename-last-commit-to-last-updated 2023-02-07 11:00:31 +00:00
Robert
24e4708477 Merge pull request #2017 from github/robertbrignull/logged_error_telemetry
Introduce showAndLogExceptionWithTelemetry
2023-02-07 10:00:14 +00:00
Koen Vlaswinkel
4f0032d77b Merge pull request #2045 from github/koesie10/link-to-actions-workflow
Add link to Actions workflow when running MRVA
2023-02-07 10:48:22 +01:00
Robert
420fd8d48a Merge branch 'main' into robertbrignull/logged_error_telemetry 2023-02-07 09:42:54 +00:00
Charis Kyriakou
a901369c5e Enable eqeqeq ESLint rule and fix violations (#2043) 2023-02-07 09:36:18 +00:00
Elena Tanasoiu
b05697c327 Merge pull request #2044 from github/elena/remove-lint
Don't lint on `git push`
2023-02-07 09:23:11 +00:00
Koen Vlaswinkel
0cbc9916fc Rename "Last commit" to "Last updated"
Last commit is confusing because it's actually the `updated_at` of the
repository. By renaming it, this will be clearer to users.
2023-02-06 17:54:31 +00:00
Koen Vlaswinkel
f57b811585 Add link to Actions workflow when running MRVA 2023-02-06 17:46:35 +00:00
Elena Tanasoiu
0b9dcb44d9 Don't lint on git push
We run `npm run lint` every time we do a `git push`.

This takes quite a long time, and the lint command has already been run
when we created the commit in the first place.

Could we instead skip this and rely on CI to tell us if we've failed
to address a linting issue?
2023-02-06 17:36:24 +00:00
Koen Vlaswinkel
a5b95944fc Add radix to parseInt 2023-02-06 17:13:23 +00:00
Koen Vlaswinkel
6d1c66b121 Add example to source map script 2023-02-06 17:09:56 +00:00
Koen Vlaswinkel
740cbc8dee Make onDidChangeConfiguration less strict
It seems like the `onDidChangeConfiguration` is being called multiple
times. It doesn't actually matter that it's being called twice, so we
just need to ensure it's called at least once.
2023-02-06 17:02:18 +00:00
Koen Vlaswinkel
c9f0d1b525 Merge remote-tracking branch 'origin/main' into koesie10/mocked-config 2023-02-06 16:21:09 +00:00
shati-patel
66fd8ad6cc Rename const to refer to the codespaces template in general 2023-02-06 11:13:10 +00:00
shati-patel
d0d48dfd08 Add feature flag for codespaces-codeql template workspace
We'll use this flag for commands that are specific to the tutorial code tour and "quick setup" in https://github.com/github/codespaces-codeql
2023-02-06 11:13:10 +00:00
Andrew Eisenberg
0dd741fa9b Merge pull request #2035 from github/version/bump-to-v1.7.9
Bump version to v1.7.9
2023-02-03 08:43:32 -08:00
Elena Tanasoiu
9c2aa8c7fa Merge pull request #2032 from github/shati-elena/check-for-ql-pack
Small tidy-up: Rename test file for databaseFetcher tests
2023-02-03 16:40:51 +00:00
github-actions[bot]
09e7a84597 Bump version to v1.7.9 2023-02-03 16:26:19 +00:00
Elena Tanasoiu
6e53ed020c Rename tests for databaseFetcher
These are not testing anything in the databases.ts file as we're
invoking functions from the DatabaseFetcher.

Let's name the file accordingly
2023-02-03 16:20:07 +00:00
Elena Tanasoiu
0eff27731e Merge pull request #2041 from github/elena/skip-failing-tests
Skip failing tests
2023-02-03 16:17:50 +00:00
Elena Tanasoiu
f276a3414a Skip failing tests
This is blocking us from merging new PRs so while we figure out
how to fix them, let's skip the tests that are failing on our
`main` branch.

For full context: the tests started failing when a new version of
VSCode was released (1.75.0).
2023-02-03 15:54:36 +00:00
Koen Vlaswinkel
0ed03c14bf Add source map support for full stacktraces
This adds support for mapping full stacktraces in the source map
script. This allows you to pass a full stacktrace to the script and get
back a stacktrace with all original positions.
2023-02-03 15:21:57 +01:00
Koen Vlaswinkel
92e2975c24 Add script for retrieving original source location
This adds a script that can be used for retrieving the original source
location when given a location in the released extension. It will
download the source map from the Actions workflow run of the release and
use the `source-map` library to extract the original location.
2023-02-03 12:15:57 +01:00
Koen Vlaswinkel
bc181c6c9b Only set CLI path in workspace configuration 2023-02-03 11:36:40 +01:00
Koen Vlaswinkel
beb0058365 Mock env.openExternal instead of overriding it 2023-02-03 11:29:29 +01:00
Robert
7a9b8bbdde Merge pull request #2034 from github/v1.7.8
Some checks failed
Release / Release (push) Has been cancelled
Release / Publish to VS Code Marketplace (push) Has been cancelled
Release / Publish to Open VSX Registry (push) Has been cancelled
v1.7.8
2023-02-02 16:59:00 +00:00
Robert
d2c795bec0 Update extensions/ql-vscode/CHANGELOG.md
Co-authored-by: Shati Patel <42641846+shati-patel@users.noreply.github.com>
2023-02-02 16:38:03 +00:00
Robert
d144874e77 v1.7.8 2023-02-02 16:30:46 +00:00
Koen Vlaswinkel
cac0add788 Mock config instead of writing settings files
In our tests, we were writing settings files to disk because we were
using the VSCode configuration API which writes settings to files. This
results in flaky tests because concurrency can cause the VSCode API to
misbehave.

This will switch the tests to use a mocked API by default. For some
tests the real implementation is used, but the large majority of tests
is now using a mocked version which only keeps track of the
configuration in memory. This makes it easier to reset the state between
tests since we can just empty out the in-memory configuration.
2023-02-02 16:51:02 +01:00
Elena Tanasoiu
c493425046 Merge pull request #2027 from github/elena/select-db-in-codespace
Introduce command to set default Code Tour database
2023-02-02 12:05:27 +00:00
Charis Kyriakou
302091f2c5 Added version to db config (#2029) 2023-02-02 11:50:16 +00:00
Robert
05d9f9b3a6 Add test that error messages are redacted 2023-02-02 11:11:52 +00:00
Robert
69b7e04ec0 Put error logging behind new secret flag 2023-02-02 11:11:49 +00:00
Robert
9184bde8a6 Merge branch 'main' into robertbrignull/logged_error_telemetry 2023-02-02 10:46:41 +00:00
Elena Tanasoiu
99d794c2a8 Update error message
Co-authored-by: Andrew Eisenberg <aeisenberg@github.com>
2023-02-02 10:30:01 +00:00
Elena Tanasoiu
b6aa41d19b Replace undefined check with length check 2023-02-02 10:27:22 +00:00
Elena Tanasoiu
6257608433 Add comment to indicate which folder we're pointing to 2023-02-02 10:27:22 +00:00
Elena Tanasoiu
6ebeb2b201 Introduce command to set default Code Tour database
We have a codespace template which houses our CodeQL tour:
https://github.com/github/codespaces-codeql

This contains a repo with a default databases already loaded
for the user so that they can start writing queries more quickly.

At the moment we're asking the user to manually right click on
the database folder ('codeql-tutorial-database') and set it as
the current database.

We can take this one step further by defining a command that gets
triggered when we arrive at the step for setting up the database.

The command ("codeQL.setDefaultTourDatabase") will build the URI
pointing to our preloaded database and set it as the current one.

We initially considered whether we can re-use the setCurrentDatabase
command and pass the URI of the database from the codespace itself,
but the URI would be hardcoded as:

```
file://0-62/workspaces/codespaces-codeql/codeql-tutorial-database
```

as we can only pass the codeTour extension a command and string
parameters.

This would have been brittle as the filepath for a codespace might
change in the future.

Instead we can define a custom tour command ("setDefaultTourDatabase")
to look at the current workspace folder and build the path to the
database in the CodeQL extension.

Co-authored-by: Shati Patel <shati-patel@github.com>
2023-02-02 10:27:22 +00:00
Nora
9f240c8500 Merge pull request #2028 from github/nora/polish-url-helper
DP Panel: Drop protocol check when creating a new item
2023-02-01 20:17:18 +01:00
Koen Vlaswinkel
d4b061115b Merge pull request #2031 from github/koesie10/gh-pr-create
Use first-party action for creating release PR
2023-02-01 15:41:52 +01:00
Koen Vlaswinkel
15382a02bc Use first-party action for creating release PR
Instead of using the third party `peter-evans/create-pull-request`
action for creating a PR for releases, we can use the already present
`./.github/actions/create-pr` action which is also used for the PR for
bumping CLI versions.
2023-02-01 14:39:00 +01:00
Robert
c3050fc324 Merge pull request #2030 from github/robertbrignull/disable-new-telemetry
Don't send new telemetry data unless opted-in
2023-02-01 12:21:12 +00:00
Nora
4c54778515 Allow usage of www.github.com 2023-02-01 11:34:49 +00:00
Nora
72412c92c8 Allow usage of github.com 2023-02-01 11:32:57 +00:00
Robert
d780c24994 Don't send new telemetry data unless opted-in 2023-02-01 11:19:11 +00:00
Koen Vlaswinkel
fa8def3c8c Merge pull request #2025 from github/koesie10/mrva-view-title
Update variant analysis view title
2023-02-01 09:37:55 +01:00
Koen Vlaswinkel
ad38d6d1ce Merge pull request #2023 from github/koesie10/db-panel-controller-repo-welcome
Show welcome view when controller repo is not setup
2023-01-31 17:01:00 +01:00
Charis Kyriakou
23a8468a26 Update the copy for the codeQLVariantAnalysisRepositories.removeItemContextMenu command (#2026) 2023-01-31 15:36:21 +00:00
Nora
9e54e5eced Drop protocol check 2023-01-31 14:18:12 +00:00
Koen Vlaswinkel
dbca4456a8 Change variant analysis view title 2023-01-31 11:55:04 +01:00
Koen Vlaswinkel
ecc5fa1e4e Extract MRVA view title generation to method
We had duplicated logic for generating the variant analysis view title.
This extracts it to a single method so the title are always in sync.
2023-01-31 11:53:22 +01:00
Koen Vlaswinkel
7ec4b4bc96 Merge pull request #2024 from github/koesie10/eslint-config
Unify ESLint configuration
2023-01-31 11:50:07 +01:00
Koen Vlaswinkel
ba11781165 Move welcome view test to rendering test 2023-01-31 11:43:55 +01:00
Nora
3fa7bec323 Merge pull request #2021 from github/nora/fix-placeholder
Fix placeholder copy
2023-01-31 09:52:21 +01:00
Robert
1120f2fca8 Fix tests 2023-01-30 16:58:11 +00:00
Robert
2f573aba0c Remove accidental spaces from error message string 2023-01-30 16:23:35 +00:00
Koen Vlaswinkel
a3c6b362f8 Remove unnecessary disabled rules
These rules are already disabled in the base config, so they don't need
to be disabled individually anymore.
2023-01-30 16:55:05 +01:00
Koen Vlaswinkel
5f382a5677 Combine ESLint configurations
Instead of having different ESLint configuration files in each
directory which don't seem to inherit the configuration correctly, this
will add `overrides` in the root file.
2023-01-30 16:43:19 +01:00
Koen Vlaswinkel
6114b591c5 Fix tests when no controller repo is set
This also extracts the helper to do so into a separate function to avoid
duplicating this logic.
2023-01-30 15:52:19 +01:00
Nora
87465a65ae Merge pull request #2022 from github/nora/remove-history-item-hover
Query History Item: remove on hover
2023-01-30 14:44:39 +01:00
Koen Vlaswinkel
b3c4979358 Show welcome view when controller repo is not setup
This will add a welcome view to the database panel which is shown when
the controller repository is not setup. This welcome view will show a
button which can be used to set up the controller repository.
2023-01-30 14:28:22 +01:00
Nora
3ba13a32e3 Remove query item on hover 2023-01-30 13:07:47 +00:00
Nora
3dc2cec5b6 Update copy 2023-01-30 10:39:42 +00:00
Robert
72c8e0bcb6 Convert RedactableError to an Error class of its own 2023-01-27 17:36:56 +00:00
Koen Vlaswinkel
160a6cca76 Use redactable error message for telemetry events 2023-01-27 11:50:40 +01:00
Koen Vlaswinkel
4edb83163d Create tagged template for error messages 2023-01-27 11:50:12 +01:00
Robert
fbe0df59be Fix typos 2023-01-27 10:32:03 +00:00
Koen Vlaswinkel
ddddd2f0b9 Merge pull request #2018 from github/koesie10/download-progress-indicator
Add download progress indicator for MRVA downloads
2023-01-27 10:14:32 +01:00
Koen Vlaswinkel
5098382afb Merge pull request #2014 from github/koesie10/download-progress
Report download progress when downloading variant analysis results
2023-01-27 10:14:08 +01:00
Koen Vlaswinkel
7dd5b0a826 Decrease download update delay
3 seconds is a really long time to wait for downloads since a
significant percentage of downloads will complete within 3 seconds. This
changes the update delay to 500ms which should still give us good
performance, but also make the download feel more responsive.
2023-01-26 17:11:42 +01:00
Koen Vlaswinkel
94968f41e7 Fix response size calculation
The `response.size` is almost always set to `0`. However, the
`Content-Length` header is returned by Azure and contains the size of
the file.
2023-01-26 17:11:40 +01:00
Nora
5ca409797d Merge pull request #2013 from github/nora/extract-scrubber-tests
Extract query history scrubber tests
2023-01-26 17:00:26 +01:00
Koen Vlaswinkel
c7bd9f9394 Add determinate progress ring 2023-01-26 16:47:37 +01:00
Robert
db0d41a305 Introduce showAndLogExceptionWithTelemetry 2023-01-26 15:38:03 +00:00
Nora
2264b6b983 Merge pull request #2016 from github/nora/query-history-context-menu
Query History: context menu copy and groups
2023-01-26 16:33:29 +01:00
Nora
012157a57a Remove unused code 2023-01-26 13:48:56 +00:00
Nora
940169e2a0 Extract query history scrubber tests 2023-01-26 13:48:56 +00:00
Nora
6ebb4affec Use groups and new copy 2023-01-26 13:41:09 +00:00
Koen Vlaswinkel
0efbbbfef1 Add test for download progress reporting 2023-01-26 13:36:04 +01:00
Koen Vlaswinkel
610a623bc5 Fix download tests 2023-01-26 13:36:04 +01:00
Koen Vlaswinkel
37c9414dad Use async appendFile 2023-01-26 13:36:04 +01:00
Robert
6cf351f332 Output percentage during results download 2023-01-26 13:36:04 +01:00
Robert
07f5d2b20d Merge pull request #2010 from github/robertbrignull/logging_types
Introduce ShowAndLogOptions
2023-01-26 11:21:28 +00:00
Robert
51a72227e9 Merge pull request #2011 from github/robertbrignull/catch_unknown
Enforce that promise rejection values must have unknown type
2023-01-26 10:39:55 +00:00
Robert
e9345dc588 Move documentation to type instead of methods 2023-01-26 10:37:23 +00:00
Nora
2acaf31287 Merge pull request #2007 from github/nora/query-history-sort-button
Query History: sorting
2023-01-26 10:43:20 +01:00
Nora
9a572a3c71 Merge pull request #2008 from github/nora/split-query-history-file
Query History: split file
2023-01-26 10:38:20 +01:00
Nora
1f52642308 Fix rebase problems 2023-01-26 09:21:04 +00:00
Nora
af7ec57b72 Fix rename in comments 2023-01-26 10:07:31 +01:00
Nora
c993d30b34 Split query history file 2023-01-26 10:07:31 +01:00
Robert
13dd5298bf Enforce that promise rejection values must have unknown type 2023-01-25 16:34:47 +00:00
Robert
de640e347d Introduce ShowAndLogOptions 2023-01-25 16:29:30 +00:00
Nora
ca1d63a3fc Merge pull request #2006 from github/nora/update-old-panel-icons
Update icons of old DB panel
2023-01-25 16:58:09 +01:00
Robert
5c5c2e485d Show download percentage in UI 2023-01-25 16:35:08 +01:00
Robert
2dc45ae5f6 Add downloadPercentage to VariantAnalysisScannedRepositoryState 2023-01-25 16:35:08 +01:00
Robert
ad6cbe60fd Merge pull request #1989 from github/robertbrignull/credentials_in_app
Add credentials to App
2023-01-25 15:15:30 +00:00
Nora
c1392e5c68 Update copy 2023-01-25 13:58:45 +00:00
Nora
dcfa990adb Use vscode icon for edit 2023-01-25 13:54:48 +00:00
Nora
89483a7b43 Use vscode icon for preview 2023-01-25 13:52:40 +00:00
Nora
bc6b829d17 Use vscode icon for trash 2023-01-25 13:50:13 +00:00
Nora
2c701e0663 Inline shorting in menu 2023-01-25 13:49:56 +00:00
Nora
0771e93c1e Use vscode icons 2023-01-25 11:34:42 +00:00
Nora
64e73c6426 Merge pull request #2005 from github/nora/update-panel-remote-icon
DB panel: use cloud icon for variant analysis repositories
2023-01-25 11:52:09 +01:00
Nora
cf2dec9577 Merge pull request #2004 from github/nora/update-query-history-icons
Query history polish: new icons
2023-01-25 11:51:55 +01:00
Robert
9e25d19924 Fix merge conflict 2023-01-25 10:41:40 +00:00
Nora
5342b5b83a Fix tests for error color 2023-01-25 10:19:49 +00:00
Robert
c5494b6fd2 Merge branch 'main' into robertbrignull/credentials_in_app 2023-01-25 10:15:29 +00:00
Nora
1ec39053cb Replace remote icon with cloud 2023-01-25 09:55:53 +00:00
Nora
0936185d2f Replace remote database icon 2023-01-25 09:47:07 +00:00
Nora
ec9b5fe1d3 Replace local database icon 2023-01-25 09:47:06 +00:00
Nora
3c56c549bc Replace error icon 2023-01-25 09:47:06 +00:00
Nora
407aa14d4d Merge pull request #2002 from github/elena-nora/move-query-history-files
Move query history files to new folders
2023-01-25 10:36:25 +01:00
Nora
76a35deb66 Move query history files to new folders 2023-01-24 17:04:25 +00:00
Nora
d6ab2292e0 Merge pull request #2001 from github/nora/query-history-empty-state
Query history polish: update empty state
2023-01-24 18:01:05 +01:00
Robert
8e80106b4f Add documentation 2023-01-24 15:40:38 +00:00
Robert
697a004005 Combine test credentials methods into testCredentialsWithRealOctokit 2023-01-24 15:40:21 +00:00
Nora
4f2b1af811 Update copy 2023-01-24 15:13:57 +00:00
github-actions[bot]
8ed826c78c Bump CLI Version to v2.12.1 for integration tests (#1999) 2023-01-24 10:36:15 +00:00
Koen Vlaswinkel
f7a9830455 Merge pull request #1788 from github/koesie10/remove-unsupported-version-constraints
Remove unsupported version constraints
2023-01-24 10:49:51 +01:00
Robert
1381cb67d6 Merge pull request #1997 from github/robertbrignull/use_as_error
Make use of asError instead of reimplementing
2023-01-23 17:15:59 +00:00
Robert
cc76ca80da Don't change compileAndRunQuery 2023-01-23 16:05:18 +00:00
Robert
3316d1712d Make use of asError instead of reimplementing 2023-01-23 15:49:31 +00:00
Koen Vlaswinkel
140d369098 Remove unsupported version constraints
This removes all CodeQL CLI version constraints for unsupported CLI
versions (< 2.7.6). The oldest supported CLI version is 2.7.6 since GHES
3.3 recommends using CodeQL CLI 2.7.6.
2023-01-23 14:13:05 +01:00
Shati Patel
2c19b32cb3 Minor polish to the "bump CLI" automation (#1996) 2023-01-20 18:42:20 +00:00
github-actions[bot]
3ce6735475 Bump CLI Version to v2.12.0 for integration tests (#1995) 2023-01-20 17:54:30 +00:00
Taj
c7f72c5aa9 Ensure cli using latest version from the supported_cli_versions.json (#1992) 2023-01-20 17:13:14 +00:00
Elena Tanasoiu
a17e41cbf1 Merge pull request #1993 from github/elena/extend-tests
Add remote queries and variant analyses to our serialization tests
2023-01-20 15:14:48 +00:00
Charis Kyriakou
3b5b85caed Disable select item button in new db panel (#1994) 2023-01-20 13:45:15 +00:00
Nora
708e55244e Merge pull request #1991 from github/nora/order-context-menu-actions
Sort and group context menu actions
2023-01-20 13:42:54 +01:00
Elena Tanasoiu
b58d82e53a Fix typo 2023-01-20 12:15:35 +00:00
Elena Tanasoiu
a2df1eaee4 Add remote queries and variant analyses to our serialization tests
This was just testing local queries.
2023-01-20 12:11:06 +00:00
Charis Kyriakou
d7fae741ae Merge pull request #1990 from github/charisk/disable-local-dbs
Turn off support for local dbs and remote root 'remote' node from new db panel
2023-01-20 11:29:08 +00:00
Nora
dadd3499ac Sort and group context menu actions 2023-01-20 11:02:03 +00:00
Charis Kyriakou
526c4f3ab7 Remove root 'remote' node 2023-01-20 09:53:23 +00:00
Charis Kyriakou
65623c07a2 Turn off support for local dbs in new panel 2023-01-20 09:53:23 +00:00
Charis Kyriakou
8a6b361e84 Fix rename that went too far (#1988) 2023-01-19 09:09:58 +00:00
Andrew Eisenberg
bd74b410f6 Merge pull request #1973 from github/tjgurwara99/bump-cli-extension
Modifying the `bump-cli` workflow to append/replace version from `supported_cli_versions.json`
2023-01-18 09:54:47 -08:00
Robert
03993f376f Add credentials to App 2023-01-18 17:36:38 +00:00
Elena Tanasoiu
4dc1b12785 Merge pull request #1984 from github/elena/move-tests
Move tests for serialization/deserialization in their own file
2023-01-18 17:29:27 +00:00
Charis Kyriakou
c2dcfe92bc Update db panel rendering tests to not rely on order of root nodes (#1987) 2023-01-18 17:47:35 +01:00
Charis Kyriakou
1bd749dee0 Convert integration tests to unit tests (#1986) 2023-01-18 16:42:38 +00:00
Elena Tanasoiu
e97a7c4993 Move tests for serialization/deserialization in their own file
We didn't have a query-serialization.test.ts file. Now we do.

We can build on these tests when we begin to save other types of data.
2023-01-18 12:21:39 +00:00
Nora
13389fd35f Merge pull request #1983 from github/nora/db-panel-add-item
Extract db panel add items tests to new file
2023-01-18 13:17:23 +01:00
Nora
9c011c5fd1 Create testfile in no workspaces and copy paste 2023-01-18 12:36:45 +01:00
Nora
f97dbb136d Merge pull request #1981 from github/nora/db-panel-selection
Extract db panel selection tests to new file
2023-01-18 12:35:59 +01:00
Taj
f154b59b14 description for version 2023-01-18 11:10:44 +00:00
Charis Kyriakou
ec1cf015bf Removed unnecessary awaits (#1982) 2023-01-18 10:58:37 +00:00
Nora
79289802c0 Create new selection test file and copy paste tests 2023-01-18 10:42:57 +00:00
Nora
e1bc8ae95a Merge pull request #1980 from github/nora/db-panel-rendering
Extract db panel render tests to new file
2023-01-18 11:41:39 +01:00
Robert
0bd6ba7898 Merge pull request #1978 from github/robertbrignull/compare_view_telemetry
Telemetry for compare view
2023-01-18 10:13:57 +00:00
Robert
84c6c1ef6b Merge pull request #1976 from github/robertbrignull/local_results_telemetry
Emit telemetry for user interactions in the local results view
2023-01-18 10:13:20 +00:00
Nora
5b6587cc18 Create new file and copy paste tests 2023-01-18 10:07:52 +00:00
Shati Patel
e230bf47d0 When adding repo, check whether name exists in specified parent list (#1977) 2023-01-18 10:01:47 +00:00
Nora
6c523db0ad Merge pull request #1975 from github/nora/review-user-messages
Polish user facing messages
2023-01-18 10:05:19 +01:00
Robert
37e3e041e8 Piggyback on changeSort message 2023-01-17 16:46:02 +00:00
Robert
3a4ce9abb1 Telemetry for compare view 2023-01-17 16:34:30 +00:00
Koen Vlaswinkel
b0168aa04a Merge pull request #1964 from github/koesie10/packages-auth
Use stdin for supplying auth to CodeQL
2023-01-17 17:30:25 +01:00
Robert
4009f03dd2 Send telementry on other links and UI elements 2023-01-17 15:49:50 +00:00
Taj
160ee22d1b combined version change and bump-cli workflow 2023-01-17 14:32:19 +00:00
Nora
fe17f61b5e Rename remote to variant analysis 2023-01-17 14:18:24 +00:00
Nora
c5722d7aa2 Merge pull request #1972 from github/nora/expanded-tests
Add test for behaviour around expanded state
2023-01-17 14:23:15 +01:00
Robert
f1dbc22a9a output telemtry from local results view on state changes 2023-01-17 12:58:11 +00:00
Robert
10776759c7 Support telemetry from local results view 2023-01-17 12:55:50 +00:00
Nora
e6c6e8a2be Merge comments 2023-01-17 12:30:11 +00:00
Nora
07868d90e9 Remove unneeded expectations and adjust test 2023-01-17 10:14:08 +00:00
Nora
40f08393b2 Add test for expanded state cleanup 2023-01-17 10:14:08 +00:00
Nora
c6c7b71b8a Add test for renaming expanded items 2023-01-17 10:14:08 +00:00
Nora
0bccdbb8d6 Add tests for adding and removing item to expanded state 2023-01-17 10:14:08 +00:00
Robert
611f6e39e0 Merge pull request #1953 from github/robertbrignull/telemetry_ui
Report telemetry on actions taken in the UI
2023-01-17 09:36:06 +00:00
Elena Tanasoiu
a1f5e5b277 Merge pull request #1944 from github/elena/fix-removal
Display modal when removing an item from query history
2023-01-17 08:57:03 +00:00
Koen Vlaswinkel
7b5e5a6407 Merge pull request #1963 from github/koesie10/webpack-production-build
Use Webpack in production mode for releases
2023-01-17 09:49:59 +01:00
Koen Vlaswinkel
2957979b15 Update comment for CodeQL CLI authentication 2023-01-17 09:35:48 +01:00
Koen Vlaswinkel
e8799ad275 Handle race condition when authenticating to the CLI 2023-01-17 09:31:58 +01:00
Taj
bfa6780529 first pass at automating appending/prepending/removing version from supported cli versions 2023-01-16 22:06:15 +00:00
Elena Tanasoiu
80f588c5c8 Merge pull request #1971 from github/elena/rename-splat-slurp
Rename `splat/slurp` to `serialize/deserialize`
2023-01-16 17:41:34 +00:00
Elena Tanasoiu
57b6c9bb2c Don't mention splat/slurp in comments or descriptions 2023-01-16 17:20:22 +00:00
Elena Tanasoiu
80dfe4ba69 Rename slurpQueryHistory -> deserializeQueryHistory 2023-01-16 17:20:22 +00:00
Elena Tanasoiu
06bc4c8fe3 Rename splatQueryHistory -> serializeQueryHistory 2023-01-16 17:20:22 +00:00
Elena Tanasoiu
c62f381a2f Remove extra log message 2023-01-16 17:19:26 +00:00
Elena Tanasoiu
3547fdfd54 Add tests for modal behaviour
Tests whether we choose "Yes" / "No" in the new modal window.

"Yes" -> remove the item and show you a toast notification
"No" -> don't remove item

This only shows up for in progress items.
2023-01-16 17:19:25 +00:00
Elena Tanasoiu
ab0e67c251 Split removal tests based on state of query
We now have special behaviour for removing an "in progress" query so the
tests will be different.

Let's have a separate section for "in progress" queries. We'll add extra
behaviour testing in the next commit.
2023-01-16 17:19:25 +00:00
Elena Tanasoiu
fa1f355b93 Show dialog with "Are you sure?" for in-progress queries
When you attempt to delete a query that's still in progress from your
query history, you get a prompt asking if you're sure.

If you pick "Yes", the item is removed and you see a toast notification
with a link towards the GitHub Action.
2023-01-16 17:19:25 +00:00
Robert
3777eb382f Make isCanary a string 2023-01-16 16:56:30 +00:00
Nora
4cb3c4cb50 Merge pull request #1968 from github/nora/rename-db-config-file
Rename DbConfigFile and Schema
2023-01-16 17:46:54 +01:00
Robert
44a0cad146 Make useTelemetryOnChange signature simpler 2023-01-16 16:44:32 +00:00
Robert
293ec1f204 Add debounce to variant-analysis-selected-repository-ids 2023-01-16 16:36:00 +00:00
Robert
38cbb95ecc Avoid === true on a boolean 2023-01-16 16:34:13 +00:00
Robert
18ddb3a297 Use isCanary() method 2023-01-16 16:12:20 +00:00
Robert
2453038387 Merge branch 'main' into robertbrignull/telemetry_ui 2023-01-16 16:10:18 +00:00
Charis Kyriakou
856e516b20 Renamed Run Query command (#1962) 2023-01-16 15:48:06 +00:00
Nora
6f78fffd10 Merge comments 2023-01-16 15:23:48 +00:00
Charis Kyriakou
957f6a023c Mark App interface properties as read-only (#1969) 2023-01-16 15:20:28 +00:00
Nora
afcb84fcd8 Rename db config file 2023-01-16 10:58:28 +00:00
Nora
c19f58b0e3 Rename schema file 2023-01-16 10:22:55 +00:00
Nora
7f1bcedf9b Extract config file to constant 2023-01-16 10:11:00 +00:00
Shati Patel
817db85c36 Add "describe" blocks around db-panel tests (#1965) 2023-01-16 10:07:35 +00:00
Koen Vlaswinkel
b4bb1b6ad7 Upload sourcemaps for release builds
To allow us to reconstruct a stack trace, this will upload the
sourcemaps for all release builds.
2023-01-16 10:58:00 +01:00
Andrew Eisenberg
ecbb0fb232 Merge pull request #1871 from tjgurwara99/main
Workflow to automatically bump cli version if different from the current version
2023-01-13 13:14:14 -08:00
Taj
365519af63 fix: src dir to test dir 2023-01-13 19:11:53 +00:00
Taj
ef1444617d Merge branch 'main' of github.com:tjgurwara99/vscode-codeql 2023-01-13 16:00:22 +00:00
Taj
c72734e49a fix: replaced with newer version since the PR was open 2023-01-13 15:59:39 +00:00
Taj
7f05af942b Merge branch 'github:main' into main 2023-01-13 14:00:41 +00:00
Koen Vlaswinkel
20a06238a2 Use stdin for supplying auth to CodeQL
This will supply the GitHub access token to certain CodeQL CLI commands
such that private packages can be resolved. It will only do so if the
user has an existing auth session. If they don't, they will now get a
prompt to login. However, this will only happen for commands which
actually use authentication, which is limited to packaging commands.
2023-01-13 15:02:51 +02:00
Taj
91dc39b465 added the bump-cli.yml file to trigger the workflow when changed 2023-01-13 12:58:28 +00:00
Koen Vlaswinkel
f6f8b68ce9 Use Webpack in production mode for releases
This will set the `mode` of Webpack to `production` for release builds.
It will also stop inlining the sourcemap and instead produce a separate
file which is excluded by `.vscodeignore`.

In terms of the bundled extension, this will add 1 file
(`out/webview.js.LICENSE.txt`). It decreases the size of the VSIX file
from 4.28MB to 1.77MB.
2023-01-13 14:23:51 +02:00
Robert
47f63f6df6 Implement debounce for telemetry events 2023-01-13 12:17:15 +00:00
Robert
98a29d2459 Convert useStateWithTelemetry to useTelemetryOnChange 2023-01-13 12:17:13 +00:00
Koen Vlaswinkel
f82fde35ee Merge pull request #1799 from github/koesie10/bundle-extension
Bundle extension files using ESBuild
2023-01-13 14:13:35 +02:00
Robert
e9830ee854 Add telemetry message to remote queries view 2023-01-13 11:21:10 +00:00
Shati Patel
277da3c971 Rename feature flag (#1961) 2023-01-13 11:07:26 +00:00
Charis Kyriakou
78e01e6f92 Rename db config terms to use 'variant analysis' instead of remote (#1960) 2023-01-13 09:30:45 +00:00
Nora
4ae77351c8 Merge pull request #1949 from github/nora/rename-expanded-methods
Minor refactoring for expanded things
2023-01-12 17:00:11 +01:00
Nora
5c40293c06 Revert "Rename arguments"
This reverts commit 85b7e0eabad1092792ff336b8ccff4fdef04e034.
2023-01-12 15:15:57 +00:00
Nora
ba830dd2e5 Fix expanded bug when renaming lists 2023-01-12 15:15:57 +00:00
Nora
c36da4ba7e Rename arguments 2023-01-12 15:15:57 +00:00
Nora
b9740fe582 Use individual functions for add and remove from expanded state 2023-01-12 15:15:56 +00:00
Charis Kyriakou
09c60ecfc8 Improve docs around different test suites (#1959) 2023-01-12 15:15:24 +00:00
Nora
8b661c7a6d Merge pull request #1947 from github/nora/db-config-store-tests
Improve tests coverage in db-config-store
2023-01-12 14:25:54 +01:00
Nora
94823a6c75 Disable filewatcher for tests 2023-01-12 12:53:12 +00:00
Nora
010e85c28b Merge comments 2023-01-12 13:44:34 +01:00
Nora
ed11b20cb7 Add tests for does exist methods 2023-01-12 12:43:30 +00:00
Nora
8cb0cd23dd Add test for set selected item 2023-01-12 12:43:30 +00:00
Nora
9f5e9653da Add tests for add 2023-01-12 12:43:30 +00:00
Shati Patel
2b7d2d0610 Increase timeout for "variant analysis submission" test (#1958) 2023-01-12 12:04:26 +00:00
Shati Patel
e322bf829a Add db manager tests for "removeDbItem" functionality (#1948) 2023-01-12 11:59:25 +00:00
Robert
25a3ba76ed Extract on-click handlers to consts 2023-01-12 11:01:10 +00:00
Robert
0aa2cd6e90 Make Telemetry.ts lowercase 2023-01-12 10:58:01 +00:00
Charis Kyriakou
67fa920d4d Merge pull request #1957 from github/charisk/rename-new-db-panel
Rename new db panel to 'Variant Analysis Repositories'
2023-01-12 10:55:08 +00:00
Shati Patel
b54dfe9b58 Fix flaky test: avoid file watcher in db manager tests (#1951) 2023-01-12 10:51:46 +00:00
Charis Kyriakou
4f588d9def Remove obsolete test file (#1955) 2023-01-12 10:38:57 +00:00
Charis Kyriakou
1c3a6154c9 Rename the id for the new db panel to 'codeQLVariantAnalysisRepositories' 2023-01-12 09:20:35 +00:00
Charis Kyriakou
a21382b053 Rename the user-visible name for the new db panel to 'Variant Analysis Repositories' 2023-01-12 08:49:24 +00:00
Andrew Eisenberg
6f168459a2 Merge pull request #1933 from github/aeisenberg/codeql-pack-yml
Ensure remote queries can handle codeql-pack.yml files
2023-01-11 15:55:15 -08:00
Andrew Eisenberg
77c6706320 Ensure remote queries can handle codeql-pack.yml files
This updates one of our integration tests so that it uses
`codeql-pack.yml` instead of `qlpack.yml`.
2023-01-11 14:36:43 -08:00
Shati Patel
3fe3117c39 Temporarily skip flaky test (#1954)
We're working on a fix, but this will unblock CI in the meantime
2023-01-11 16:24:35 +00:00
Robert
e163e0625d Merge pull request #1952 from github/robertbrignull/open_logs_command
Convert opening variant analysis logs to a command
2023-01-11 15:37:28 +00:00
Robert
f1a8564db4 Output telemetry when clicking links 2023-01-11 14:50:25 +00:00
Robert
34e98c4cc5 Convert useStateWithTelemetry to use useMemo 2023-01-11 14:50:25 +00:00
Robert
f325eeb5ab Output telemetry on react state changes in MRVA results view 2023-01-11 14:50:24 +00:00
Robert
bdfb2f29da Add method to loging telemetry of a UI interaction 2023-01-11 14:48:14 +00:00
Robert
9d457304b1 Convert opening variant analysis logs to a command 2023-01-11 14:35:40 +00:00
Koen Vlaswinkel
bb63dc52c9 Fix debugging not working
VSCode was not able to find the original source of the bundled
extension because it was looking for the source in the `out` directory.
By setting the `sourceRoot` to the `extensions/ql-vscode` directory
which is located at `..` from the `out` directory, VSCode is able to
find the original source and breakpoints are hit.
2023-01-11 12:13:55 +02:00
Koen Vlaswinkel
033d653d44 Fix types in CodeFlowsDropdown 2023-01-11 11:56:50 +02:00
Koen Vlaswinkel
6bf19eb52f Use case-insensitive path comparison on Windows 2023-01-11 11:29:23 +02:00
Koen Vlaswinkel
477b32662f Copy WASM file from source-map
This will copy the WASM file from source-map to the output directory.
This makes the source-map package work. See the comment in the code for
more details.
2023-01-11 10:43:45 +02:00
Koen Vlaswinkel
65696997de Add correct binding of sourcemap instance 2023-01-11 10:43:45 +02:00
Koen Vlaswinkel
d79b105751 Remove fs mocking from cli-integration tests 2023-01-11 10:43:44 +02:00
Koen Vlaswinkel
1f9e28e09d Remove fs mocking from minimal-workspace tests 2023-01-11 10:43:43 +02:00
Koen Vlaswinkel
0d8c90a7b5 Remove fs mocking from no-workspace tests 2023-01-11 10:43:24 +02:00
Koen Vlaswinkel
f13f0b3bc3 Bundle extension files using ESBuild
This bundles the extension files using esbuild, as recommended by
VSCode. This reduces the size of the extension from 34MB to less than
5MB.

Gulp will still run TypeScript to check types, but will not use the
TypeScript compiler output in the bundle.

Tests are now run separately, outside of Gulp, so their data doesn't
need to be copied anymore.

See: https://code.visualstudio.com/api/working-with-extensions/bundling-extension
2023-01-11 10:42:24 +02:00
Charis Kyriakou
0b6f2c248b Refactor logic to remove db or list from config (#1946) 2023-01-11 08:41:58 +00:00
Shati Patel
9cf508837e Add db manager tests for "rename" functions (#1939)
Co-authored-by: Charis Kyriakou <charisk@users.noreply.github.com>
2023-01-10 14:00:47 +00:00
Nora
ed2bdd8a43 Merge pull request #1925 from github/nora/add-remove-context-action
Add remove context menu action
2023-01-10 09:09:51 +01:00
Robert
82ce7bc874 Merge pull request #1943 from github/robertbrignull/telemetry_race_condition
Avoid race condition requesting telemetry permissions
2023-01-09 17:38:00 +00:00
Robert
7bbbf8b986 Merge pull request #1942 from github/robertbrignull/telemetryListener_undefined
Acknowledge that telemetryListener may be undefined
2023-01-09 17:09:32 +00:00
Robert
aa950eed6a Avoid race condition requesting telemetry permissions 2023-01-09 16:54:32 +00:00
Robert
f9777016a7 Acknowledge that telemetryListener may be undefined 2023-01-09 16:19:09 +00:00
Nora
c4df8bf7b2 Handle expanded state 2023-01-09 15:01:57 +00:00
Nora
29c29f0b77 Remove db in list from selected 2023-01-09 07:54:33 +00:00
Nora
b5f865432e Add action 2023-01-09 08:26:21 +01:00
Aditya Sharad
8346eda8b8 Integration tests: Accept github/codeql checkouts named ql (#1940)
Some checkouts of the github/codeql repo, such as the
internal submodule, may be named `ql` rather than
`codeql`. Allow this folder name when running tests.
2023-01-06 15:16:36 -08:00
Charis Kyriakou
2a6d581de4 Added logic to clean expanded state when it's updated (#1938) 2023-01-06 16:09:43 +00:00
Shati Patel
b3fcd47930 Add integration test for database selection command (#1937) 2023-01-06 14:38:28 +00:00
Charis Kyriakou
8c558f04f4 Merge pull request #1936 from github/charisk/expansion-tidy
Some minor tidy up around db item expansion
2023-01-06 14:14:56 +00:00
Charis Kyriakou
51d1d3226c Remove unnecessary type casting 2023-01-06 12:57:23 +00:00
Charis Kyriakou
d69a048a38 Handle all db item kinds when checking for equality with expanded items 2023-01-06 12:57:19 +00:00
Charis Kyriakou
971fb6edee Rename updateItemInExpandedState -> updateExpandedItem and replaceItemInExpandedState -> replaceExpandedItem 2023-01-06 12:57:12 +00:00
Elena Tanasoiu
13db377334 Merge pull request #1931 from github/elena/ignore-prettier-commits
Move list of ignored commits to root
2023-01-06 09:37:28 +00:00
Andrew Eisenberg
61c3bef8ff Merge pull request #1932 from github/aeisenberg/fix-vscode-integration-tests
Remove assertion in tests
2023-01-05 16:41:49 -08:00
Andrew Eisenberg
0959cb8bbd Remove assertion in tests
I am removing these assertions so that our internal integration tests
can pass. They are currently failing because the number of dependencies
of the `codeql/javascript-all` pack has changed. It no longer makes
sense to test this value as newer versions of this pack will have more
dependencies and we expect this value will continue to go up.
2023-01-05 16:13:13 -08:00
Elena Tanasoiu
d385a9e7a4 Move list of ignored commits to root
This was initially added [here][1] but wasn't quite in the right place
to have the intended effect.

Let's move it up to the root of the project.

[1]: f515663640
2023-01-05 17:37:41 +00:00
Charis Kyriakou
1c705da444 Add 'rename' context menu action for dbs/lists (#1928) 2023-01-05 13:29:10 +00:00
Shati Patel
4dba169412 Support new DB config format in "copy repo list" function (#1927) 2023-01-05 10:56:55 +00:00
Charis Kyriakou
afc6ce5211 Merge pull request #1926 from github/charisk/db-config-store-rename
Add db and list rename functionality to db config store
2023-01-04 17:38:44 +00:00
Charis Kyriakou
db9bc5bf5c Add db and list rename functionality to db config store 2023-01-04 15:59:14 +00:00
Charis Kyriakou
3227935078 Minor refactoring of the db config store and tests (#1924)
* Remove unnecessary type castings
* Extract validation to separate functions
* Nest tests inside a 'describe' block
2023-01-04 13:11:26 +00:00
Shati Patel
0902e187c8 Add context menu command to open repo/owner on GitHub (#1921) 2023-01-04 10:44:48 +00:00
Charis Kyriakou
35a49b018f Merge pull request #1923 from github/charisk/db-item-expansion-tidy
Some small refactorings around db item expansion
2023-01-04 10:02:33 +00:00
Charis Kyriakou
a82f40fb1e Remove unnecessary config check.
This used to be valid when expanded state lived in the db config, but it's now stored in workspace storage.
2023-01-04 09:28:16 +00:00
Charis Kyriakou
4db3cd6b1b Extract setExpandedItems function so that it can be re-used 2023-01-04 09:10:04 +00:00
Charis Kyriakou
abe5b3c0fc Rename getCurrentExpandedItems -> getExpandedItems 2023-01-04 09:08:21 +00:00
Charis Kyriakou
7738041ee7 Nest tests inside a 'describe' block 2023-01-04 09:07:42 +00:00
Charis Kyriakou
f3d0773085 Rename calculateNewExpandedState -> updateItemInExpandedState 2023-01-04 09:06:31 +00:00
Charis Kyriakou
1a08ae4df2 Move db item expansion models to db-item-expansion 2023-01-04 09:05:12 +00:00
dependabot[bot]
5e864ae8e0 Bump json5 from 1.0.1 to 1.0.2 in /extensions/ql-vscode (#1919)
Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2.
- [Release notes](https://github.com/json5/json5/releases)
- [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md)
- [Commits](https://github.com/json5/json5/compare/v1.0.1...v1.0.2)

---
updated-dependencies:
- dependency-name: json5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-03 10:10:38 -08:00
dependabot[bot]
f716032235 Bump d3-color and d3-graphviz in /extensions/ql-vscode (#1915)
Bumps [d3-color](https://github.com/d3/d3-color) to 3.1.0 and updates ancestor dependency [d3-graphviz](https://github.com/magjac/d3-graphviz). These dependencies need to be updated together.


Updates `d3-color` from 1.4.1 to 3.1.0
- [Release notes](https://github.com/d3/d3-color/releases)
- [Commits](https://github.com/d3/d3-color/compare/v1.4.1...v3.1.0)

Updates `d3-graphviz` from 2.6.1 to 5.0.2
- [Release notes](https://github.com/magjac/d3-graphviz/releases)
- [Changelog](https://github.com/magjac/d3-graphviz/blob/master/CHANGELOG.md)
- [Commits](https://github.com/magjac/d3-graphviz/compare/v2.6.1...v5.0.2)

---
updated-dependencies:
- dependency-name: d3-color
  dependency-type: indirect
- dependency-name: d3-graphviz
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-01-03 10:09:58 -08:00
Charis Kyriakou
8e848e3403 Set db tree item context value to drive actions (#1920) 2023-01-03 16:17:51 +00:00
Nora
ae3ed9402d Merge pull request #1918 from github/nora/add-select-context-menu
Add select context menu
2023-01-03 16:40:44 +01:00
Nora
306529b4a9 Add command to activationEvents 2023-01-03 15:10:02 +00:00
Nora
48a51fe10b Add select context menu 2023-01-03 13:34:50 +00:00
Charis Kyriakou
bbbbb3a1ee Renamed selectable context value (#1917) 2023-01-03 12:34:24 +00:00
Charis Kyriakou
bbdbe01e03 Add test tsconfigs in eslint projects (#1916) 2023-01-03 12:17:17 +00:00
Charis Kyriakou
35d1d8ba6e Move VS Code integration tests to /test directory (#1912) 2023-01-03 10:31:38 +00:00
Charis Kyriakou
a7be6cf31a Fix broken unit test that relies on date (#1914) 2023-01-03 09:26:13 +00:00
Charis Kyriakou
40a7dd04fb Tidy up unit test suite file structure (#1910) 2022-12-23 14:23:55 +00:00
Charis Kyriakou
24a7348fc2 Add support for adding local lists (#1907) 2022-12-23 11:11:48 +00:00
Charis Kyriakou
31b80efc56 Use constant for selected db item resource uri (#1908) 2022-12-23 08:34:16 +00:00
Charis Kyriakou
3234f0afe1 Move db item expanded state to workspace storage (#1904) 2022-12-22 15:44:00 +00:00
Elena Tanasoiu
ae0dfd8089 Merge pull request #1901 from github/elena/move-test-scenarios-into-markdown
Move test plan into markdown file
2022-12-22 14:32:08 +00:00
Elena Tanasoiu
1a6f532c8b Change results view title 2022-12-22 14:15:21 +00:00
Elena Tanasoiu
beb5e37f3a American spelling 2022-12-22 14:14:59 +00:00
Elena Tanasoiu
9fe4c8cfa9 Remove copy section 2022-12-22 14:14:35 +00:00
Shati Patel
9e1da8f142 Check for duplicate repo within parent list (#1905) 2022-12-22 14:01:11 +00:00
Elena Tanasoiu
f1b17d1c46 Fix wonky indentation 2022-12-22 12:54:24 +00:00
Elena Tanasoiu
097c048edd Expand results view tests 2022-12-22 12:49:14 +00:00
Elena Tanasoiu
531f32c1f6 Expand query results scenarios based on variant analysis state 2022-12-22 12:49:10 +00:00
Nora
46a54a623a Merge pull request #1900 from github/nora/add-repo-to-list
Add new repositories to a highlighted user defined list
2022-12-22 13:41:27 +01:00
Elena Tanasoiu
1b76159c06 Fix quotes 2022-12-22 11:35:22 +00:00
Elena Tanasoiu
30e614e26d Remove duplicate test case 2022-12-22 11:31:21 +00:00
Elena Tanasoiu
8ca9391115 Mention what "it" means 2022-12-22 11:28:55 +00:00
Elena Tanasoiu
ec8066a11c Clarify these are mostly aimed at MRVA 2022-12-22 11:28:01 +00:00
Elena Tanasoiu
ac27a80769 Drop numbering 2022-12-22 11:27:06 +00:00
Elena Tanasoiu
c9087ffaf0 Update screenshot 2022-12-22 11:26:18 +00:00
Robert
25dd679b7d Merge pull request #1892 from github/robertbrignull/undefined_credentials
Simplify the credentials class, and clear up impossible error cases
2022-12-22 11:20:09 +00:00
Elena Tanasoiu
16c688f9c8 Change to american spelling 2022-12-22 11:15:49 +00:00
Elena Tanasoiu
0f3936900c Remove pre-live-results sections 2022-12-22 11:15:15 +00:00
Elena Tanasoiu
3c9c6dc324 Rephrase ... erm ... phrases
And fix a typo
2022-12-22 11:14:10 +00:00
Elena Tanasoiu
f11cd17f83 Check these when query starts instead of completes 2022-12-22 11:10:05 +00:00
Nora
824f56d614 use find and remove unneccessary checks 2022-12-22 10:53:54 +00:00
Elena Tanasoiu
eddc228a00 Remove bullet points and mention results view 2022-12-22 10:48:36 +00:00
Elena Tanasoiu
812205cecf Clarify that test cases are for MRVA 2022-12-22 10:45:59 +00:00
Elena Tanasoiu
a839206846 Mention canary flag as pre-requisite for MRVA 2022-12-22 10:45:22 +00:00
Elena Tanasoiu
2f07f417fa Move last step to first step in release requirements 2022-12-22 10:43:31 +00:00
Elena Tanasoiu
dc6bd07518 Add more info to release steps 2022-12-22 10:43:08 +00:00
Elena Tanasoiu
e890e6cc1f Remove "Areas to consider" section 2022-12-22 10:32:26 +00:00
Robert
6285ba7632 fix typos 2022-12-22 10:25:34 +00:00
Koen Vlaswinkel
be79d68271 Merge pull request #1891 from github/koesie10/sort-gist-files
Sort Gist files by user-defined sort order
2022-12-22 09:17:07 +01:00
Charis Kyriakou
19a9ad38d5 Add workspace state to app container (#1902) 2022-12-21 17:58:34 +00:00
Elena Tanasoiu
1e84bc9116 Move test plan into VSCode markdown file
This moves our existing test plan under a "Required testing" section.

We're also adding the scenarios used for testing live results under an "Optional testing" section.
2022-12-21 16:55:33 +00:00
Nora
28abd40963 Add repo to list when child is highlighted 2022-12-21 15:45:19 +00:00
Robert
abc025cb39 Inline the createOctokit method
It's now only used from one place and inlining it doesn't make
getOctokit too long to be unclear.
2022-12-21 15:01:47 +00:00
Robert
551f76cc4e Create a new octokit instance every time
I believe this doesn't change the user-visible behaviour at all. The user
won't be prompted to log in any more or less often than they would have
done before.

One benefit of this is that we can remove the registerListeners method
because we no longer need to know if the cached octokit is still valid.
Instead we just call vscode.authentication.getSession every time and it
will return the current session, which might be different from the last
time we called it. This might prompt the user to log in, but that would
have happened anyway because when the session changed we would have
overwritten our cached octokit instance.

Another benefit is that we no longer need the extension context and this
removed a surprisingly large amount of code where we are passing this
parameter around because we need it for the credentials.

The only downside I can see is that we call getSession more often and
create more javascript objects in general. I believe the performance
impact of this will be negligible and not worth worrying about.
2022-12-21 15:01:42 +00:00
Robert
8f34f6af2e Remove the createIfNone parameter from createOctokit
At this point we are only ever passing true, so we may as well remove
the parameter and simplify the code.
2022-12-21 14:52:25 +00:00
Robert
8c05b3a508 Don't try to pre-populate an octokit
I argue that calling createOctokit(false) adds no benefit. If an
authenticated session already exists then this silently create an
octokit, which makes getOctokit() a no-op just returning the field.
However if there is already an authenticated session then getOctokit()
would already be able to create an octokit without prompting the user.

On the other hand if there isn't an authenticated session then we
won't be able to pre-populate an octokit, so getOctokit() will have
to prompt the user anyway.

Not calling createOctokit(false) in registerListeners also doesn't
change behaviour. If the user is authenticated in the new session then
we would be able to create an octokit instance wihtout prompting in
getOctokit anyway. If the user is not authenticated in the new session
then we won't be able to create an instance without prompting either way.

The only benefit I can think of is that it moves a tiny amount of
computation earlier in the pipeline, but the amount of computation is
tiny and it isn't any more async than it would be if it happened in
getOctokit(). I don't think this is worth making the code more complex.
2022-12-21 14:51:13 +00:00
dependabot[bot]
7004e94b32 Bump actions/dependency-review-action from 1 to 3 (#1897) 2022-12-21 14:32:38 +00:00
Robert
74f10a306e Remove the overrideToken parameter from createOctokit
This was only used from initializeWithToken and only added a completely
separate case to the start of the method, effectively turning it into
two separate implementations. Therefore we can make things simpler by
inlining this case in the one place it is used.
2022-12-21 14:27:50 +00:00
Robert
7e8ce35485 Remove the requiresAuthentication parameter
It is true by default and no place in the codebase sets it to false. We can
simplify the code by removing this case we aren't using. If we want this
behaviour in the future we can always implement it again, but I think it's
likely to be unnecessary and if you don't want authenticated requests then
you likely won't be initializing a Credentials object.
2022-12-21 14:24:13 +00:00
Nora
758c182a33 Add repo to highlighted list 2022-12-21 15:23:09 +01:00
Robert
0c483d1e29 Remove places where we are checking if credentials are undefined
This cannot happen already, even before the other changes in this PR.
The Credentials.initialize method can never return undefined, so these
checks would never return true. The real place that checks that we are
authenticated is in the vscode.authentication.getSession method, and
it will reject the promise if the user declines to authenticate or
anything else means we can't get an authenticated session.

I feel justified in removing the tests for these cases because the
code was never actually called in production, and we are covered by the
vscode authentication library rejecting the promise. Any exception
thrown from Credentials.initialize would behave the same as the one I'm
deleting.
2022-12-21 14:23:08 +00:00
dependabot[bot]
4bb3be9fd1 Bump peter-evans/create-pull-request from 3.4.1 to 4.2.3 (#1898) 2022-12-21 14:10:45 +00:00
Shati Patel
f99e5587d0 Update dependencies in workflow files (#1896) 2022-12-21 13:54:49 +00:00
Charis Kyriakou
2493b0fd3c Handle db validation errors gracefully (#1895) 2022-12-21 12:53:47 +00:00
Charis Kyriakou
dbdb4ba57a Stop user from adding a db or owner with the same name (#1893) 2022-12-21 10:51:24 +00:00
Charis Kyriakou
55869e8033 Merge pull request #1894 from github/charisk/add-db-integration-test
Add basic integration test for 'add db' functionality
2022-12-21 10:06:52 +00:00
Charis Kyriakou
47ac9c631e Add basic integration test for 'add db' functionality 2022-12-20 20:42:14 +00:00
Charis Kyriakou
decbd52d1b Rename 'addNewRemoteList' to 'addNewList' 2022-12-20 20:40:58 +00:00
Nora
952faf5efc Merge pull request #1889 from github/shati-nora/add-remote-repositories
Create "Add database" button in DB panel
2022-12-20 17:31:12 +01:00
shati-patel
eb3ba1e229 Merge branch 'main' into shati-nora/add-remote-repositories 2022-12-20 16:13:00 +00:00
Shati Patel
5a3248647b Get highlighted item in DB panel (#1887) 2022-12-20 16:00:45 +00:00
Charis Kyriakou
4b43b9a140 Use ✓ for db item selection (#1890) 2022-12-20 15:00:03 +00:00
Nora
467d43c68c Implement refactor merge comments 2022-12-20 12:58:50 +00:00
Koen Vlaswinkel
fe7d14b136 Sort Gist files by user-defined sort order
This will sort the files in an exported Gist by the user-defined sort
order. It does so by prefixing the files with `result-{index}-` where
the `index` is the 1-based index of the repository in the sort order.
It will automatically pad the index with leading zeros to ensure that
the files are sorted in the correct order.

Unfortunately, we can't just use `{index}-` because numbers sort before
the `_` character, which is used in the summary filename to place it
first.

There are also some changes in how we determine which repositories to
export since we need to know in advance how many zeroes we need to pad
the index with. There should be no functional changes in which
repositories are actually exported.
2022-12-20 13:51:22 +01:00
Nora
f332e6145a Implement addNewDatabase 2022-12-20 11:01:48 +00:00
Nora
6350ac7f66 Merge pull request #1888 from github/nora/refactor-githubnwoowner-helper
Extract github url identifier helper
2022-12-20 12:01:13 +01:00
Nora
7241e317af Move helper to new file and minor refactor 2022-12-20 10:19:42 +00:00
Charis Kyriakou
22ec4b0b6a Don't allow empty list names (#1886) 2022-12-19 11:59:53 +00:00
Taj
5a42b8b890 using secrets instead of actions context 2022-12-16 20:30:14 +00:00
Taj
f2076df73d Merge branch 'main' of github.com:tjgurwara99/vscode-codeql 2022-12-16 20:28:51 +00:00
Taj
c89d267d55 change the order of supported versions 2022-12-16 20:28:29 +00:00
Taj
09d744a98e Merge branch 'github:main' into main 2022-12-16 18:36:37 +00:00
Andrew Eisenberg
2493ddd39a Merge pull request #1885 from github/aeisenberg/lgtm-remove
Remove LGTM references and commands
2022-12-16 10:17:15 -08:00
Andrew Eisenberg
0bf1fae2fe Remove LGTM references and commands
LGTM has been decommissioned. All code and tests for downloading
LGTM databases should be removed.
2022-12-16 09:58:24 -08:00
Taj
f7d48916d9 Merge branch 'github:main' into main 2022-12-16 17:21:43 +00:00
Taj
ec9078d616 permission conf and removed deprecated use of set-output 2022-12-16 17:09:39 +00:00
Charis Kyriakou
8971bee31d Add basic integration test for 'add db list' functionality (#1881) 2022-12-16 14:44:53 +00:00
Taj
2723816a5a namespacing actions branch 2022-12-16 13:40:38 +00:00
Koen Vlaswinkel
281fe56d2b Merge pull request #1883 from github/koesie10/result-performance
Add Storybook story for many results performance
2022-12-16 14:20:06 +01:00
Taj
54204167b6 separation of concern of creating a PR vs code to change the version 2022-12-16 13:12:19 +00:00
Koen Vlaswinkel
c6c6d55bed Add Storybook story for many results performance 2022-12-16 13:28:59 +01:00
Nora
2b1a2cddb1 Merge pull request #1880 from github/nora/move-db-config-factories
Move DbConfig Factories to src directory
2022-12-16 10:05:01 +01:00
Nora
0c2e15a176 Use factory in db tree creator 2022-12-15 14:56:26 +00:00
Nora
1aebd895b1 Use factory in db panel test 2022-12-15 14:53:36 +00:00
Nora
8665a81ec1 Move factory to src 2022-12-15 14:52:51 +00:00
Shati Patel
fecefe4468 Add unit tests to check codeQLDatabasesExperimental.configError value (#1876) 2022-12-15 13:07:17 +00:00
Charis Kyriakou
727da3d78c Add logging around db config loading (#1875) 2022-12-15 12:21:20 +00:00
Charis Kyriakou
468c4a2539 Add logger to the app container (#1874) 2022-12-15 11:28:38 +00:00
Shati Patel
18423ca518 Hide DB panel UI actions when config is broken/undefined (#1866) 2022-12-15 10:50:13 +00:00
Charis Kyriakou
091d793f13 Stop user from adding a db list with the same name (#1873) 2022-12-15 09:21:54 +00:00
Charis Kyriakou
b1bf82d432 Enable awaitWriteFinish for the db config file watcher (#1872) 2022-12-14 15:25:34 +00:00
Charis Kyriakou
602289eb6d Add validation for duplicate names in the db config (#1867) 2022-12-14 12:51:46 +00:00
Taj
3f39af2840 workflow to automatically bump cli version if different from the current version 2022-12-14 00:01:36 +00:00
Shati Patel
bce5d420d6 Bump CLI version to 2.11.6 for integration tests (#1869) 2022-12-13 18:15:49 +00:00
Charis Kyriakou
dc2e17d2f9 Add min length constraints to various properties in the db config schema (#1868) 2022-12-13 17:29:02 +00:00
Nora
b2285499a3 Merge pull request #1860 from github/nora/show-error-empty-list
Show error message when running query on empty list
2022-12-13 17:48:18 +01:00
Shati Patel
5ba2a5af1d Merge pull request #1865 from github/shati-patel/gh-nwo
Extract github nwo helper functions
2022-12-13 15:35:56 +00:00
Nora
0f1881d2bc Merge comments 2022-12-13 15:12:57 +00:00
Charis Kyriakou
e18a33074c Update ValueResult to have generic error type (#1861) 2022-12-13 14:15:52 +00:00
Robert
3b197a21e7 Merge pull request #1864 from github/version/bump-to-v1.7.8
Bump version to v1.7.8
2022-12-13 14:13:12 +00:00
Charis Kyriakou
e987a3535d Fix executeCommand to pass arguments correctly (#1863) 2022-12-13 13:12:10 +00:00
robertbrignull
060b7c6099 Bump version to v1.7.8 2022-12-13 13:10:27 +00:00
shati-patel
674a126078 Extract github nwo helper functions 2022-12-13 12:58:46 +00:00
Nora
ed9592c2d7 Update extensions/ql-vscode/src/vscode-tests/no-workspace/remote-queries/repository-selection.test.ts
Co-authored-by: Robert <robertbrignull@github.com>
2022-12-13 11:37:12 +01:00
Nora
35ce928068 Show error message when running query on empty list 2022-12-13 09:53:07 +00:00
553 changed files with 23390 additions and 23139 deletions

2
.gitattributes vendored
View File

@@ -22,7 +22,7 @@ CHANGELOG.md merge=union
# Mark some JSON files containing test data as generated so they are not included
# as part of diffs or language statistics.
extensions/ql-vscode/src/stories/remote-queries/data/*.json linguist-generated
extensions/ql-vscode/src/stories/variant-analysis/data/*.json linguist-generated
# Always use LF line endings, also on Windows
* text=auto eol=lf

82
.github/actions/create-pr/action.yml vendored Normal file
View File

@@ -0,0 +1,82 @@
name: Create a PR if one doesn't exists
description: >
Creates a commit with the current changes to the repo, and opens a PR for that commit. If
any PR with the same title exists, then this action is marked as succeeded.
inputs:
commit-message:
description: >
The message for the commit to be created.
required: true
title:
description: >
The title of the PR. If empty, the title and body will be determined from the commit message.
default: ''
required: false
body:
description: >
The body (description) of the PR. The `title` input must be specified in order for this input to be used.
default: ''
required: false
head-branch:
description: >
The name of the branch to hold the new commit. If an existing open PR with the same head
branch exists, the new branch will be force-pushed to that PR instead of creating a new PR.
required: true
base-branch:
description: >
The base branch to target with the new PR.
required: true
token:
description: |
The GitHub token to use. It must have enough privileges to
make API calls to create and close pull requests.
required: true
runs:
using: composite
steps:
- name: Update git config
shell: bash
run: |
git config --global user.email "github-actions@github.com"
git config --global user.name "github-actions[bot]"
- name: Commit, Push and Open PR
shell: bash
env:
COMMIT_MESSAGE: ${{ inputs.commit-message }}
HEAD_BRANCH: ${{ inputs.head-branch }}
BASE_BRANCH: ${{ inputs.base-branch }}
GH_TOKEN: ${{ inputs.token }}
TITLE: ${{ inputs.title }}
BODY: ${{ inputs.body }}
run: |
set -exu
if ! [[ $(git diff --stat) != '' ]]; then
exit 0 # exit early
fi
# stage changes in the working tree
git add .
git commit -m "$COMMIT_MESSAGE"
git checkout -b "$HEAD_BRANCH"
# CAUTION: gits history changes with the following
git push --force origin "$HEAD_BRANCH"
PR_JSON=$(gh pr list --state open --json number --head "$HEAD_BRANCH")
if [[ $? -ne 0 ]]; then
echo "Failed to fetch existing PRs."
exit 1
fi
PR_NUMBERS=$(echo $PR_JSON | jq '. | length')
if [[ $PR_NUMBERS -ne 0 ]]; then
echo "Found existing open PR: $PR_NUMBERS"
exit 0
fi
gh pr create --head "$HEAD_BRANCH" --base "$BASE_BRANCH" --title "$TITLE" --body "$BODY" --assignee ${{ github.actor }} --draft
if [[ $? -ne 0 ]]; then
echo "Failed to create new PR."
exit 1
fi

View File

@@ -2,6 +2,8 @@ name: "CodeQL config"
queries:
- name: Run standard queries
uses: security-and-quality
- name: Experimental queries
uses: security-experimental
- name: Run custom javascript queries
uses: ./.github/codeql/queries
paths:

View File

@@ -0,0 +1,134 @@
/**
* @name A VS Code command should not be used in multiple locations
* @kind problem
* @problem.severity warning
* @id vscode-codeql/unique-command-use
* @description Using each VS Code command from only one location makes
* our telemetry more useful, because we can differentiate more user
* interactions and know which features of the UI our users are using.
* To fix this alert, new commands will need to be made so that each one
* is only used from one location. The commands should share the same
* implementation so we do not introduce duplicate code.
* When fixing this alert, search the codebase for all other references
* to the command name. The location of the alert is an arbitrarily
* chosen usage of the command, and may not necessarily be the location
* that should be changed to fix the alert.
*/
import javascript
/**
* The name of a VS Code command.
*/
class CommandName extends string {
CommandName() { exists(CommandUsage e | e.getCommandName() = this) }
/**
* In how many ways is this command used. Will always be at least 1.
*/
int getNumberOfUsages() { result = count(this.getAUse()) }
/**
* Get a usage of this command.
*/
CommandUsage getAUse() { result.getCommandName() = this }
/**
* Get the canonical first usage of this command, to use for the location
* of the alert. The implementation of this ordering of usages is arbitrary
* and the usage given may not be the one that should be changed when fixing
* the alert.
*/
CommandUsage getFirstUsage() {
result =
max(CommandUsage use |
use = this.getAUse()
|
use
order by
use.getFile().getRelativePath(), use.getLocation().getStartLine(),
use.getLocation().getStartColumn()
)
}
}
/**
* Represents a single usage of a command, either from within code or
* from the command's definition in package.json
*/
abstract class CommandUsage extends Locatable {
abstract string getCommandName();
}
/**
* A usage of a command from the typescript code, by calling `executeCommand`.
*/
class CommandUsageCallExpr extends CommandUsage, CallExpr {
CommandUsageCallExpr() {
this.getCalleeName() = "executeCommand" and
this.getArgument(0).(StringLiteral).getValue().matches("%codeQL%") and
not this.getFile().getRelativePath().matches("extensions/ql-vscode/test/%")
}
override string getCommandName() { result = this.getArgument(0).(StringLiteral).getValue() }
}
/**
* A usage of a command from any menu that isn't the command palette.
* This means a user could invoke the command by clicking on a button in
* something like a menu or a dropdown.
*/
class CommandUsagePackageJsonMenuItem extends CommandUsage, JsonObject {
CommandUsagePackageJsonMenuItem() {
exists(this.getPropValue("command")) and
exists(PackageJson packageJson, string menuName |
packageJson
.getPropValue("contributes")
.getPropValue("menus")
.getPropValue(menuName)
.getElementValue(_) = this and
menuName != "commandPalette"
)
}
override string getCommandName() { result = this.getPropValue("command").getStringValue() }
}
/**
* Is the given command disabled for use in the command palette by
* a block with a `"when": "false"` field.
*/
predicate isDisabledInCommandPalette(string commandName) {
exists(PackageJson packageJson, JsonObject commandPaletteObject |
packageJson
.getPropValue("contributes")
.getPropValue("menus")
.getPropValue("commandPalette")
.getElementValue(_) = commandPaletteObject and
commandPaletteObject.getPropValue("command").getStringValue() = commandName and
commandPaletteObject.getPropValue("when").getStringValue() = "false"
)
}
/**
* Represents a command being usable from the command palette.
* This means that a user could choose to manually invoke the command.
*/
class CommandUsagePackageJsonCommandPalette extends CommandUsage, JsonObject {
CommandUsagePackageJsonCommandPalette() {
this.getFile().getBaseName() = "package.json" and
exists(this.getPropValue("command")) and
exists(PackageJson packageJson |
packageJson.getPropValue("contributes").getPropValue("commands").getElementValue(_) = this
) and
not isDisabledInCommandPalette(this.getPropValue("command").getStringValue())
}
override string getCommandName() { result = this.getPropValue("command").getStringValue() }
}
from CommandName c
where c.getNumberOfUsages() > 1
select c.getFirstUsage(),
"The " + c + " command is used from " + c.getNumberOfUsages() + " locations"

View File

@@ -11,7 +11,7 @@ updates:
- dependency-name: "*"
update-types: ["version-update:semver-minor", "version-update:semver-patch"]
- package-ecosystem: "github-actions"
directory: ".github"
directory: "/"
schedule:
interval: "weekly"
day: "thursday" # Thursday is arbitrary

61
.github/workflows/bump-cli.yml vendored Normal file
View File

@@ -0,0 +1,61 @@
name: Bump CLI version
on:
workflow_dispatch:
inputs:
option:
description: "Option"
required: true
default: 'replace'
type: choice
options:
- prepend
- replace
version:
description: |
The version to prepend to the supported versions file. This should be in the form: `vA.B.C`.
required: false
type: string
pull_request:
branches: [main]
paths:
- .github/actions/create-pr/action.yml
- .github/workflows/bump-cli.yml
schedule:
- cron: 0 0 */14 * * # run every 14 days
permissions:
contents: write
pull-requests: write
jobs:
build:
name: Build
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 1
- name: Bump CLI
if: ${{ inputs.option == 'replace' }}
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
scripts/replace-cli-version.sh
- name: Prepend another version
if: ${{ inputs.option == 'prepend' }}
run: |
cat extensions/ql-vscode/supported_cli_versions.json | jq '. |= ["${{ inputs.version }}"] + .' > supported_cli_versions_temp.json
mv supported_cli_versions_temp.json extensions/ql-vscode/supported_cli_versions.json
echo "LATEST_VERSION=${{ inputs.version }}" >> $GITHUB_ENV
echo "PREVIOUS_VERSION=`jq -r '.[1]' extensions/ql-vscode/supported_cli_versions.json`" >> $GITHUB_ENV
- name: Commit, Push and Open a PR
uses: ./.github/actions/create-pr
with:
token: ${{ secrets.GITHUB_TOKEN }}
base-branch: main
head-branch: github-action/bump-cli
commit-message: Bump CLI version from ${{ env.PREVIOUS_VERSION }} to ${{ env.LATEST_VERSION }} for integration tests
title: Bump CLI Version to ${{ env.LATEST_VERSION }} for integration tests
body: >
Bumps CLI version from ${{ env.PREVIOUS_VERSION }} to ${{ env.LATEST_VERSION }}

View File

@@ -13,4 +13,4 @@ jobs:
- name: 'Checkout Repository'
uses: actions/checkout@v3
- name: 'Dependency Review'
uses: actions/dependency-review-action@v1
uses: actions/dependency-review-action@v3

View File

@@ -132,7 +132,12 @@ jobs:
- name: Run unit tests
working-directory: extensions/ql-vscode
run: |
npm run test
npm run test:unit
- name: Run view tests
working-directory: extensions/ql-vscode
run: |
npm run test:view
test:
name: Test
@@ -173,7 +178,7 @@ jobs:
VSCODE_CODEQL_GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
run: |
unset DBUS_SESSION_BUS_ADDRESS
/usr/bin/xvfb-run npm run integration
/usr/bin/xvfb-run npm run test:vscode-integration
- name: Run integration tests (Windows)
if: matrix.os == 'windows-latest'
@@ -181,16 +186,27 @@ jobs:
env:
VSCODE_CODEQL_GITHUB_TOKEN: '${{ secrets.GITHUB_TOKEN }}'
run: |
npm run integration
npm run test:vscode-integration
set-matrix:
name: Set Matrix for cli-test
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Set the variables
id: set-variables
run: echo "cli-versions=$(cat ./extensions/ql-vscode/supported_cli_versions.json | jq -rc)" >> $GITHUB_OUTPUT
outputs:
cli-versions: ${{ steps.set-variables.outputs.cli-versions }}
cli-test:
name: CLI Test
runs-on: ${{ matrix.os }}
needs: [find-nightly]
needs: [find-nightly, set-matrix]
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
version: ['v2.7.6', 'v2.8.5', 'v2.9.4', 'v2.10.5', 'v2.11.5', 'nightly']
version: ${{ fromJson(needs.set-matrix.outputs.cli-versions) }}
fail-fast: false
env:
CLI_VERSION: ${{ matrix.version }}
@@ -243,10 +259,10 @@ jobs:
if: matrix.os == 'ubuntu-latest'
run: |
unset DBUS_SESSION_BUS_ADDRESS
/usr/bin/xvfb-run npm run cli-integration
/usr/bin/xvfb-run npm run test:cli-integration
- name: Run CLI tests (Windows)
working-directory: extensions/ql-vscode
if: matrix.os == 'windows-latest'
run: |
npm run cli-integration
npm run test:cli-integration

View File

@@ -54,11 +54,17 @@ jobs:
echo "ref_name=$REF_NAME" >> "$GITHUB_OUTPUT"
- name: Upload artifacts
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v3
with:
name: vscode-codeql-extension
path: artifacts
- name: Upload source maps
uses: actions/upload-artifact@v3
with:
name: vscode-codeql-sourcemaps
path: dist/vscode-codeql/out/*.map
# TODO Run tests, or check that a test run on the same branch succeeded.
- name: Create release
@@ -88,6 +94,23 @@ jobs:
asset_name: ${{ format('vscode-codeql-{0}.vsix', steps.prepare-artifacts.outputs.ref_name) }}
asset_content_type: application/zip
- name: Create sourcemap ZIP file
run: |
cd dist/vscode-codeql/out
zip -r ../../vscode-codeql-sourcemaps.zip *.map
- name: Upload sourcemap ZIP file
uses: actions/upload-release-asset@v1.0.1
if: success()
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
# Get the `upload_url` from the `create-release` step above.
upload_url: ${{ steps.create-release.outputs.upload_url }}
asset_path: dist/vscode-codeql-sourcemaps.zip
asset_name: ${{ format('vscode-codeql-sourcemaps-{0}.zip', steps.prepare-artifacts.outputs.ref_name) }}
asset_content_type: application/zip
###
# Do Post release work: version bump and changelog PR
# Only do this if we are running from a PR (ie- this is part of the release process)
@@ -116,16 +139,15 @@ jobs:
perl -i -pe 's/^/## \[UNRELEASED\]\n\n/ if($.==3)' CHANGELOG.md
- name: Create version bump PR
uses: peter-evans/create-pull-request@c7f493a8000b8aeb17a1332e326ba76b57cb83eb # v3.4.1
uses: ./.github/actions/create-pr
if: success()
with:
token: ${{ secrets.GITHUB_TOKEN }}
commit-message: Bump version to ${{ steps.bump-patch-version.outputs.next_version }}
title: Bump version to ${{ steps.bump-patch-version.outputs.next_version }}
body: This PR was automatically generated by the GitHub Actions release workflow in this repository.
branch: ${{ format('version/bump-to-{0}', steps.bump-patch-version.outputs.next_version) }}
base: main
draft: true
head-branch: ${{ format('version/bump-to-{0}', steps.bump-patch-version.outputs.next_version) }}
base-branch: main
vscode-publish:
name: Publish to VS Code Marketplace

4
.husky/pre-commit Executable file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
cd extensions/ql-vscode && npm run format-staged

4
.husky/pre-push Executable file
View File

@@ -0,0 +1,4 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"
cd extensions/ql-vscode && ./scripts/forbid-test-only

9
.vscode/launch.json vendored
View File

@@ -11,6 +11,7 @@
"--extensionDevelopmentPath=${workspaceRoot}/extensions/ql-vscode",
// Add a reference to a workspace to open. Eg-
// "${workspaceRoot}/../vscode-codeql-starter/vscode-codeql-starter.code-workspace"
// "${workspaceRoot}/../codespaces-codeql/tutorial.code-workspace"
],
"sourceMaps": true,
"outFiles": [
@@ -38,7 +39,7 @@
},
"args": [
"--projects",
"test"
"test/unit-tests"
],
"stopOnEntry": false,
"sourceMaps": true,
@@ -94,7 +95,7 @@
"cwd": "${workspaceFolder}/extensions/ql-vscode",
"args": [
"--projects",
"src/vscode-tests/no-workspace"
"test/vscode-tests/no-workspace"
],
"sourceMaps": true,
"console": "integratedTerminal",
@@ -110,7 +111,7 @@
"cwd": "${workspaceFolder}/extensions/ql-vscode",
"args": [
"--projects",
"src/vscode-tests/minimal-workspace"
"test/vscode-tests/minimal-workspace"
],
"sourceMaps": true,
"console": "integratedTerminal",
@@ -126,7 +127,7 @@
"cwd": "${workspaceFolder}/extensions/ql-vscode",
"args": [
"--projects",
"src/vscode-tests/cli-integration"
"test/vscode-tests/cli-integration"
],
"env": {
// Optionally, set the version to use for the integration tests.

19
.vscode/settings.json vendored
View File

@@ -42,14 +42,29 @@
"LANG": "en-US",
"TZ": "UTC"
},
// These options are used by the `jestrunner.debug` command.
// They are not used by the `jestrunner.run` command.
// After clicking "debug" over a test, continually invoke the
// "Debug: Attach to Node Process" command until you see a
// process named "Code Helper (Plugin)". Then click "attach".
// This will attach the debugger to the test process.
"jestrunner.debugOptions": {
// Uncomment to debug integration tests
// "attachSimplePort": 9223,
"attachSimplePort": 9223,
"env": {
"LANG": "en-US",
"TZ": "UTC",
// Uncomment to set a custom path to a CodeQL checkout.
// "TEST_CODEQL_PATH": "/absolute/path/to/checkout/of/codeql",
// Uncomment to set a custom path to a CodeQL CLI executable.
// This is the CodeQL version that will be used in the tests.
// "CLI_PATH": "/absolute/path/to/custom/codeql",
// Uncomment to debug integration tests
// "VSCODE_WAIT_FOR_DEBUGGER": "true",
"VSCODE_WAIT_FOR_DEBUGGER": "true",
}
},
"terminal.integrated.env.linux": {

View File

@@ -1,4 +1,3 @@
**/* @github/codeql-vscode-reviewers
**/remote-queries/ @github/code-scanning-secexp-reviewers
**/variant-analysis/ @github/code-scanning-secexp-reviewers
**/databases/ @github/code-scanning-secexp-reviewers

View File

@@ -2,7 +2,7 @@
[fork]: https://github.com/github/vscode-codeql/fork
[pr]: https://github.com/github/vscode-codeql/compare
[style]: https://primer.style
[style]: https://github.com/microsoft/vscode-webview-ui-toolkit
[code-of-conduct]: CODE_OF_CONDUCT.md
Hi there! We're thrilled that you'd like to contribute to this project. Your help is essential for keeping it great.
@@ -93,202 +93,7 @@ More information about Storybook can be found inside the **Overview** page once
### Testing
We have several types of tests:
* Unit tests: these live in the `tests/pure-tests/` directory
* View tests: these live in `src/view/variant-analysis/__tests__/`
* VSCode integration tests: these live in `src/vscode-tests/no-workspace` and `src/vscode-tests/minimal-workspace`
* CLI integration tests: these live in `src/vscode-tests/cli-integration`
The CLI integration tests require an instance of the CodeQL CLI to run so they will require some extra setup steps. When adding new tests to our test suite, please be mindful of whether they need to be in the cli-integration folder. If the tests don't depend on the CLI, they are better suited to being a VSCode integration test.
Any test data you're using (sample projects, config files, etc.) must go in a `src/vscode-tests/*/data` directory. When you run the tests, the test runner will copy the data directory to `out/vscode-tests/*/data`.
#### Running the tests
Pre-requisites:
1. Run `npm run build`.
2. You will need to have `npm run watch` running in the background.
##### 1. From the terminal
Then, from the `extensions/ql-vscode` directory, use the appropriate command to run the tests:
* Unit tests: `npm run test:unit`
* View Tests: `npm test:view`
* VSCode integration tests: `npm run integration`
###### CLI integration tests
The CLI integration tests require the CodeQL standard libraries in order to run so you will need to clone a local copy of the `github/codeql` repository.
1. Set the `TEST_CODEQL_PATH` environment variable: running from a terminal, you _must_ set the `TEST_CODEQL_PATH` variable to point to a checkout of the `github/codeql` repository. The appropriate CLI version will be downloaded as part of the test.
2. Run your test command:
```shell
cd extensions/ql-vscode && npm run cli-integration
```
##### 2. From VSCode
Alternatively, you can run the tests inside of VSCode. There are several VSCode launch configurations defined that run the unit and integration tests.
You will need to run tests using a task from inside of VS Code, under the "Run and Debug" view:
* Unit tests: run the _Launch Unit Tests - React_ task
* View Tests: run the _Launch Unit Tests_ task
* VSCode integration tests: run the _Launch Unit Tests - No Workspace_ and _Launch Unit Tests - Minimal Workspace_ tasks
###### CLI integration tests
The CLI integration tests require the CodeQL standard libraries in order to run so you will need to clone a local copy of the `github/codeql` repository.
1. Set the `TEST_CODEQL_PATH` environment variable: running from a terminal, you _must_ set the `TEST_CODEQL_PATH` variable to point to a checkout of the `github/codeql` repository. The appropriate CLI version will be downloaded as part of the test.
2. Set the codeql path in VSCode's launch configuration: open `launch.json` and under the _Launch Integration Tests - With CLI_ section, uncomment the `"${workspaceRoot}/../codeql"` line. If you've cloned the `github/codeql` repo to a different path, replace the value with the correct path.
3. Run the VSCode task from the "Run and Debug" view called _Launch Integration Tests - With CLI_.
#### Running a single test
##### 1. From the terminal
The easiest way to run a single test is to change the `it` of the test to `it.only` and then run the test command with some additional options
to only run tests for this specific file. For example, to run the test `src/vscode-tests/cli-integration/run-queries.test.ts`:
```shell
npm run cli-integration -- --runTestsByPath src/vscode-tests/cli-integration/run-queries.test.ts
```
You can also use the `--testNamePattern` option to run a specific test within a file. For example, to run the test `src/vscode-tests/cli-integration/run-queries.test.ts`:
```shell
npm run cli-integration -- --runTestsByPath src/vscode-tests/cli-integration/run-queries.test.ts --testNamePattern "should create a QueryEvaluationInfo"
```
##### 2. From VSCode
Alternatively, you can run a single test inside VSCode. To do so, install the [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) extension. Then,
you will have quicklinks to run a single test from within test files. To run a single unit or integration test, click the "Run" button. Debugging a single test is currently only supported
for unit tests by default. To debug integration tests, open the `.vscode/settings.json` file and uncomment the `jestrunner.debugOptions` lines. This will allow you to debug integration tests.
Please make sure to revert this change before committing; with this setting enabled, it is not possible to debug unit tests.
Without the Jest Runner extension, you can also use the "Launch Selected Unit Test (vscode-codeql)" launch configuration to run a single unit test.
#### Using a mock GitHub API server
Multi-Repo Variant Analyses (MRVA) rely on the GitHub API. In order to make development and testing easy, we have functionality that allows us to intercept requests to the GitHub API and provide mock responses.
##### Using a pre-recorded test scenario
To run a mock MRVA scenario, follow these steps:
1. Enable the mock GitHub API server by adding the following in your VS Code user settings (which can be found by running the `Preferences: Open User Settings (JSON)` VS Code command):
```json
"codeQL.mockGitHubApiServer": {
"enabled": true
}
```
1. Run the `CodeQL: Mock GitHub API Server: Load Scenario` command from the command pallet, and choose one of the scenarios to load.
1. Execute a normal MRVA. At this point you should see the scenario being played out, rather than an actual MRVA running.
1. Once you're done, you can stop using the mock scenario with `CodeQL: Mock GitHub API Server: Unload Scenario`
If you want to replay the same scenario you should unload and reload it so requests are replayed from the start.
##### Recording a new test scenario
To record a new mock MRVA scenario, follow these steps:
1. Enable the mock GitHub API server by adding the following in your VS Code user settings (which can be found by running the `Preferences: Open User Settings (JSON)` VS Code command):
```json
"codeQL.mockGitHubApiServer": {
"enabled": true
}
```
1. Run the `CodeQL: Mock GitHub API Server: Start Scenario Recording` VS Code command from the command pallet.
1. Execute a normal MRVA.
1. Once what you wanted to record is done (e.g. the MRVA has finished), then run the `CodeQL: Mock GitHub API Server: Save Scenario` command from the command pallet.
1. The scenario should then be available for replaying.
If you want to cancel recording, run the `CodeQL: Mock GitHub API Server: Cancel Scenario Recording` command.
Once the scenario has been recorded, it's often useful to remove some of the requests to speed up the replay, particularly ones that fetch the variant analysis status. Once some of the request files have manually been removed, the [fix-scenario-file-numbering script](./extensions/ql-vscode/scripts/fix-scenario-file-numbering.ts) can be used to update the number of the files. See the script file for details on how to use.
#### Scenario data location
Pre-recorded scenarios are stored in `./src/mocks/scenarios`. However, it's possible to configure the location, by setting the `codeQL.mockGitHubApiServer.scenariosPath` configuration property in the VS Code user settings.
## Releasing (write access required)
1. Double-check the `CHANGELOG.md` contains all desired change comments and has the version to be released with date at the top.
* Go through all recent PRs and make sure they are properly accounted for.
* Make sure all changelog entries have links back to their PR(s) if appropriate.
1. Double-check that the node version we're using matches the one used for VS Code. If it doesn't, you will then need to update the node version in the following files:
* `.nvmrc` - this will enable `nvm` to automatically switch to the correct node version when you're in the project folder
* `.github/workflows/main.yml` - all the "node-version: <version>" settings
* `.github/workflows/release.yml` - the "node-version: <version>" setting
1. Double-check that the extension `package.json` and `package-lock.json` have the version you intend to release. If you are doing a patch release (as opposed to minor or major version) this should already be correct.
1. Create a PR for this release:
* This PR will contain any missing bits from steps 1 and 2. Most of the time, this will just be updating `CHANGELOG.md` with today's date.
* Create a new branch for the release named after the new version. For example: `v1.3.6`
* Create a new commit with a message the same as the branch name.
* Create a PR for this branch.
* Wait for the PR to be merged into `main`
1. Switch to `main` and add a new tag on the `main` branch with your new version (named after the release), e.g.
```bash
git checkout main
git tag v1.3.6
```
If you've accidentally created a badly named tag, you can delete it via
```bash
git tag -d badly-named-tag
```
1. Push the new tag up:
a. If you're using a fork of the repo:
```bash
git push upstream refs/tags/v1.3.6
```
b. If you're working straight in this repo:
```bash
git push origin refs/tags/v1.3.6
```
This will trigger [a release build](https://github.com/github/vscode-codeql/releases) on Actions.
* **IMPORTANT** Make sure you are on the `main` branch and your local checkout is fully updated when you add the tag.
* If you accidentally add the tag to the wrong ref, you can just force push it to the right one later.
1. Monitor the status of the release build in the `Release` workflow in the Actions tab.
* DO NOT approve the "publish" stages of the workflow yet.
1. Download the VSIX from the draft GitHub release at the top of [the releases page](https://github.com/github/vscode-codeql/releases) that is created when the release build finishes.
1. Unzip the `.vsix` and inspect its `package.json` to make sure the version is what you expect,
or look at the source if there's any doubt the right code is being shipped.
1. Install the `.vsix` file into your vscode IDE and ensure the extension can load properly. Run a single command (like run query, or add database).
1. Go to the actions tab of the vscode-codeql repository and select the [Release workflow](https://github.com/github/vscode-codeql/actions?query=workflow%3ARelease).
- If there is an authentication failure when publishing, be sure to check that the authentication keys haven't expired. See below.
1. Approve the deployments of the correct Release workflow. This will automatically publish to Open VSX and VS Code Marketplace.
1. Go to the draft GitHub release in [the releases tab of the repository](https://github.com/github/vscode-codeql/releases), click 'Edit', add some summary description, and publish it.
1. Confirm the new release is marked as the latest release at <https://github.com/github/vscode-codeql/releases>.
1. If documentation changes need to be published, notify documentation team that release has been made.
1. Review and merge the version bump PR that is automatically created by Actions.
## Secrets and authentication for publishing
Repository administrators, will need to manage the authentication keys for publishing to the VS Code marketplace and Open VSX. Each requires an authentication token. The VS Code marketplace token expires yearly.
To regenerate the Open VSX token:
1. Log in to the [user settings page on Open VSX](https://open-vsx.org/user-settings/namespaces).
1. Make sure you are a member of the GitHub namespace.
1. Go to the [Access Tokens](https://open-vsx.org/user-settings/tokens) page and generate a new token.
1. Update the secret in the `publish-open-vsx` environment in the project settings.
To regenerate the VSCode Marketplace token, please see our internal documentation. Note that Azure DevOps PATs expire every 90 days and must be regenerated.
Information about testing can be found [here](./docs/testing.md).
## Resources

View File

@@ -7,7 +7,7 @@ The extension is released. You can download it from the [Visual Studio Marketpla
To see what has changed in the last few versions of the extension, see the [Changelog](https://github.com/github/vscode-codeql/blob/main/extensions/ql-vscode/CHANGELOG.md).
[![CI status badge](https://github.com/github/vscode-codeql/workflows/Build%20Extension/badge.svg)](https://github.com/github/vscode-codeql/actions?query=workflow%3A%22Build+Extension%22+branch%3Amaster)
[![VS Marketplace badge](https://vsmarketplacebadge.apphb.com/version/github.vscode-codeql.svg)](https://marketplace.visualstudio.com/items?itemName=github.vscode-codeql)
[![VS Marketplace badge](https://vsmarketplacebadges.dev/version/github.vscode-codeql.svg)](https://marketplace.visualstudio.com/items?itemName=github.vscode-codeql)
## Features
@@ -15,6 +15,7 @@ To see what has changed in the last few versions of the extension, see the [Chan
* Shows the flow of data through the results of path queries, which is essential for triaging security results.
* Provides an easy way to run queries from the large, open source repository of [CodeQL security queries](https://github.com/github/codeql).
* Adds IntelliSense to support you writing and editing your own CodeQL query and library files.
* Supports you running CodeQL queries against thousands of repositories on GitHub using multi-repository variant analysis.
## Project goals and scope

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

89
docs/releasing.md Normal file
View File

@@ -0,0 +1,89 @@
# Releasing (write access required)
1. Double-check the `CHANGELOG.md` contains all desired change comments and has the version to be released with date at the top.
* Go through all recent PRs and make sure they are properly accounted for.
* Make sure all changelog entries have links back to their PR(s) if appropriate.
* For picking the new version number, we default to increasing the patch version number, but make our own judgement about whether a change is big enough to warrant a minor version bump. Common reasons for a minor bump could include:
* Making substantial new features available to all users. This can include lifting a feature flag.
* Breakage in compatibility with recent versions of the CLI.
* Minimum required version of VS Code is increased.
* New telemetry events are added.
* Deprecation or removal of commands.
* Accumulation of many changes, none of which are individually big enough to warrant a minor bump, but which together are. This does not include changes which are purely internal to the extension, such as refactoring, or which are only available behind a feature flag.
1. Double-check that the node version we're using matches the one used for VS Code. If it doesn't, you will then need to update the node version in the following files:
* `.nvmrc` - this will enable `nvm` to automatically switch to the correct node version when you're in the project folder
* `.github/workflows/main.yml` - all the "node-version: <version>" settings
* `.github/workflows/release.yml` - the "node-version: <version>" setting
1. Double-check that the extension `package.json` and `package-lock.json` have the version you intend to release. If you are doing a patch release (as opposed to minor or major version) this should already be correct.
1. Create a PR for this release:
* This PR will contain any missing bits from steps 1, 2 and 3. Most of the time, this will just be updating `CHANGELOG.md` with today's date.
* Create a new branch for the release named after the new version. For example: `v1.3.6`
* Create a new commit with a message the same as the branch name.
* Create a PR for this branch.
* Wait for the PR to be merged into `main`
1. Switch to `main` branch and pull latest changes
1. Lock the `main` branch.
* Go to the [branch protection rules for the `main` branch](https://github.com/github/vscode-codeql/settings/branch_protection_rules/16447115)
* Select "Lock branch"
* Click "Save changes"
1. Ensure that no PRs have been merged since the release PR that you merged. If there were, you might need to unlock `main` temporarily and update the CHANGELOG again.
1. Build the extension `npm run build` and install it on your VS Code using "Install from VSIX".
1. Go through [our test plan](./test-plan.md) to ensure that the extension is working as expected.
1. Switch to `main` and add a new tag on the `main` branch with your new version (named after the release), e.g.
```bash
git checkout main
git tag v1.3.6
```
If you've accidentally created a badly named tag, you can delete it via
```bash
git tag -d badly-named-tag
```
1. Unlock the main branch
* Go to the [branch protection rules for the `main` branch](https://github.com/github/vscode-codeql/settings/branch_protection_rules/16447115)
* Deselect "Lock branch"
* Click "Save changes"
1. Push the new tag up:
a. If you're using a fork of the repo:
```bash
git push upstream refs/tags/v1.3.6
```
b. If you're working straight in this repo:
```bash
git push origin refs/tags/v1.3.6
```
This will trigger [a release build](https://github.com/github/vscode-codeql/releases) on Actions.
* **IMPORTANT** Make sure you are on the `main` branch and your local checkout is fully updated when you add the tag.
* If you accidentally add the tag to the wrong ref, you can just force push it to the right one later.
1. Monitor the status of the release build in the `Release` workflow in the Actions tab.
* DO NOT approve the "publish" stages of the workflow yet.
1. Download the VSIX from the draft GitHub release at the top of [the releases page](https://github.com/github/vscode-codeql/releases) that is created when the release build finishes.
1. Unzip the `.vsix` and inspect its `package.json` to make sure the version is what you expect,
or look at the source if there's any doubt the right code is being shipped.
1. Install the `.vsix` file into your vscode IDE and ensure the extension can load properly. Run a single command (like run query, or add database).
1. Go to the actions tab of the vscode-codeql repository and select the [Release workflow](https://github.com/github/vscode-codeql/actions?query=workflow%3ARelease).
- If there is an authentication failure when publishing, be sure to check that the authentication keys haven't expired. See below.
1. Approve the deployments of the correct Release workflow. This will automatically publish to Open VSX and VS Code Marketplace.
1. Go to the draft GitHub release in [the releases tab of the repository](https://github.com/github/vscode-codeql/releases), click 'Edit', add some summary description, and publish it.
1. Confirm the new release is marked as the latest release at <https://github.com/github/vscode-codeql/releases>.
1. If documentation changes need to be published, notify documentation team that release has been made.
1. Review and merge the version bump PR that is automatically created by Actions.
## Secrets and authentication for publishing
Repository administrators, will need to manage the authentication keys for publishing to the VS Code marketplace and Open VSX. Each requires an authentication token. The VS Code marketplace token expires yearly.
To regenerate the Open VSX token:
1. Log in to the [user settings page on Open VSX](https://open-vsx.org/user-settings/namespaces).
1. Make sure you are a member of the GitHub namespace.
1. Go to the [Access Tokens](https://open-vsx.org/user-settings/tokens) page and generate a new token.
1. Update the secret in the `publish-open-vsx` environment in the project settings.
To regenerate the VSCode Marketplace token, please see our internal documentation. Note that Azure DevOps PATs expire every 90 days and must be regenerated.

337
docs/test-plan.md Normal file
View File

@@ -0,0 +1,337 @@
# Test Plan
This document describes the manual test plan for the QL extension for Visual Studio Code.
The plan will be executed manually to start with but the goal is to eventually automate parts of the process (based on
effort vs value basis).
## What this doesn't cover
We don't need to test features (and permutations of features) that are covered by automated tests.
## Before releasing the VS Code extension
- Go through the required test cases listed below
- Check major PRs since the previous release for specific one-off things to test. Based on that, you might want to
choose to go through some of the Optional Test Cases.
- Run a query using the existing version of the extension (to generate an "old" query history item)
## Required Test Cases
### Test Case 1: MRVA - Running a problem path query and viewing results
1. Open the [UnsafeJQueryPlugin query](https://github.com/github/codeql/blob/main/javascript/ql/src/Security/CWE-079/UnsafeJQueryPlugin.ql).
2. Run a MRVA against the following repo list:
```json
{
"name": "test-repo-list",
"repositories": [
"angular-cn/ng-nice",
"apache/hadoop",
"apache/hive"
]
}
```
3. Check that a notification message pops up and the results view is opened.
4. Check the query history. It should:
- Show that an item has been added to the query history
- The item should be marked as "in progress".
5. Once the query starts:
- Check the results view
- Check the code paths view, including the code paths drop down menu.
- Check that the repository filter box works
- Click links to files/locations on GitHub
- Check that the query history item is updated to show the number of results
6. Once the query completes:
- Check that the query history item is updated to show the query status as "complete"
### Test Case 2: MRVA - Running a problem query and viewing results
1. Open the [ReDoS query](https://github.com/github/codeql/blob/main/javascript/ql/src/Performance/ReDoS.ql).
2. Run a MRVA against the "Top 10" repositories.
3. Check that there is a notification message.
4. Check the query history. It should:
- Show that an item has been added to the query history
- The item should be marked as "in progress".
5. Once the query starts:
- Check that a notification is shown with a link to the results view
- Check that the results are rendered with an alert message and a highlighted code snippet:
![highlighted-code-snippet](images/highlighted-code-snippet.png)
### Test Case 3: MRVA - Running a non-problem query and viewing results
1. Open the [FunLinesOfCode query](https://github.com/github/codeql/blob/main/cpp/ql/src/Metrics/Functions/FunLinesOfCode.ql).
2. Run a MRVA against a single repository (e.g. `google/brotli`).
3. Once the query starts:
- Open the query results
- Check that the results show up in a table:
![results-table](images/results-table.png)
### Test Case 4: MRVA - Interacting with query history
1. Click a history item (for MRVA):
- Check that exporting results works
- Check that sorting results works
- Check that copying repo lists works
2. Open the query results directory:
- Check that the correct directory is opened and there are results in it
3. View logs
- Check that the correct workflow is opened
### Test Case 5: MRVA - Canceling a variant analysis run
Run one of the above MRVAs, but cancel it from within VS Code:
- Check that the query is canceled and the query history item is updated.
- Check that the workflow run is also canceled.
- Check that any available results are visible in VS Code.
### Test Case 6: MRVA - Change to a different colour theme
Open one of the above MRVAs, try changing to a different colour theme and check that everything looks sensible.
Are there any components that are not showing up?
## Optional Test Cases
These are mostly aimed at MRVA, but some of them are also applicable to non-MRVA queries.
### Selecting repositories to run on
#### Test case 1: Running a query on a single repository
1. When the repository exists and is public
1. Has a CodeQL database for the correct language
2. Has a CodeQL database for another language
3. Does not have any CodeQL databases
2. When the repository exists and is private
1. Is accessible and has a CodeQL database
2. Is not accessible
3. When the repository does not exist
#### Test case 2: Running a query on a custom repository list
1. The repository list is non-empty
1. All repositories in the list have a CodeQL database
2. Some but not all repositories in the list have a CodeQL database
3. No repositories in the list have a CodeQL database
2. The repository list is empty
#### Test case 3: Running a query on all repositories in an organization
1. The org exists
1. The org contains repositories that have CodeQL databases
2. The org contains repositories of the right language but without CodeQL databases
3. The org contains repositories not of the right language
4. The org contains private repositories that are inaccessible
2. The org does not exist
### Using different types of controller repos
#### Test case 1: Running a query when the controller repository is public
1. Can run queries on public repositories
2. Can not run queries on private repositories
#### Test case 2: Running a query when the controller repository is private
1. Can run queries on public repositories
2. Can run queries on private repositories
#### Test case 3: Running a query when the controller repo exists but you do not have write access
1. Cannot run queries
#### Test case 4: Running a query when the controller repo doesnt exist
1. Cannot run queries
#### Test case 5: Running a query when the "config field" for the controller repo is not set
1. Cannot run queries
### Query History
This requires running a MRVA query and viewing the query history.
The first test case specifies actions that you can do when the query is first run and is in "pending" state. We start
with this since it has quite a limited number of actions you can do.
#### Test case 1: When variant analysis state is "pending"
1. Starts monitoring variant analysis
2. Cannot open query history item
3. Can delete a query history item
1. Item is removed from list in UI
2. Files on dist are deleted (can get to files using "open query directory")
4. Can sort query history items
1. By name
2. By query date
3. By result count
5. Cannot open query directory
6. Can open query that produced these results
1. When the file still exists and has not moved
2. When the file does not exist
7. Cannot view logs
8. Cannot copy repository list
9. Cannot export results
10. Cannot select to create a gist
11. Cannot select to save as markdown
12. Cannot cancel analysis
#### Test case 2: When the variant analysis state is not "pending"
1. Query history is loaded when VSCode starts
2. Handles when action workflow was canceled while VSCode was closed
3. Can open query history item
1. Manually by clicking on them
2. Automatically when VSCode starts (if they were open when VSCode was last used)
4. Can delete a query history item
1. Item is removed from list in UI
2. Files on dist are deleted (can get to files using "open query directory")
5. Can sort query history items
1. By name
2. By query date
3. By result count
6. Can open query directory
7. Can open query that produced these results
1. When the file still exists and has not moved
2. When the file does not exist
8. Can view logs
9. Can copy repository list
1. Text is copied to clipboard
2. Text is a valid repository list
10. Can export results
11. Can select to create gist
1. A gist is created
2. The first thing in the gist is a summary
3. Contains a file for each repository with results
4. A popup links you to the gist
12. Can select to save as markdown
1. A directory is created on disk
2. Contains a summary file
3. Contains a file for each repository with results
4. A popup allows you to open the directory
#### Test case 3: When variant analysis state is "in_progress"
1. Starts monitoring variant analysis
1. Ready results are downloaded
2. Can cancel analysis
1. Causes the actions run to be canceled
#### Test case 4: When variant analysis state is in final state ("succeeded"/"failed"/"canceled")
1. Stops monitoring variant analysis
1. All results are downloaded if state is succeeded
2. Otherwise, ready results are downloaded, if any are available
2. Cannot cancel analysis
### MRVA results view
This requires running a MRVA query and seeing the results view.
#### Test case 1: When variant analysis state is "pending"
1. Can open a results view
2. Results view opens automatically
- When starting variant analysis run
- When VSCode opens (if view was open when VSCode was closed)
3. Results view is empty
#### Test case 2: When variant analysis state is not "pending"
1. Can open a results view
2. Results view opens automatically
1. When starting variant analysis run
2. When VSCode opens (if view was open when VSCode was closed)
3. Can copy repository list
1. Text is copied to clipboard
2. Text is a valid repository list
4. Can export results
1. Only includes repos that you have selected (also see section from query history)
5. Can cancel analysis
6. Can open query file
1. When the file still exists and has not moved
2. When the file does not exist
7. Can open query text
8. Can sort repos
1. By name
2. By results
3. By stars
4. By last updated
9. Can filter repos
10. Shows correct statistics
1. Total number of results
2. Total number of repositories
3. Duration
11. Can see live results
1. Results appear in extension as soon as each query is completed
12. Can view interpreted results (i.e. for a "problem" query)
1. Can view non-path results
2. Can view code paths for "path-problem" queries
13. Can view raw results (i.e. for a non "problem" query)
1. Renders a table
14. Can see skipped repositories
1. Can see repos with no db in a tab
1. Shown warning that explains the tab
2. Can see repos with no access in a tab
1. Shown warning that explains the tab
3. Only shows tab when there are skipped repos
15. Result downloads
1. All results are downloaded automatically
2. Download status is indicated by a spinner (Not currently any indication of progress beyond "downloading" and "not downloading")
3. Only 3 items are downloaded at a time
4. Results for completed queries are still downloaded when
1. Some but not all queries failed
2. The variant analysis was canceled after some queries completed
#### Test case 3: When variant analysis state is in "succeeded" state
1. Can view logs
2. All results are downloaded
#### Test case 4: When variant analysis is in "failed" or "canceled" state
1. Can view logs
1. Results for finished queries are still downloaded.
### MRVA repositories panel
1. Add a list
1. Add a database at the top level
1. Add a database to a list
1. Add a the same database at a top-level and in a list
1. Delete a list
1. Delete a database from the top level
1. Delete a database from a list
1. Add an owner
1. Remove an owner
1. Rename a list
1. Open on GitHub
1. Select a list (via "Select" button and via context menu action)
1. Run MRVA against a user-defined list
1. Run MRVA against a top-N list
1. Run MRVA against an owner
1. Run MRVA against a database
1. Copy repo list
1. Open config file
1. Make changes via config file (ensure JSON schema is helping out)
1. Close and re-open VS Code (ensure lists are there)
1. Collapse/expand tree nodes
Error cases that trigger an error notification:
1. Try to add a list with a name that already exists
1. Try to add a top-level database that already exists
1. Try to add a database in a list that already exists in the list
Error cases that show an error in the panel (and only the edit button should be visible):
1. Edit the db config file directly and save invalid JSON
1. Edit the db config file directly and save valid JSON but invalid config (e.g. add an unknown property)
1. Edit the db config file directly and save two lists with the same name
Cases where there the welcome view is shown:
1. No controller repo is set in the user's settings JSON.

131
docs/testing.md Normal file
View File

@@ -0,0 +1,131 @@
# Testing
We have several types of tests:
* Unit tests: these live in the `tests/unit-tests/` directory
* View tests: these live in `src/view/variant-analysis/__tests__/`
* VSCode integration tests:
* `test/vscode-tests/activated-extension` tests: These are intended to cover functionality that require the full extension to be activated but don't require the CLI. This suite is not run against multiple versions of the CLI in CI.
* `test/vscode-tests/no-workspace` tests: These are intended to cover functionality around not having a workspace. The extension is not activated in these tests.
* `test/vscode-tests/minimal-workspace` tests: These are intended to cover functionality that need a workspace but don't require the full extension to be activated.
* CLI integration tests: these live in `test/vscode-tests/cli-integration`
* These tests are intended to cover functionality that is related to the integration between the CodeQL CLI and the extension. These tests are run against each supported versions of the CLI in CI.
The CLI integration tests require an instance of the CodeQL CLI to run so they will require some extra setup steps. When adding new tests to our test suite, please be mindful of whether they need to be in the cli-integration folder. If the tests don't depend on the CLI, they are better suited to being a VSCode integration test.
Any test data you're using (sample projects, config files, etc.) must go in a `test/vscode-tests/*/data` directory. When you run the tests, the test runner will copy the data directory to `out/vscode-tests/*/data`.
## Running the tests
Pre-requisites:
1. Run `npm run build`.
2. You will need to have `npm run watch` running in the background.
### 1. From the terminal
Then, from the `extensions/ql-vscode` directory, use the appropriate command to run the tests:
* Unit tests: `npm run test:unit`
* View Tests: `npm test:view`
* VSCode integration tests: `npm run test:vscode-integration`
#### CLI integration tests
The CLI integration tests require the CodeQL standard libraries in order to run so you will need to clone a local copy of the `github/codeql` repository.
1. Set the `TEST_CODEQL_PATH` environment variable: running from a terminal, you _must_ set the `TEST_CODEQL_PATH` variable to point to a checkout of the `github/codeql` repository. The appropriate CLI version will be downloaded as part of the test.
2. Run your test command:
```shell
cd extensions/ql-vscode && npm run test:cli-integration
```
### 2. From VSCode
Alternatively, you can run the tests inside of VSCode. There are several VSCode launch configurations defined that run the unit and integration tests.
You will need to run tests using a task from inside of VS Code, under the "Run and Debug" view:
* Unit tests: run the _Launch Unit Tests - React_ task
* View Tests: run the _Launch Unit Tests_ task
* VSCode integration tests: run the _Launch Unit Tests - No Workspace_ and _Launch Unit Tests - Minimal Workspace_ tasks
#### CLI integration tests
The CLI integration tests require the CodeQL standard libraries in order to run so you will need to clone a local copy of the `github/codeql` repository.
1. Set the `TEST_CODEQL_PATH` environment variable: running from a terminal, you _must_ set the `TEST_CODEQL_PATH` variable to point to a checkout of the `github/codeql` repository. The appropriate CLI version will be downloaded as part of the test.
2. Set the codeql path in VSCode's launch configuration: open `launch.json` and under the _Launch Integration Tests - With CLI_ section, uncomment the `"${workspaceRoot}/../codeql"` line. If you've cloned the `github/codeql` repo to a different path, replace the value with the correct path.
3. Run the VSCode task from the "Run and Debug" view called _Launch Integration Tests - With CLI_.
## Running a single test
### 1. From the terminal
The easiest way to run a single test is to change the `it` of the test to `it.only` and then run the test command with some additional options
to only run tests for this specific file. For example, to run the test `test/vscode-tests/cli-integration/run-queries.test.ts`:
```shell
npm run test:cli-integration -- --runTestsByPath test/vscode-tests/cli-integration/run-queries.test.ts
```
You can also use the `--testNamePattern` option to run a specific test within a file. For example, to run the test `test/vscode-tests/cli-integration/run-queries.test.ts`:
```shell
npm run test:cli-integration -- --runTestsByPath test/vscode-tests/cli-integration/run-queries.test.ts --testNamePattern "should create a QueryEvaluationInfo"
```
### 2. From VSCode
Alternatively, you can run a single test inside VSCode. To do so, install the [Jest Runner](https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner) extension. Then,
you will have quicklinks to run a single test from within test files. To run a single unit or integration test, click the "Run" button. Debugging a single test is currently only supported
for unit tests by default. To debug integration tests, open the `.vscode/settings.json` file and uncomment the `jestrunner.debugOptions` lines. This will allow you to debug integration tests.
Please make sure to revert this change before committing; with this setting enabled, it is not possible to debug unit tests.
Without the Jest Runner extension, you can also use the "Launch Selected Unit Test (vscode-codeql)" launch configuration to run a single unit test.
## Using a mock GitHub API server
Multi-Repo Variant Analyses (MRVA) rely on the GitHub API. In order to make development and testing easy, we have functionality that allows us to intercept requests to the GitHub API and provide mock responses.
### Using a pre-recorded test scenario
To run a mock MRVA scenario, follow these steps:
1. Enable the mock GitHub API server by adding the following in your VS Code user settings (which can be found by running the `Preferences: Open User Settings (JSON)` VS Code command):
```json
"codeQL.mockGitHubApiServer": {
"enabled": true
}
```
1. Run the `CodeQL: Mock GitHub API Server: Load Scenario` command from the command pallet, and choose one of the scenarios to load.
1. Execute a normal MRVA. At this point you should see the scenario being played out, rather than an actual MRVA running.
1. Once you're done, you can stop using the mock scenario with `CodeQL: Mock GitHub API Server: Unload Scenario`
If you want to replay the same scenario you should unload and reload it so requests are replayed from the start.
### Recording a new test scenario
To record a new mock MRVA scenario, follow these steps:
1. Enable the mock GitHub API server by adding the following in your VS Code user settings (which can be found by running the `Preferences: Open User Settings (JSON)` VS Code command):
```json
"codeQL.mockGitHubApiServer": {
"enabled": true
}
```
1. Run the `CodeQL: Mock GitHub API Server: Start Scenario Recording` VS Code command from the command pallet.
1. Execute a normal MRVA.
1. Once what you wanted to record is done (e.g. the MRVA has finished), then run the `CodeQL: Mock GitHub API Server: Save Scenario` command from the command pallet.
1. The scenario should then be available for replaying.
If you want to cancel recording, run the `CodeQL: Mock GitHub API Server: Cancel Scenario Recording` command.
Once the scenario has been recorded, it's often useful to remove some of the requests to speed up the replay, particularly ones that fetch the variant analysis status. Once some of the request files have manually been removed, the [fix-scenario-file-numbering script](../extensions/ql-vscode/scripts/fix-scenario-file-numbering.ts) can be used to update the number of the files. See the script file for details on how to use.
### Scenario data location
Pre-recorded scenarios are stored in `./src/mocks/scenarios`. However, it's possible to configure the location, by setting the `codeQL.mockGitHubApiServer.scenariosPath` configuration property in the VS Code user settings.

View File

@@ -1,6 +1,7 @@
.vscode-test/
node_modules/
out/
build/
# Include the Storybook config
!.storybook

View File

@@ -1,14 +1,20 @@
module.exports = {
const { resolve } = require("path");
const baseConfig = {
parser: "@typescript-eslint/parser",
parserOptions: {
ecmaVersion: 2018,
sourceType: "module",
project: ["tsconfig.json", "./src/**/tsconfig.json", "./gulpfile.ts/tsconfig.json", "./scripts/tsconfig.json", "./.storybook/tsconfig.json"],
project: [
resolve(__dirname, "tsconfig.lint.json"),
resolve(__dirname, "src/**/tsconfig.json"),
resolve(__dirname, "test/**/tsconfig.json"),
resolve(__dirname, "gulpfile.ts/tsconfig.json"),
resolve(__dirname, "scripts/tsconfig.json"),
resolve(__dirname, ".storybook/tsconfig.json"),
],
},
plugins: [
"github",
"@typescript-eslint"
],
plugins: ["github", "@typescript-eslint", "etc"],
env: {
node: true,
es6: true,
@@ -20,9 +26,10 @@ module.exports = {
"plugin:github/typescript",
"plugin:jest-dom/recommended",
"plugin:prettier/recommended",
"plugin:@typescript-eslint/recommended"
"plugin:@typescript-eslint/recommended",
],
rules: {
"@typescript-eslint/await-thenable": "error",
"@typescript-eslint/no-use-before-define": 0,
"@typescript-eslint/no-unused-vars": [
"warn",
@@ -36,15 +43,15 @@ module.exports = {
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-non-null-assertion": "off",
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/no-floating-promises": [ "error", { ignoreVoid: true } ],
"@typescript-eslint/no-floating-promises": ["error", { ignoreVoid: true }],
"@typescript-eslint/no-invalid-this": "off",
"@typescript-eslint/no-shadow": "off",
"prefer-const": ["warn", { destructuring: "all" }],
"@typescript-eslint/no-throw-literal": "error",
"no-useless-escape": 0,
"camelcase": "off",
"eqeqeq": "off",
camelcase: "off",
"escompat/no-regexp-lookbehind": "off",
"etc/no-implicit-any-catch": "error",
"filenames/match-regex": "off",
"filenames/match-regexp": "off",
"func-style": "off",
@@ -70,3 +77,102 @@ module.exports = {
"github/no-then": "off",
},
};
module.exports = {
root: true,
...baseConfig,
overrides: [
{
files: ["src/stories/**/*"],
parserOptions: {
project: resolve(__dirname, "src/stories/tsconfig.json"),
},
extends: [
...baseConfig.extends,
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:storybook/recommended",
],
rules: {
...baseConfig.rules,
},
settings: {
react: {
version: "detect",
},
},
},
{
files: ["src/view/**/*"],
parserOptions: {
project: resolve(__dirname, "src/view/tsconfig.json"),
},
extends: [
...baseConfig.extends,
"plugin:react/recommended",
"plugin:react-hooks/recommended",
],
rules: {
...baseConfig.rules,
},
settings: {
react: {
version: "detect",
},
},
},
{
files: ["test/**/*"],
parserOptions: {
project: resolve(__dirname, "test/tsconfig.json"),
},
env: {
jest: true,
},
},
{
files: ["test/vscode-tests/**/*"],
parserOptions: {
project: resolve(__dirname, "test/tsconfig.json"),
},
env: {
jest: true,
},
rules: {
...baseConfig.rules,
"@typescript-eslint/ban-types": [
"error",
{
// For a full list of the default banned types, see:
// https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/ban-types.md
extendDefaults: true,
types: {
// Don't complain about the `Function` type in test files. (Default is `true`.)
Function: false,
},
},
],
},
},
{
files: [
".eslintrc.js",
"test/**/jest-runner-vscode.config.js",
"test/**/jest-runner-vscode.config.base.js",
],
parser: undefined,
plugins: ["github"],
extends: [
"eslint:recommended",
"plugin:github/recommended",
"plugin:prettier/recommended",
],
rules: {
"import/no-commonjs": "off",
"prefer-template": "off",
"filenames/match-regex": "off",
"@typescript-eslint/no-var-requires": "off",
},
},
],
};

View File

@@ -2,5 +2,9 @@
node_modules/
out/
# This file gets written by an actions workflow.
# Don't try to format it.
supported_cli_versions.json
# Include the Storybook config
!.storybook

View File

@@ -14,3 +14,4 @@ gulpfile.js/**
tsconfig.json
.prettierrc
vsc-extension-quickstart.md
node_modules/**

View File

@@ -1,5 +1,33 @@
# CodeQL for Visual Studio Code: Changelog
## 1.8.1 - 23 March 2023
- Show data flow paths of a variant analysis in a new tab. [#2172](https://github.com/github/vscode-codeql/pull/2172) & [#2182](https://github.com/github/vscode-codeql/pull/2182)
- Show labels of entities in exported CSV results. [#2170](https://github.com/github/vscode-codeql/pull/2170)
## 1.8.0 - 9 March 2023
- Send telemetry about unhandled errors happening within the extension. [#2125](https://github.com/github/vscode-codeql/pull/2125)
- Enable multi-repository variant analysis. [#2144](https://github.com/github/vscode-codeql/pull/2144)
## 1.7.11 - 1 March 2023
- Enable collection of telemetry concerning interactions with UI elements, including buttons, links, and other inputs. [#2114](https://github.com/github/vscode-codeql/pull/2114)
- Prevent the automatic installation of CodeQL CLI version 2.12.3 to avoid a bug in the language server. CodeQL CLI 2.12.2 will be used instead. [#2126](https://github.com/github/vscode-codeql/pull/2126)
## 1.7.10 - 23 February 2023
- Fix bug that was causing unwanted error notifications.
## 1.7.9 - 20 February 2023
No user facing changes.
## 1.7.8 - 2 February 2023
- Renamed command "CodeQL: Run Query" to "CodeQL: Run Query on Selected Database". [#1962](https://github.com/github/vscode-codeql/pull/1962)
- Remove support for CodeQL CLI versions older than 2.7.6. [#1788](https://github.com/github/vscode-codeql/pull/1788)
## 1.7.7 - 13 December 2022
- Increase the required version of VS Code to 1.67.0. [#1662](https://github.com/github/vscode-codeql/pull/1662)

View File

@@ -94,7 +94,7 @@ The instructions below assume that you're using the CodeQL starter workspace, or
1. Expand the `ql` folder and locate a query to run. The standard queries are grouped by target language and then type, for example: `ql/java/ql/src/Likely Bugs`.
1. Open a query (`.ql`) file.
1. Right-click in the query window and select **CodeQL: Run Query**. Alternatively, open the Command Palette (**Ctrl+Shift+P** or **Cmd+Shift+P**), type `Run Query`, then select **CodeQL: Run Query**.
1. Right-click in the query window and select **CodeQL: Run Query on Selected Database**. Alternatively, open the Command Palette (**Ctrl+Shift+P** or **Cmd+Shift+P**), type `Run Query`, then select **CodeQL: Run Query on Selected Database**.
The CodeQL extension runs the query on the current database using the CLI and reports progress in the bottom right corner of the application.
When the results are ready, they're displayed in the CodeQL Query Results view. Use the dropdown menu to choose between different forms of result output.

View File

@@ -0,0 +1,127 @@
{
"type": "object",
"properties": {
"$schema": {
"type": "string"
},
"version": {
"type": "integer"
},
"databases": {
"type": "object",
"properties": {
"variantAnalysis": {
"type": "object",
"properties": {
"repositoryLists": {
"type": "array",
"items": {
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 1
},
"repositories": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[a-zA-Z0-9-_\\.]+/[a-zA-Z0-9-_\\.]+$"
}
}
},
"required": ["name", "repositories"],
"additionalProperties": false
}
},
"owners": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[a-zA-Z0-9-_\\.]+$"
}
},
"repositories": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[a-zA-Z0-9-_\\.]+/[a-zA-Z0-9-_\\.]+$"
}
}
},
"required": ["repositoryLists", "owners", "repositories"],
"additionalProperties": false
}
},
"required": ["variantAnalysis"],
"additionalProperties": false
},
"selected": {
"type": "object",
"oneOf": [
{
"properties": {
"kind": {
"type": "string",
"enum": ["variantAnalysisSystemDefinedList"]
},
"listName": {
"type": "string",
"minLength": 1
}
},
"required": ["kind", "listName"],
"additionalProperties": false
},
{
"properties": {
"kind": {
"type": "string",
"enum": ["variantAnalysisUserDefinedList"]
},
"listName": {
"type": "string",
"minLength": 1
}
},
"required": ["kind", "listName"],
"additionalProperties": false
},
{
"properties": {
"kind": {
"type": "string",
"enum": ["variantAnalysisOwner"]
},
"ownerName": {
"type": "string",
"minLength": 1
}
},
"required": ["kind", "ownerName"],
"additionalProperties": false
},
{
"properties": {
"kind": {
"type": "string",
"enum": ["variantAnalysisRepository"]
},
"repositoryName": {
"type": "string",
"minLength": 1
},
"listName": {
"type": "string",
"minLength": 1
}
},
"required": ["kind", "repositoryName"],
"additionalProperties": false
}
]
}
},
"required": ["databases", "version"],
"additionalProperties": false
}

View File

@@ -13,7 +13,7 @@ export function injectAppInsightsKey() {
}
// replace the key
return src(["out/telemetry.js"])
return src(["out/extension.js"])
.pipe(replace(/REPLACE-APP-INSIGHTS-KEY/, process.env.APP_INSIGHTS_KEY))
.pipe(dest("out/"));
}

View File

@@ -8,6 +8,7 @@ import {
writeFile,
} from "fs-extra";
import { resolve, join } from "path";
import { isDevBuild } from "./dev";
export interface DeployedPackage {
distPath: string;
@@ -22,21 +23,27 @@ const packageFiles = [
"language-configuration.json",
"snippets.json",
"media",
"node_modules",
"out",
"workspace-databases-schema.json",
"databases-schema.json",
];
async function copyDirectory(
sourcePath: string,
destPath: string,
): Promise<void> {
console.log(`copying ${sourcePath} to ${destPath}`);
await copy(sourcePath, destPath);
}
async function copyPackage(
sourcePath: string,
destPath: string,
): Promise<void> {
for (const file of packageFiles) {
console.log(
`copying ${resolve(sourcePath, file)} to ${resolve(destPath, file)}`,
);
await copy(resolve(sourcePath, file), resolve(destPath, file));
}
await Promise.all(
packageFiles.map((file) =>
copyDirectory(resolve(sourcePath, file), resolve(destPath, file)),
),
);
}
export async function deployPackage(
@@ -47,8 +54,6 @@ export async function deployPackage(
await readFile(packageJsonPath, "utf8"),
);
// Default to development build; use flag --release to indicate release build.
const isDevBuild = !process.argv.includes("--release");
const distDir = join(__dirname, "../../../dist");
await mkdirs(distDir);

View File

@@ -0,0 +1,2 @@
// Default to development build; use flag --release to indicate release build.
export const isDevBuild = !process.argv.includes("--release");

View File

@@ -1,7 +1,13 @@
import { series, parallel } from "gulp";
import { compileTypeScript, watchTypeScript, cleanOutput } from "./typescript";
import { parallel, series } from "gulp";
import {
compileEsbuild,
watchEsbuild,
checkTypeScript,
watchCheckTypeScript,
cleanOutput,
copyWasmFiles,
} from "./typescript";
import { compileTextMateGrammar } from "./textmate";
import { copyTestData, watchTestData } from "./tests";
import { compileView, watchView } from "./webpack";
import { packageExtension } from "./package";
import { injectAppInsightsKey } from "./appInsights";
@@ -9,21 +15,25 @@ import { injectAppInsightsKey } from "./appInsights";
export const buildWithoutPackage = series(
cleanOutput,
parallel(
compileTypeScript,
compileEsbuild,
copyWasmFiles,
checkTypeScript,
compileTextMateGrammar,
compileView,
copyTestData,
),
);
export const watch = parallel(watchEsbuild, watchCheckTypeScript, watchView);
export {
cleanOutput,
compileTextMateGrammar,
watchTypeScript,
watchEsbuild,
watchCheckTypeScript,
watchView,
compileTypeScript,
copyTestData,
watchTestData,
compileEsbuild,
copyWasmFiles,
checkTypeScript,
injectAppInsightsKey,
compileView,
};

View File

@@ -3,7 +3,9 @@ import { deployPackage } from "./deploy";
import { spawn } from "child-process-promise";
export async function packageExtension(): Promise<void> {
const deployedPackage = await deployPackage(resolve("package.json"));
const deployedPackage = await deployPackage(
resolve(__dirname, "../package.json"),
);
console.log(
`Packaging extension '${deployedPackage.name}@${deployedPackage.version}'...`,
);
@@ -15,8 +17,9 @@ export async function packageExtension(): Promise<void> {
"..",
`${deployedPackage.name}-${deployedPackage.version}.vsix`,
),
"--no-dependencies",
];
const proc = spawn("./node_modules/.bin/vsce", args, {
const proc = spawn(resolve(__dirname, "../node_modules/.bin/vsce"), args, {
cwd: deployedPackage.distPath,
});
proc.childProcess.stdout!.on("data", (data) => {

View File

@@ -1,21 +0,0 @@
import { watch, src, dest } from "gulp";
export function copyTestData() {
return Promise.all([copyNoWorkspaceData(), copyCliIntegrationData()]);
}
export function watchTestData() {
return watch(["src/vscode-tests/*/data/**/*"], copyTestData);
}
function copyNoWorkspaceData() {
return src("src/vscode-tests/no-workspace/data/**/*").pipe(
dest("out/vscode-tests/no-workspace/data"),
);
}
function copyCliIntegrationData() {
return src("src/vscode-tests/cli-integration/data/**/*").pipe(
dest("out/vscode-tests/cli-integration/data"),
);
}

View File

@@ -1,7 +1,7 @@
import { src, dest } from "gulp";
import { dest, src } from "gulp";
import { load } from "js-yaml";
import { obj } from "through2";
import * as PluginError from "plugin-error";
import PluginError from "plugin-error";
import * as Vinyl from "vinyl";
/**

View File

@@ -1,8 +1,8 @@
import { gray, red } from "ansi-colors";
import { dest, watch } from "gulp";
import { init, write } from "gulp-sourcemaps";
import * as ts from "gulp-typescript";
import * as del from "del";
import { dest, src, watch } from "gulp";
import esbuild from "gulp-esbuild";
import ts from "gulp-typescript";
import del from "del";
function goodReporter(): ts.reporter.Reporter {
return {
@@ -35,20 +35,46 @@ export function cleanOutput() {
: Promise.resolve();
}
export function compileTypeScript() {
return tsProject
.src()
.pipe(init())
.pipe(tsProject(goodReporter()))
export function compileEsbuild() {
return src("./src/extension.ts")
.pipe(
write(".", {
includeContent: false,
sourceRoot: ".",
esbuild({
outfile: "extension.js",
bundle: true,
external: ["vscode", "fsevents"],
format: "cjs",
platform: "node",
target: "es2020",
sourcemap: "linked",
sourceRoot: "..",
loader: {
".node": "copy",
},
}),
)
.pipe(dest("out"));
}
export function watchTypeScript() {
watch("src/**/*.ts", compileTypeScript);
export function watchEsbuild() {
watch("src/**/*.ts", compileEsbuild);
}
export function checkTypeScript() {
// This doesn't actually output the TypeScript files, it just
// runs the TypeScript compiler and reports any errors.
return tsProject.src().pipe(tsProject(goodReporter()));
}
export function watchCheckTypeScript() {
watch("src/**/*.ts", checkTypeScript);
}
export function copyWasmFiles() {
// We need to copy this file for the source-map package to work. Without this fie, the source-map
// package is not able to load the WASM file because we are not including the full node_modules
// directory. In version 0.7.4, it is not possible to call SourceMapConsumer.initialize in Node environments
// to configure the path to the WASM file. So, source-map will always load the file from `__dirname/mappings.wasm`.
// In version 0.8.0, it may be possible to do this properly by calling SourceMapConsumer.initialize by
// using the "browser" field in source-map's package.json to load the WASM file from a given file path.
return src("node_modules/source-map/lib/mappings.wasm").pipe(dest("out"));
}

View File

@@ -1,9 +1,10 @@
import { resolve } from "path";
import * as webpack from "webpack";
import * as MiniCssExtractPlugin from "mini-css-extract-plugin";
import MiniCssExtractPlugin from "mini-css-extract-plugin";
import { isDevBuild } from "./dev";
export const config: webpack.Configuration = {
mode: "development",
mode: isDevBuild ? "development" : "production",
entry: {
webview: "./src/view/webview.tsx",
},
@@ -11,7 +12,7 @@ export const config: webpack.Configuration = {
path: resolve(__dirname, "..", "out"),
filename: "[name].js",
},
devtool: "inline-source-map",
devtool: isDevBuild ? "inline-source-map" : "source-map",
resolve: {
extensions: [".js", ".ts", ".tsx", ".json"],
fallback: {
@@ -53,6 +54,9 @@ export const config: webpack.Configuration = {
MiniCssExtractPlugin.loader,
{
loader: "css-loader",
options: {
sourceMap: true,
},
},
],
},

View File

@@ -1,4 +1,4 @@
import * as webpack from "webpack";
import webpack from "webpack";
import { config } from "./webpack.config";
export function compileView(cb: (err?: Error) => void) {

View File

@@ -7,9 +7,10 @@
module.exports = {
projects: [
"<rootDir>/src/view",
"<rootDir>/test",
"<rootDir>/src/vscode-tests/cli-integration",
"<rootDir>/src/vscode-tests/no-workspace",
"<rootDir>/src/vscode-tests/minimal-workspace",
"<rootDir>/test/unit-tests",
"<rootDir>/test/vscode-tests/activated-extension",
"<rootDir>/test/vscode-tests/cli-integration",
"<rootDir>/test/vscode-tests/no-workspace",
"<rootDir>/test/vscode-tests/minimal-workspace",
],
};

View File

@@ -1,56 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="30px"
width="30px"
fill="#000000"
version="1.1"
x="0px"
y="0px"
viewBox="0 0 100 100"
style="enable-background:new 0 0 100 100;"
xml:space="preserve"
id="svg3895"
sodipodi:docname="check-dark-mode.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)"><metadata
id="metadata3901"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs3899" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1179"
inkscape:window-height="701"
id="namedview3897"
showgrid="false"
inkscape:zoom="7.8666667"
inkscape:cx="-22.881356"
inkscape:cy="15"
inkscape:window-x="0"
inkscape:window-y="28"
inkscape:window-maximized="0"
inkscape:current-layer="svg3895" /><g
transform="translate(-452.57627,-74.457627)"
id="g3893"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1"><g
id="g3891"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1"><g
id="g3889"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1"><path
d="M 457.98136,131.82373 488.80508,163.49492 548.8661,92.416949 535.93729,81.60678 487.85763,144.41695 468.2678,120.58983 Z"
id="path3887"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc"
style="fill:#ffffff;fill-opacity:1;stroke:none;stroke-opacity:1" /></g></g></g></svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -1,3 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.23 1H11.77L3.52002 9.25L3.35999 9.46997L1 13.59L2.41003 15L6.53003 12.64L6.75 12.48L15 4.22998V2.77002L13.23 1ZM2.41003 13.59L3.92004 10.59L5.37 12.04L2.41003 13.59ZM6.23999 11.53L4.46997 9.76001L12.47 1.76001L14.24 3.53003L6.23999 11.53Z" fill="#C5C5C5"/>
</svg>

Before

Width:  |  Height:  |  Size: 372 B

View File

@@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" fill="none">
<path d="M16.010 6.49c-3.885 0-7.167 0.906-9.328 2.813-0.063-0.12-0.109-0.219-0.188-0.339-0.224-0.365-0.438-0.776-1.104-1.188-0.411-0.26-0.87-0.438-1.349-0.516-0.208-0.021-0.422-0.021-0.63 0l0.135-0.016c-1.214 0-1.922 0.724-2.385 1.354-0.458 0.625-0.755 1.328-0.948 2.099-0.38 1.542-0.385 3.536 1.083 5.026 0.766 0.781 1.667 1.151 2.484 1.37 0.156 0.042 0.297 0.052 0.448 0.083 0.531 2.521 2.104 4.656 4.208 5.839v0.005c1.24 0.693 2.417 1.010 3.297 1.349 1.234 0.479 2.536 1 4.052 1.135l0.078 0.005h0.198c1.745 0 3.063-0.703 4.203-1.141 0.875-0.333 2.052-0.641 3.302-1.344 0.578-0.323 1.115-0.719 1.594-1.172 1.318-1.234 2.229-2.839 2.625-4.599 1.115-0.182 2.141-0.719 2.922-1.536 1.464-1.484 1.458-3.479 1.078-5.021-0.193-0.771-0.49-1.474-0.948-2.099-0.458-0.63-1.172-1.354-2.385-1.354l0.135 0.016c-0.208-0.021-0.422-0.021-0.63 0-0.479 0.078-0.938 0.255-1.344 0.516-0.667 0.411-0.88 0.823-1.104 1.182-0.073 0.12-0.12 0.219-0.188 0.333-2.156-1.901-5.432-2.802-9.313-2.802zM16.042 8.313c4.745 0 8.016 1.422 9.411 3.964 0.839-0.323 1.453-2.521 2.146-2.948 0.563-0.344 0.885-0.26 0.885-0.26 1.271 0 2.578 3.729 0.953 5.38-0.859 0.875-2.443 1.12-3.229 1.057-0.063 2.542-1.542 4.833-3.5 5.932-1 0.563-2.068 0.854-3.063 1.234-1.229 0.469-2.38 1.016-3.547 1.016h-0.125c-1.161-0.099-2.318-0.542-3.547-1.016-0.995-0.38-2.068-0.682-3.063-1.24-1.948-1.099-3.427-3.391-3.49-5.927-0.781 0.068-2.385-0.177-3.245-1.057-1.625-1.651-0.318-5.38 0.948-5.38 0 0 0.328-0.083 0.885 0.26 0.698 0.427 1.318 2.646 2.161 2.953 1.391-2.547 4.667-3.969 9.417-3.969zM10.875 11.422c-2.276-0.042-4.146 1.792-4.146 4.068 0 2.281 1.87 4.115 4.146 4.073 5.328-0.099 5.328-8.047 0-8.141zM21.208 11.422c-5.427 0-5.427 8.141 0 8.141s5.427-8.141 0-8.141zM11.453 13.708c2.349 0.063 2.349 3.552 0 3.615-1.182 0-2.042-1.115-1.75-2.255 0.318 0.771 1.469 0.547 1.464-0.292 0-0.406-0.318-0.745-0.729-0.76 0.302-0.203 0.656-0.313 1.016-0.307zM20.641 13.708c2.344 0.063 2.344 3.552 0 3.615-1.182 0-2.047-1.115-1.755-2.255 0.229 0.552 0.979 0.641 1.328 0.146 0.344-0.49 0.010-1.167-0.589-1.193 0.297-0.208 0.651-0.313 1.016-0.313zM15.359 19.906c-0.318 0.026-0.5 0.193-0.5 0.635 0 0.281 0.182 0.484 0.5 0.484 0.229 0 0.266-0.323 0.047-0.375-0.031-0.005-0.172-0.057-0.172-0.182 0-0.12 0-0.167 0.24-0.198 0.104-0.016 0.156-0.141 0.125-0.24s-0.125-0.135-0.24-0.125zM16.724 19.906c-0.115-0.005-0.208 0.026-0.24 0.125s0.021 0.224 0.125 0.24c0.24 0.031 0.24 0.078 0.24 0.198 0 0.125-0.141 0.177-0.172 0.182-0.219 0.052-0.182 0.375 0.042 0.375 0.323 0 0.51-0.203 0.51-0.484 0-0.443-0.188-0.609-0.505-0.635z" fill="#C5C5C5"/>
<line y2="24" x2="16" y1="26" x1="32" stroke-width="2" stroke="green" fill="none"/>
<line y2="16" x2="24" y1="32" x1="24" stroke-width="1" stroke="green" fill="none"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -1,3 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2 2H14L15 3V13L14 14H2L1 13V3L2 2ZM2 13H14V3H2V13ZM13 4H3V7H13V4ZM12 6H4V5H12V6ZM9 12H13V8H9V12ZM10 9H12V11H10V9ZM7 8H3V9H7V8ZM3 11H7V12H3V11Z" fill="#C5C5C5"/>
</svg>

Before

Width:  |  Height:  |  Size: 313 B

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" fill="none"
viewBox="0 0 432 432" style="enable-background:new 0 0 432 432;" xml:space="preserve">
<g>
<g>
<g>
<polygon points="234.24,9.067 183.893,59.413 284.587,59.413" fill="#C5C5C5"/>
<path d="m 259.24622,341.40906 v -32.34375 q 13.35937,6.32812 27.07031,9.66797 13.71094,3.33984 26.89453,3.33984 35.15625,0 53.61328,-23.55469 18.63282,-23.73047 21.26953,-71.89453 -10.19531,15.11719 -25.83984,23.20313 -15.64453,8.08593 -34.62891,8.08593 -39.375,0 -62.40234,-23.73046 -22.85156,-23.90625 -22.85156,-65.21485 0,-40.42969 23.90625,-64.86328 23.90625,-24.433594 63.63281,-24.433594 45.52734,0 69.43359,34.980474 24.08204,34.80468 24.08204,101.25 0,62.05078 -29.53125,99.14062 -29.35547,36.91406 -79.10157,36.91406 -13.35937,0 -27.07031,-2.63672 -13.71094,-2.63671 -28.47656,-7.91015 z m 70.66406,-111.26953 q 23.90625,0 37.79297,-16.34766 14.0625,-16.34766 14.0625,-44.82422 0,-28.30078 -14.0625,-44.64844 -13.88672,-16.52343 -37.79297,-16.52343 -23.90625,0 -37.96875,16.52343 -13.88672,16.34766 -13.88672,44.64844 0,28.47656 13.88672,44.82422 14.0625,16.34766 37.96875,16.34766 z" fill="#C5C5C5" />
<polygon points="234.24,422.933 283.947,373.227 184.533,373.227" fill="#C5C5C5"/>
<path d="M 35.300905,316.97546 H 93.308718 V 116.76062 L 30.203249,129.41687 V 97.07312 L 92.957155,84.41687 h 35.507815 v 232.55859 h 58.00781 v 29.88282 H 35.300905 Z" fill="#C5C5C5"/>
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -1,3 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10 3H12H13V4H12V13L11 14H4L3 13V4H2V3H5V2C5 1.73478 5.10531 1.48038 5.29285 1.29285C5.48038 1.10531 5.73478 1 6 1H9C9.26522 1 9.51962 1.10531 9.70715 1.29285C9.89469 1.48038 10 1.73478 10 2V3ZM9 2H6V3H9V2ZM4 13H11V4H4V13ZM6 5H5V12H6V5ZM7 5H8V12H7V5ZM9 5H10V12H9V5Z" fill="#C5C5C5"/>
</svg>

Before

Width:  |  Height:  |  Size: 435 B

View File

@@ -1,7 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M15.5 12.1952C15.5 12.9126 14.9137 13.4996 14.1957 13.4996H1.80435C1.08696 13.4996 0.5 12.9126 0.5 12.1952L0.5 9.80435C0.5 9.08696 1.08696 8.5 1.80435 8.5H14.1956C14.9137 8.5 15.5 9.08696 15.5 9.80435L15.5 12.1952Z" stroke="#959DA5" stroke-linecap="round" stroke-linejoin="round"/>
<path d="M2.45654 11.5H13.5435" stroke="#959DA5" stroke-linecap="round" stroke-linejoin="round"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.5 9.5C13.224 9.5 13 9.725 13 10C13 10.275 13.224 10.5 13.5 10.5C13.776 10.5 14 10.275 14 10C14 9.725 13.776 9.5 13.5 9.5" fill="#959DA5"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M11.5 9.5C11.224 9.5 11 9.725 11 10C11 10.275 11.224 10.5 11.5 10.5C11.776 10.5 12 10.275 12 10C12 9.725 11.776 9.5 11.5 9.5" fill="#959DA5"/>
<path d="M15.5 9.81464L13.8728 2.76261C13.6922 2.06804 12.9572 1.5 12.2391 1.5H3.76087C3.04348 1.5 2.30848 2.06804 2.12783 2.76261L0.5 9.8" stroke="#959DA5" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,16 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<circle cx="7.5" cy="7.5" r="7" stroke="#959DA5"/>
<mask id="mask0_394_2982" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="15" height="15">
<circle cx="7.5" cy="7.5" r="7.5" fill="#C4C4C4"/>
</mask>
<g mask="url(#mask0_394_2982)">
<path d="M14.5 7.5C14.5 9.42971 13.6822 11.1907 12.5493 12.4721C11.4035 13.7683 10.0054 14.5 8.90625 14.5C7.84644 14.5 6.81131 13.8113 6.01569 12.5383C5.22447 11.2724 4.71875 9.49235 4.71875 7.5C4.71875 5.50765 5.22447 3.72765 6.01569 2.4617C6.81131 1.1887 7.84644 0.5 8.90625 0.5C10.0054 0.5 11.4035 1.23172 12.5493 2.52786C13.6822 3.80934 14.5 5.57029 14.5 7.5Z" stroke="#959DA5"/>
</g>
<mask id="mask1_394_2982" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="1" y="0" width="16" height="15">
<circle cx="9.375" cy="7.5" r="7.5" fill="#C4C4C4"/>
</mask>
<g mask="url(#mask1_394_2982)">
<path d="M10.2812 7.5C10.2812 9.49235 9.77553 11.2724 8.98431 12.5383C8.18869 13.8113 7.15356 14.5 6.09375 14.5C4.99456 14.5 3.5965 13.7683 2.45067 12.4721C1.31781 11.1907 0.5 9.42971 0.5 7.5C0.5 5.57029 1.31781 3.80934 2.45067 2.52786C3.5965 1.23172 4.99456 0.5 6.09375 0.5C7.15356 0.5 8.18869 1.1887 8.98431 2.4617C9.77553 3.72765 10.2812 5.50765 10.2812 7.5Z" stroke="#959DA5"/>
</g>
<line y1="7.5" x2="15" y2="7.5" stroke="#959DA5"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -1,57 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="30px"
width="30px"
fill="#000000"
version="1.1"
x="0px"
y="0px"
viewBox="0 0 100 100"
style="enable-background:new 0 0 100 100;"
xml:space="preserve"
id="svg3895"
sodipodi:docname="check.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)"><metadata
id="metadata3901"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs3899" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1179"
inkscape:window-height="701"
id="namedview3897"
showgrid="false"
inkscape:zoom="7.8666667"
inkscape:cx="15"
inkscape:cy="15"
inkscape:window-x="0"
inkscape:window-y="28"
inkscape:window-maximized="0"
inkscape:current-layer="svg3895" /><g
transform="translate(-452.57627,-74.457627)"
id="g3893"
style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"><g
id="g3891"
style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"><g
id="g3889"
style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-opacity:1"><path
d="M 457.98136,131.82373 488.80508,163.49492 548.8661,92.416949 535.93729,81.60678 487.85763,144.41695 468.2678,120.58983 Z"
id="path3887"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccc"
style="fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-opacity:1" /></g></g></g></svg>

Before

Width:  |  Height:  |  Size: 2.2 KiB

View File

@@ -1,3 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M13.2302 1H11.7703L3.52026 9.25L3.36023 9.46997L1.00024 13.59L2.41028 15L6.53027 12.64L6.75024 12.48L15.0002 4.22998V2.77002L13.2302 1ZM2.41028 13.59L3.92029 10.59L5.37024 12.04L2.41028 13.59ZM6.24023 11.53L4.47021 9.76001L12.4702 1.76001L14.2402 3.53003L6.24023 11.53Z" fill="#424242"/>
</svg>

Before

Width:  |  Height:  |  Size: 399 B

View File

@@ -1,5 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" viewBox="0 0 32 32" fill="none">
<path d="M16.010 6.49c-3.885 0-7.167 0.906-9.328 2.813-0.063-0.12-0.109-0.219-0.188-0.339-0.224-0.365-0.438-0.776-1.104-1.188-0.411-0.26-0.87-0.438-1.349-0.516-0.208-0.021-0.422-0.021-0.63 0l0.135-0.016c-1.214 0-1.922 0.724-2.385 1.354-0.458 0.625-0.755 1.328-0.948 2.099-0.38 1.542-0.385 3.536 1.083 5.026 0.766 0.781 1.667 1.151 2.484 1.37 0.156 0.042 0.297 0.052 0.448 0.083 0.531 2.521 2.104 4.656 4.208 5.839v0.005c1.24 0.693 2.417 1.010 3.297 1.349 1.234 0.479 2.536 1 4.052 1.135l0.078 0.005h0.198c1.745 0 3.063-0.703 4.203-1.141 0.875-0.333 2.052-0.641 3.302-1.344 0.578-0.323 1.115-0.719 1.594-1.172 1.318-1.234 2.229-2.839 2.625-4.599 1.115-0.182 2.141-0.719 2.922-1.536 1.464-1.484 1.458-3.479 1.078-5.021-0.193-0.771-0.49-1.474-0.948-2.099-0.458-0.63-1.172-1.354-2.385-1.354l0.135 0.016c-0.208-0.021-0.422-0.021-0.63 0-0.479 0.078-0.938 0.255-1.344 0.516-0.667 0.411-0.88 0.823-1.104 1.182-0.073 0.12-0.12 0.219-0.188 0.333-2.156-1.901-5.432-2.802-9.313-2.802zM16.042 8.313c4.745 0 8.016 1.422 9.411 3.964 0.839-0.323 1.453-2.521 2.146-2.948 0.563-0.344 0.885-0.26 0.885-0.26 1.271 0 2.578 3.729 0.953 5.38-0.859 0.875-2.443 1.12-3.229 1.057-0.063 2.542-1.542 4.833-3.5 5.932-1 0.563-2.068 0.854-3.063 1.234-1.229 0.469-2.38 1.016-3.547 1.016h-0.125c-1.161-0.099-2.318-0.542-3.547-1.016-0.995-0.38-2.068-0.682-3.063-1.24-1.948-1.099-3.427-3.391-3.49-5.927-0.781 0.068-2.385-0.177-3.245-1.057-1.625-1.651-0.318-5.38 0.948-5.38 0 0 0.328-0.083 0.885 0.26 0.698 0.427 1.318 2.646 2.161 2.953 1.391-2.547 4.667-3.969 9.417-3.969zM10.875 11.422c-2.276-0.042-4.146 1.792-4.146 4.068 0 2.281 1.87 4.115 4.146 4.073 5.328-0.099 5.328-8.047 0-8.141zM21.208 11.422c-5.427 0-5.427 8.141 0 8.141s5.427-8.141 0-8.141zM11.453 13.708c2.349 0.063 2.349 3.552 0 3.615-1.182 0-2.042-1.115-1.75-2.255 0.318 0.771 1.469 0.547 1.464-0.292 0-0.406-0.318-0.745-0.729-0.76 0.302-0.203 0.656-0.313 1.016-0.307zM20.641 13.708c2.344 0.063 2.344 3.552 0 3.615-1.182 0-2.047-1.115-1.755-2.255 0.229 0.552 0.979 0.641 1.328 0.146 0.344-0.49 0.010-1.167-0.589-1.193 0.297-0.208 0.651-0.313 1.016-0.313zM15.359 19.906c-0.318 0.026-0.5 0.193-0.5 0.635 0 0.281 0.182 0.484 0.5 0.484 0.229 0 0.266-0.323 0.047-0.375-0.031-0.005-0.172-0.057-0.172-0.182 0-0.12 0-0.167 0.24-0.198 0.104-0.016 0.156-0.141 0.125-0.24s-0.125-0.135-0.24-0.125zM16.724 19.906c-0.115-0.005-0.208 0.026-0.24 0.125s0.021 0.224 0.125 0.24c0.24 0.031 0.24 0.078 0.24 0.198 0 0.125-0.141 0.177-0.172 0.182-0.219 0.052-0.182 0.375 0.042 0.375 0.323 0 0.51-0.203 0.51-0.484 0-0.443-0.188-0.609-0.505-0.635z" fill="#424242"/>
<line y2="24" x2="16" y1="26" x1="32" stroke-width="2" stroke="green" fill="none"/>
<line y2="16" x2="24" y1="32" x1="24" stroke-width="1" stroke="green" fill="none"/>
</svg>

Before

Width:  |  Height:  |  Size: 2.8 KiB

View File

@@ -1,3 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M2.00024 2H14.0002L15.0002 3V13L14.0002 14H2.00024L1.00024 13V3L2.00024 2ZM2.00024 13H14.0002V3H2.00024V13ZM13.0002 4H3.00024V7H13.0002V4ZM12.0002 6H4.00024V5H12.0002V6ZM9.00024 12H13.0002V8H9.00024V12ZM10.0002 9H12.0002V11H10.0002V9ZM7.00024 8H3.00024V9H7.00024V8ZM3.00024 11H7.00024V12H3.00024V11Z" fill="#424242"/>
</svg>

Before

Width:  |  Height:  |  Size: 469 B

View File

@@ -1,15 +0,0 @@
<?xml version="1.0" encoding="iso-8859-1"?>
<!-- Generator: Adobe Illustrator 19.0.0, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Capa_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 432 432" style="enable-background:new 0 0 432 432;" xml:space="preserve">
<g>
<g>
<g>
<polygon points="234.24,9.067 183.893,59.413 284.587,59.413" />
<path d="m 259.24622,341.40906 v -32.34375 q 13.35937,6.32812 27.07031,9.66797 13.71094,3.33984 26.89453,3.33984 35.15625,0 53.61328,-23.55469 18.63282,-23.73047 21.26953,-71.89453 -10.19531,15.11719 -25.83984,23.20313 -15.64453,8.08593 -34.62891,8.08593 -39.375,0 -62.40234,-23.73046 -22.85156,-23.90625 -22.85156,-65.21485 0,-40.42969 23.90625,-64.86328 23.90625,-24.433594 63.63281,-24.433594 45.52734,0 69.43359,34.980474 24.08204,34.80468 24.08204,101.25 0,62.05078 -29.53125,99.14062 -29.35547,36.91406 -79.10157,36.91406 -13.35937,0 -27.07031,-2.63672 -13.71094,-2.63671 -28.47656,-7.91015 z m 70.66406,-111.26953 q 23.90625,0 37.79297,-16.34766 14.0625,-16.34766 14.0625,-44.82422 0,-28.30078 -14.0625,-44.64844 -13.88672,-16.52343 -37.79297,-16.52343 -23.90625,0 -37.96875,16.52343 -13.88672,16.34766 -13.88672,44.64844 0,28.47656 13.88672,44.82422 14.0625,16.34766 37.96875,16.34766 z" />
<polygon points="234.24,422.933 283.947,373.227 184.533,373.227" />
<path d="M 35.300905,316.97546 H 93.308718 V 116.76062 L 30.203249,129.41687 V 97.07312 L 92.957155,84.41687 h 35.507815 v 232.55859 h 58.00781 v 29.88282 H 35.300905 Z" />
</g>
</g>
</g>
</svg>

Before

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -1,3 +0,0 @@
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M10.0002 3H12.0002H13.0002V4H12.0002V13L11.0002 14H4.00024L3.00024 13V4H2.00024V3H5.00024V2C5.00024 1.73478 5.10555 1.48038 5.29309 1.29285C5.48063 1.10531 5.73503 1 6.00024 1H9.00024C9.26546 1 9.51986 1.10531 9.7074 1.29285C9.89493 1.48038 10.0002 1.73478 10.0002 2V3ZM9.00024 2H6.00024V3H9.00024V2ZM4.00024 13H11.0002V4H4.00024V13ZM6.00024 5H5.00024V12H6.00024V5ZM7.00024 5H8.00024V12H7.00024V5ZM9.00024 5H10.0002V12H9.00024V5Z" fill="#424242"/>
</svg>

Before

Width:  |  Height:  |  Size: 599 B

View File

@@ -1,58 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
height="30px"
width="30px"
fill="#000000"
version="1.1"
x="0px"
y="0px"
viewBox="0 0 100 100"
style="enable-background:new 0 0 100 100;"
xml:space="preserve"
id="svg3895"
sodipodi:docname="red-x.svg"
inkscape:version="0.92.3 (2405546, 2018-03-11)"><metadata
id="metadata3901"><rdf:RDF><cc:Work
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
id="defs3899" /><sodipodi:namedview
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1"
objecttolerance="10"
gridtolerance="10"
guidetolerance="10"
inkscape:pageopacity="0"
inkscape:pageshadow="2"
inkscape:window-width="1179"
inkscape:window-height="701"
id="namedview3897"
showgrid="false"
inkscape:zoom="7.8666667"
inkscape:cx="-22.881356"
inkscape:cy="15"
inkscape:window-x="33"
inkscape:window-y="36"
inkscape:window-maximized="0"
inkscape:current-layer="svg3895" /><rect
style="opacity:1;vector-effect:none;fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:2.24023867;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
id="rect29"
width="15.499873"
height="88.381233"
x="-8.3491764"
y="27.119303"
transform="matrix(-0.70710678,0.70710678,0.70710678,0.70710678,0,0)" /><rect
style="fill:#ff0000;fill-opacity:1;stroke:none;stroke-width:2.24023867;stroke-opacity:1"
id="rect29-6"
width="15.499873"
height="88.381233"
x="63.559982"
y="-44.789856"
transform="rotate(45)" /></svg>

Before

Width:  |  Height:  |  Size: 2.1 KiB

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,7 @@
"description": "CodeQL for Visual Studio Code",
"author": "GitHub",
"private": true,
"version": "1.7.7",
"version": "1.8.1",
"publisher": "GitHub",
"license": "MIT",
"icon": "media/VS-marketplace-CodeQL-icon.png",
@@ -37,19 +37,13 @@
"onLanguage:ql",
"onLanguage:ql-summary",
"onView:codeQLDatabases",
"onView:codeQLDatabasesExperimental",
"onView:codeQLVariantAnalysisRepositories",
"onView:codeQLQueryHistory",
"onView:codeQLAstViewer",
"onView:codeQLEvalLogViewer",
"onView:test-explorer",
"onCommand:codeQL.checkForUpdatesToCLI",
"onCommand:codeQL.authenticateToGitHub",
"onCommand:codeQLDatabases.chooseDatabaseFolder",
"onCommand:codeQLDatabases.chooseDatabaseArchive",
"onCommand:codeQLDatabases.chooseDatabaseInternet",
"onCommand:codeQLDatabases.chooseDatabaseGithub",
"onCommand:codeQLDatabases.chooseDatabaseLgtm",
"onCommand:codeQL.setCurrentDatabase",
"onCommand:codeQL.viewAst",
"onCommand:codeQL.viewCfg",
"onCommand:codeQL.openReferencedFile",
@@ -58,16 +52,11 @@
"onCommand:codeQL.chooseDatabaseArchive",
"onCommand:codeQL.chooseDatabaseInternet",
"onCommand:codeQL.chooseDatabaseGithub",
"onCommand:codeQL.chooseDatabaseLgtm",
"onCommand:codeQLDatabases.chooseDatabase",
"onCommand:codeQLDatabases.setCurrentDatabase",
"onCommand:codeQLDatabasesExperimental.openConfigFile",
"onCommand:codeQLDatabasesExperimental.addNewList",
"onCommand:codeQLDatabasesExperimental.setSelectedItem",
"onCommand:codeQL.quickQuery",
"onCommand:codeQL.restartQueryServer",
"onWebviewPanel:resultsView",
"onWebviewPanel:codeQL.variantAnalysis",
"onWebviewPanel:codeQL.dataFlowPaths",
"onFileSystem:codeql-zip-archive"
],
"main": "./out/extension",
@@ -89,8 +78,8 @@
},
"jsonValidation": [
{
"fileMatch": "workspace-databases.json",
"url": "./workspace-databases-schema.json"
"fileMatch": "GitHub.vscode-codeql/databases.json",
"url": "./databases-schema.json"
}
],
"languages": [
@@ -236,6 +225,19 @@
"default": true,
"description": "Enable the 'Quick Evaluation' CodeLens."
},
"codeQL.runningQueries.useExtensionPacks": {
"type": "string",
"default": "none",
"enum": [
"none",
"all"
],
"enumDescriptions": [
"Do not use extension packs.",
"Use all extension packs found in the workspace."
],
"description": "Choose whether or not to run queries using extension packs. Requires CodeQL CLI v2.12.3 or later."
},
"codeQL.resultsDisplay.pageSize": {
"type": "integer",
"default": 200,
@@ -278,22 +280,6 @@
"scope": "application",
"description": "Specifies whether or not to write telemetry events to the extension log."
},
"codeQL.variantAnalysis.repositoryLists": {
"type": [
"object",
null
],
"patternProperties": {
".*": {
"type": "array",
"items": {
"type": "string"
}
}
},
"default": null,
"markdownDescription": "[For internal use only] Lists of GitHub repositories that you want to run variant analysis against. This should be a JSON object where each key is a user-specified name for this repository list, and the value is an array of GitHub repositories (of the form `<owner>/<repo>`)."
},
"codeQL.variantAnalysis.controllerRepo": {
"type": "string",
"default": "",
@@ -317,16 +303,28 @@
},
{
"command": "codeQL.runQuery",
"title": "CodeQL: Run Query"
"title": "CodeQL: Run Query on Selected Database"
},
{
"command": "codeQL.runQueryContextEditor",
"title": "CodeQL: Run Query on Selected Database"
},
{
"command": "codeQL.runQueryOnMultipleDatabases",
"title": "CodeQL: Run Query on Multiple Databases"
},
{
"command": "codeQL.runQueryOnMultipleDatabasesContextEditor",
"title": "CodeQL: Run Query on Multiple Databases"
},
{
"command": "codeQL.runVariantAnalysis",
"title": "CodeQL: Run Variant Analysis"
},
{
"command": "codeQL.runVariantAnalysisContextEditor",
"title": "CodeQL: Run Variant Analysis"
},
{
"command": "codeQL.exportSelectedVariantAnalysisResults",
"title": "CodeQL: Export Variant Analysis Results"
@@ -339,10 +337,22 @@
"command": "codeQL.quickEval",
"title": "CodeQL: Quick Evaluation"
},
{
"command": "codeQL.quickEvalContextEditor",
"title": "CodeQL: Quick Evaluation"
},
{
"command": "codeQL.openReferencedFile",
"title": "CodeQL: Open Referenced File"
},
{
"command": "codeQL.openReferencedFileContextEditor",
"title": "CodeQL: Open Referenced File"
},
{
"command": "codeQL.openReferencedFileContextExplorer",
"title": "CodeQL: Open Referenced File"
},
{
"command": "codeQL.previewQueryHelp",
"title": "CodeQL: Preview Query Help"
@@ -360,19 +370,39 @@
"title": "CodeQL: Copy Version Information"
},
{
"command": "codeQLDatabasesExperimental.openConfigFile",
"title": "Open Database Configuration File",
"icon": "$(edit)"
"command": "codeQLVariantAnalysisRepositories.openConfigFile",
"title": "Open database configuration file",
"icon": "$(json)"
},
{
"command": "codeQLDatabasesExperimental.addNewList",
"command": "codeQLVariantAnalysisRepositories.addNewDatabase",
"title": "Add new database",
"icon": "$(add)"
},
{
"command": "codeQLVariantAnalysisRepositories.addNewList",
"title": "Add new list",
"icon": "$(new-folder)"
},
{
"command": "codeQLDatabasesExperimental.setSelectedItem",
"title": "Select Item",
"icon": "$(circle-small-filled)"
"command": "codeQLVariantAnalysisRepositories.setSelectedItem",
"title": "Select"
},
{
"command": "codeQLVariantAnalysisRepositories.setSelectedItemContextMenu",
"title": "Select"
},
{
"command": "codeQLVariantAnalysisRepositories.renameItemContextMenu",
"title": "Rename"
},
{
"command": "codeQLVariantAnalysisRepositories.openOnGitHubContextMenu",
"title": "Open on GitHub"
},
{
"command": "codeQLVariantAnalysisRepositories.removeItemContextMenu",
"title": "Delete"
},
{
"command": "codeQLDatabases.chooseDatabaseFolder",
@@ -410,14 +440,6 @@
"dark": "media/dark/github.svg"
}
},
{
"command": "codeQLDatabases.chooseDatabaseLgtm",
"title": "Download from LGTM",
"icon": {
"light": "media/light/lgtm-plus.svg",
"dark": "media/dark/lgtm-plus.svg"
}
},
{
"command": "codeQL.setCurrentDatabase",
"title": "CodeQL: Set Current Database"
@@ -426,10 +448,26 @@
"command": "codeQL.viewAst",
"title": "CodeQL: View AST"
},
{
"command": "codeQL.viewAstContextExplorer",
"title": "CodeQL: View AST"
},
{
"command": "codeQL.viewAstContextEditor",
"title": "CodeQL: View AST"
},
{
"command": "codeQL.viewCfg",
"title": "CodeQL: View CFG"
},
{
"command": "codeQL.viewCfgContextExplorer",
"title": "CodeQL: View CFG"
},
{
"command": "codeQL.viewCfgContextEditor",
"title": "CodeQL: View CFG"
},
{
"command": "codeQL.upgradeCurrentDatabase",
"title": "CodeQL: Upgrade Current Database"
@@ -448,7 +486,7 @@
},
{
"command": "codeQLDatabases.setCurrentDatabase",
"title": "Set Current Database"
"title": "Select"
},
{
"command": "codeQLDatabases.removeDatabase",
@@ -486,10 +524,6 @@
"command": "codeQL.chooseDatabaseGithub",
"title": "CodeQL: Download Database from GitHub"
},
{
"command": "codeQL.chooseDatabaseLgtm",
"title": "CodeQL: Download Database from LGTM"
},
{
"command": "codeQLDatabases.sortByName",
"title": "Sort by Name",
@@ -511,60 +545,54 @@
"title": "CodeQL: Check for CLI Updates"
},
{
"command": "codeQLQueryHistory.openQuery",
"title": "Open the Query that Produced these Results",
"icon": {
"light": "media/light/edit.svg",
"dark": "media/dark/edit.svg"
}
"command": "codeQLQueryHistory.openQueryTitleMenu",
"title": "View Query",
"icon": "$(edit)"
},
{
"command": "codeQLQueryHistory.openQueryContextMenu",
"title": "View Query",
"icon": "$(edit)"
},
{
"command": "codeQLQueryHistory.itemClicked",
"title": "Open Query Results",
"icon": {
"light": "media/light/preview.svg",
"dark": "media/dark/preview.svg"
}
"icon": "$(preview)"
},
{
"command": "codeQLQueryHistory.removeHistoryItem",
"title": "Remove History Item(s)",
"icon": {
"light": "media/light/trash.svg",
"dark": "media/dark/trash.svg"
}
"command": "codeQLQueryHistory.removeHistoryItemTitleMenu",
"title": "Delete",
"icon": "$(trash)"
},
{
"command": "codeQLQueryHistory.removeHistoryItemContextMenu",
"title": "Delete",
"icon": "$(trash)"
},
{
"command": "codeQLQueryHistory.removeHistoryItemContextInline",
"title": "Delete",
"icon": "$(trash)"
},
{
"command": "codeQLQueryHistory.sortByName",
"title": "Sort by Name",
"icon": {
"light": "media/light/sort-alpha.svg",
"dark": "media/dark/sort-alpha.svg"
}
"title": "Sort by Name"
},
{
"command": "codeQLQueryHistory.sortByDate",
"title": "Sort by Query Date",
"icon": {
"light": "media/light/sort-date.svg",
"dark": "media/dark/sort-date.svg"
}
"title": "Sort by Date"
},
{
"command": "codeQLQueryHistory.sortByCount",
"title": "Sort by Results Count",
"icon": {
"light": "media/light/sort-num.svg",
"dark": "media/dark/sort-num.svg"
}
"title": "Sort by Results Count"
},
{
"command": "codeQLQueryHistory.showQueryLog",
"title": "Show Query Log"
"title": "View Query Log"
},
{
"command": "codeQLQueryHistory.openQueryDirectory",
"title": "Open Query Directory"
"title": "Open Results Directory"
},
{
"command": "codeQLQueryHistory.showEvalLog",
@@ -584,7 +612,7 @@
},
{
"command": "codeQLQueryHistory.showQueryText",
"title": "Show Query Text"
"title": "View Query Text"
},
{
"command": "codeQLQueryHistory.exportResults",
@@ -607,8 +635,8 @@
"title": "View DIL"
},
{
"command": "codeQLQueryHistory.setLabel",
"title": "Set Label"
"command": "codeQLQueryHistory.renameItem",
"title": "Rename"
},
{
"command": "codeQLQueryHistory.compareWith",
@@ -616,7 +644,7 @@
},
{
"command": "codeQLQueryHistory.openOnGithub",
"title": "Open Variant Analysis on GitHub"
"title": "View Logs"
},
{
"command": "codeQLQueryHistory.copyRepoList",
@@ -729,12 +757,7 @@
"group": "navigation"
},
{
"command": "codeQLDatabases.chooseDatabaseLgtm",
"when": "config.codeQL.canary && view == codeQLDatabases",
"group": "navigation"
},
{
"command": "codeQLQueryHistory.openQuery",
"command": "codeQLQueryHistory.openQueryTitleMenu",
"when": "view == codeQLQueryHistory",
"group": "navigation"
},
@@ -744,24 +767,24 @@
"group": "navigation"
},
{
"command": "codeQLQueryHistory.removeHistoryItem",
"command": "codeQLQueryHistory.removeHistoryItemTitleMenu",
"when": "view == codeQLQueryHistory",
"group": "navigation"
},
{
"command": "codeQLQueryHistory.sortByName",
"when": "view == codeQLQueryHistory",
"group": "navigation"
"group": "1_queryHistory@0"
},
{
"command": "codeQLQueryHistory.sortByDate",
"when": "view == codeQLQueryHistory",
"group": "navigation"
"group": "1_queryHistory@1"
},
{
"command": "codeQLQueryHistory.sortByCount",
"when": "view == codeQLQueryHistory",
"group": "navigation"
"group": "1_queryHistory@2"
},
{
"command": "codeQLAstViewer.clear",
@@ -774,17 +797,42 @@
"group": "navigation"
},
{
"command": "codeQLDatabasesExperimental.openConfigFile",
"when": "view == codeQLDatabasesExperimental",
"command": "codeQLVariantAnalysisRepositories.openConfigFile",
"when": "view == codeQLVariantAnalysisRepositories",
"group": "navigation"
},
{
"command": "codeQLDatabasesExperimental.addNewList",
"when": "view == codeQLDatabasesExperimental",
"command": "codeQLVariantAnalysisRepositories.addNewDatabase",
"when": "view == codeQLVariantAnalysisRepositories && codeQLVariantAnalysisRepositories.configError == false",
"group": "navigation"
},
{
"command": "codeQLVariantAnalysisRepositories.addNewList",
"when": "view == codeQLVariantAnalysisRepositories && codeQLVariantAnalysisRepositories.configError == false",
"group": "navigation"
}
],
"view/item/context": [
{
"command": "codeQLVariantAnalysisRepositories.removeItemContextMenu",
"when": "view == codeQLVariantAnalysisRepositories && viewItem =~ /canBeRemoved/",
"group": "2_qlContextMenu@3"
},
{
"command": "codeQLVariantAnalysisRepositories.setSelectedItemContextMenu",
"when": "view == codeQLVariantAnalysisRepositories && viewItem =~ /canBeSelected/",
"group": "1_qlContextMenu@1"
},
{
"command": "codeQLVariantAnalysisRepositories.renameItemContextMenu",
"when": "view == codeQLVariantAnalysisRepositories && viewItem =~ /canBeRenamed/",
"group": "2_qlContextMenu@2"
},
{
"command": "codeQLVariantAnalysisRepositories.openOnGitHubContextMenu",
"when": "view == codeQLVariantAnalysisRepositories && viewItem =~ /canBeOpenedOnGitHub/",
"group": "2_qlContextMenu@1"
},
{
"command": "codeQLDatabases.setCurrentDatabase",
"group": "inline",
@@ -811,63 +859,68 @@
"when": "view == codeQLDatabases"
},
{
"command": "codeQLDatabasesExperimental.setSelectedItem",
"when": "view == codeQLDatabasesExperimental && viewItem == selectableDbItem",
"command": "codeQLVariantAnalysisRepositories.setSelectedItem",
"when": "view == codeQLVariantAnalysisRepositories && viewItem =~ /canBeSelected/",
"group": "inline"
},
{
"command": "codeQLQueryHistory.openQuery",
"group": "9_qlCommands",
"command": "codeQLQueryHistory.openQueryContextMenu",
"group": "2_queryHistory@0",
"when": "view == codeQLQueryHistory"
},
{
"command": "codeQLQueryHistory.removeHistoryItem",
"group": "9_qlCommands",
"when": "viewItem == interpretedResultsItem || viewItem == rawResultsItem || viewItem == remoteResultsItem || viewItem == cancelledResultsItem || viewItem == cancelledRemoteResultsItem"
"command": "codeQLQueryHistory.removeHistoryItemContextMenu",
"group": "7_queryHistory@0",
"when": "viewItem == interpretedResultsItem || viewItem == rawResultsItem || viewItem == remoteResultsItem || viewItem == cancelledRemoteResultsItemWithoutLogs || viewItem == cancelledResultsItem || viewItem == cancelledRemoteResultsItem"
},
{
"command": "codeQLQueryHistory.setLabel",
"group": "9_qlCommands",
"command": "codeQLQueryHistory.removeHistoryItemContextInline",
"group": "inline",
"when": "viewItem == interpretedResultsItem || viewItem == rawResultsItem || viewItem == remoteResultsItem || viewItem == cancelledRemoteResultsItemWithoutLogs || viewItem == cancelledResultsItem || viewItem == cancelledRemoteResultsItem"
},
{
"command": "codeQLQueryHistory.renameItem",
"group": "6_queryHistory@0",
"when": "view == codeQLQueryHistory"
},
{
"command": "codeQLQueryHistory.compareWith",
"group": "9_qlCommands",
"group": "3_queryHistory@0",
"when": "viewItem == rawResultsItem || viewItem == interpretedResultsItem"
},
{
"command": "codeQLQueryHistory.showQueryLog",
"group": "9_qlCommands",
"group": "4_queryHistory@4",
"when": "viewItem == rawResultsItem || viewItem == interpretedResultsItem"
},
{
"command": "codeQLQueryHistory.openQueryDirectory",
"group": "9_qlCommands",
"group": "2_queryHistory@4",
"when": "view == codeQLQueryHistory && !hasRemoteServer"
},
{
"command": "codeQLQueryHistory.showEvalLog",
"group": "9_qlCommands",
"group": "4_queryHistory@1",
"when": "codeql.supportsEvalLog && viewItem == rawResultsItem || codeql.supportsEvalLog && viewItem == interpretedResultsItem || codeql.supportsEvalLog && viewItem == cancelledResultsItem"
},
{
"command": "codeQLQueryHistory.showEvalLogSummary",
"group": "9_qlCommands",
"group": "4_queryHistory@2",
"when": "codeql.supportsEvalLog && viewItem == rawResultsItem || codeql.supportsEvalLog && viewItem == interpretedResultsItem || codeql.supportsEvalLog && viewItem == cancelledResultsItem"
},
{
"command": "codeQLQueryHistory.showEvalLogViewer",
"group": "9_qlCommands",
"group": "4_queryHistory@3",
"when": "config.codeQL.canary && codeql.supportsEvalLog && viewItem == rawResultsItem || config.codeQL.canary && codeql.supportsEvalLog && viewItem == interpretedResultsItem || config.codeQL.canary && codeql.supportsEvalLog && viewItem == cancelledResultsItem"
},
{
"command": "codeQLQueryHistory.showQueryText",
"group": "9_qlCommands",
"group": "2_queryHistory@2",
"when": "view == codeQLQueryHistory"
},
{
"command": "codeQLQueryHistory.exportResults",
"group": "9_qlCommands",
"group": "1_queryHistory@0",
"when": "view == codeQLQueryHistory && viewItem == remoteResultsItem"
},
{
@@ -877,17 +930,17 @@
},
{
"command": "codeQLQueryHistory.viewCsvAlerts",
"group": "9_qlCommands",
"group": "5_queryHistory@0",
"when": "viewItem == interpretedResultsItem"
},
{
"command": "codeQLQueryHistory.viewSarifAlerts",
"group": "9_qlCommands",
"group": "5_queryHistory@1",
"when": "viewItem == interpretedResultsItem"
},
{
"command": "codeQLQueryHistory.viewDil",
"group": "9_qlCommands",
"group": "5_queryHistory@2",
"when": "viewItem == rawResultsItem || viewItem == interpretedResultsItem"
},
{
@@ -897,12 +950,12 @@
},
{
"command": "codeQLQueryHistory.openOnGithub",
"group": "9_qlCommands",
"group": "2_queryHistory@3",
"when": "viewItem == remoteResultsItem || viewItem == inProgressRemoteResultsItem || viewItem == cancelledRemoteResultsItem"
},
{
"command": "codeQLQueryHistory.copyRepoList",
"group": "9_qlCommands",
"group": "1_queryHistory@1",
"when": "viewItem == remoteResultsItem"
},
{
@@ -923,12 +976,12 @@
"when": "resourceScheme == codeql-zip-archive || explorerResourceIsFolder || resourceExtname == .zip"
},
{
"command": "codeQL.viewAst",
"command": "codeQL.viewAstContextExplorer",
"group": "9_qlCommands",
"when": "resourceScheme == codeql-zip-archive && !explorerResourceIsFolder && !listMultiSelection"
},
{
"command": "codeQL.viewCfg",
"command": "codeQL.viewCfgContextExplorer",
"group": "9_qlCommands",
"when": "resourceScheme == codeql-zip-archive && config.codeQL.canary"
},
@@ -938,7 +991,7 @@
"when": "resourceScheme != codeql-zip-archive"
},
{
"command": "codeQL.openReferencedFile",
"command": "codeQL.openReferencedFileContextExplorer",
"group": "9_qlCommands",
"when": "resourceExtname == .qlref"
},
@@ -957,17 +1010,25 @@
"command": "codeQL.runQuery",
"when": "resourceLangId == ql && resourceExtname == .ql"
},
{
"command": "codeQL.runQueryContextEditor",
"when": "false"
},
{
"command": "codeQL.runQueryOnMultipleDatabases",
"when": "resourceLangId == ql && resourceExtname == .ql"
},
{
"command": "codeQL.runVariantAnalysis",
"when": "config.codeQL.canary && editorLangId == ql && resourceExtname == .ql"
"command": "codeQL.runQueryOnMultipleDatabasesContextEditor",
"when": "false"
},
{
"command": "codeQL.exportSelectedVariantAnalysisResults",
"when": "config.codeQL.canary"
"command": "codeQL.runVariantAnalysis",
"when": "editorLangId == ql && resourceExtname == .ql"
},
{
"command": "codeQL.runVariantAnalysisContextEditor",
"when": "false"
},
{
"command": "codeQL.runQueries",
@@ -977,10 +1038,22 @@
"command": "codeQL.quickEval",
"when": "editorLangId == ql"
},
{
"command": "codeQL.quickEvalContextEditor",
"when": "false"
},
{
"command": "codeQL.openReferencedFile",
"when": "resourceExtname == .qlref"
},
{
"command": "codeQL.openReferencedFileContextEditor",
"when": "false"
},
{
"command": "codeQL.openReferencedFileContextExplorer",
"when": "false"
},
{
"command": "codeQL.previewQueryHelp",
"when": "resourceExtname == .qhelp && isWorkspaceTrusted"
@@ -993,24 +1066,56 @@
"command": "codeQL.viewAst",
"when": "resourceScheme == codeql-zip-archive"
},
{
"command": "codeQL.viewAstContextEditor",
"when": "false"
},
{
"command": "codeQL.viewAstContextExplorer",
"when": "false"
},
{
"command": "codeQL.viewCfg",
"when": "resourceScheme == codeql-zip-archive && config.codeQL.canary"
},
{
"command": "codeQL.chooseDatabaseLgtm",
"when": "config.codeQL.canary"
},
{
"command": "codeQLDatabasesExperimental.openConfigFile",
"command": "codeQL.viewCfgContextExplorer",
"when": "false"
},
{
"command": "codeQLDatabasesExperimental.addNewList",
"command": "codeQL.viewCfgContextEditor",
"when": "false"
},
{
"command": "codeQLDatabasesExperimental.setSelectedItem",
"command": "codeQLVariantAnalysisRepositories.openConfigFile",
"when": "false"
},
{
"command": "codeQLVariantAnalysisRepositories.addNewDatabase",
"when": "false"
},
{
"command": "codeQLVariantAnalysisRepositories.addNewList",
"when": "false"
},
{
"command": "codeQLVariantAnalysisRepositories.setSelectedItem",
"when": "false"
},
{
"command": "codeQLVariantAnalysisRepositories.setSelectedItemContextMenu",
"when": "false"
},
{
"command": "codeQLVariantAnalysisRepositories.renameItemContextMenu",
"when": "false"
},
{
"command": "codeQLVariantAnalysisRepositories.openOnGitHubContextMenu",
"when": "false"
},
{
"command": "codeQLVariantAnalysisRepositories.removeItemContextMenu",
"when": "false"
},
{
@@ -1061,20 +1166,28 @@
"command": "codeQLDatabases.chooseDatabaseGithub",
"when": "false"
},
{
"command": "codeQLDatabases.chooseDatabaseLgtm",
"when": "false"
},
{
"command": "codeQLDatabases.upgradeDatabase",
"when": "false"
},
{
"command": "codeQLQueryHistory.openQuery",
"command": "codeQLQueryHistory.openQueryTitleMenu",
"when": "false"
},
{
"command": "codeQLQueryHistory.removeHistoryItem",
"command": "codeQLQueryHistory.openQueryContextMenu",
"when": "false"
},
{
"command": "codeQLQueryHistory.removeHistoryItemTitleMenu",
"when": "false"
},
{
"command": "codeQLQueryHistory.removeHistoryItemContextMenu",
"when": "false"
},
{
"command": "codeQLQueryHistory.removeHistoryItemContextInline",
"when": "false"
},
{
@@ -1138,7 +1251,7 @@
"when": "false"
},
{
"command": "codeQLQueryHistory.setLabel",
"command": "codeQLQueryHistory.renameItem",
"when": "false"
},
{
@@ -1200,31 +1313,31 @@
],
"editor/context": [
{
"command": "codeQL.runQuery",
"command": "codeQL.runQueryContextEditor",
"when": "editorLangId == ql && resourceExtname == .ql"
},
{
"command": "codeQL.runQueryOnMultipleDatabases",
"command": "codeQL.runQueryOnMultipleDatabasesContextEditor",
"when": "editorLangId == ql && resourceExtname == .ql"
},
{
"command": "codeQL.runVariantAnalysis",
"when": "config.codeQL.canary && editorLangId == ql && resourceExtname == .ql"
"command": "codeQL.runVariantAnalysisContextEditor",
"when": "editorLangId == ql && resourceExtname == .ql"
},
{
"command": "codeQL.viewAst",
"command": "codeQL.viewAstContextEditor",
"when": "resourceScheme == codeql-zip-archive"
},
{
"command": "codeQL.viewCfg",
"command": "codeQL.viewCfgContextEditor",
"when": "resourceScheme == codeql-zip-archive && config.codeQL.canary"
},
{
"command": "codeQL.quickEval",
"command": "codeQL.quickEvalContextEditor",
"when": "editorLangId == ql"
},
{
"command": "codeQL.openReferencedFile",
"command": "codeQL.openReferencedFileContextEditor",
"when": "resourceExtname == .qlref"
},
{
@@ -1253,9 +1366,8 @@
"name": "Databases"
},
{
"id": "codeQLDatabasesExperimental",
"name": "Databases",
"when": "config.codeQL.canary && config.codeQL.newQueryRunExperience"
"id": "codeQLVariantAnalysisRepositories",
"name": "Variant Analysis Repositories"
},
{
"id": "codeQLQueryHistory",
@@ -1279,7 +1391,7 @@
},
{
"view": "codeQLQueryHistory",
"contents": "Run the 'CodeQL: Run Query' command on a QL query.\n[Run Query](command:codeQL.runQuery)"
"contents": "You have no query history items at the moment.\n\nSelect a database to run a CodeQL query and get your first results."
},
{
"view": "codeQLDatabases",
@@ -1288,37 +1400,39 @@
{
"view": "codeQLEvalLogViewer",
"contents": "Run the 'Show Evaluator Log (UI)' command on a CodeQL query run in the Query History view."
},
{
"view": "codeQLVariantAnalysisRepositories",
"contents": "Set up a controller repository to start using variant analysis. [Learn more](https://codeql.github.com/docs/codeql-for-visual-studio-code/running-codeql-queries-at-scale-with-mrva#controller-repository) about controller repositories. \n[Set up controller repository](command:codeQLVariantAnalysisRepositories.setupControllerRepository)",
"when": "!config.codeQL.variantAnalysis.controllerRepo"
}
]
},
"scripts": {
"build": "gulp",
"watch": "npm-run-all -p watch:*",
"watch:extension": "tsc --watch",
"watch:webpack": "gulp watchView",
"watch:files": "gulp watchTestData",
"test": "npm-run-all -p test:*",
"test:unit": "cross-env TZ=UTC LANG=en-US jest --projects test",
"watch": "gulp watch",
"test": "npm-run-all test:*",
"test:unit": "cross-env TZ=UTC LANG=en-US jest --projects test/unit-tests",
"test:view": "jest --projects src/view",
"integration": "npm-run-all integration:*",
"integration:no-workspace": "jest --projects src/vscode-tests/no-workspace",
"integration:minimal-workspace": "jest --projects src/vscode-tests/minimal-workspace",
"cli-integration": "jest --projects src/vscode-tests/cli-integration",
"test:vscode-integration": "npm-run-all test:vscode-integration:*",
"test:vscode-integration:activated-extension": "jest --projects test/vscode-tests/activated-extension",
"test:vscode-integration:no-workspace": "jest --projects test/vscode-tests/no-workspace",
"test:vscode-integration:minimal-workspace": "jest --projects test/vscode-tests/minimal-workspace",
"test:cli-integration": "jest --projects test/vscode-tests/cli-integration",
"update-vscode": "node ./node_modules/vscode/bin/install",
"format": "prettier --write **/*.{ts,tsx} && eslint . --ext .ts,.tsx --fix",
"lint": "eslint . --ext .ts,.tsx --max-warnings=0",
"lint": "eslint . --ext .js,.ts,.tsx --max-warnings=0",
"format-staged": "lint-staged",
"storybook": "start-storybook -p 6006",
"build-storybook": "build-storybook",
"lint:scenarios": "ts-node scripts/lint-scenarios.ts",
"check-types": "find . -type f -name \"tsconfig.json\" -not -path \"./node_modules/*\" | sed -r 's|/[^/]+$||' | sort | uniq | xargs -I {} sh -c \"echo Checking types in {} && cd {} && npx tsc --noEmit\"",
"postinstall": "patch-package"
"postinstall": "patch-package",
"prepare": "cd ../.. && husky install"
},
"dependencies": {
"@octokit/plugin-retry": "^3.0.9",
"@octokit/rest": "^19.0.4",
"@primer/octicons-react": "^17.6.0",
"@primer/react": "^35.0.0",
"@vscode/codicons": "^0.0.31",
"@vscode/webview-ui-toolkit": "^1.0.1",
"ajv": "^8.11.0",
@@ -1326,13 +1440,13 @@
"chokidar": "^3.5.3",
"classnames": "~2.2.6",
"d3": "^7.6.1",
"d3-graphviz": "^2.6.1",
"d3-graphviz": "^5.0.2",
"fs-extra": "^10.0.1",
"glob-promise": "^4.2.2",
"glob-promise": "^6.0.2",
"immutable": "^4.0.0",
"js-yaml": "^4.1.0",
"minimist": "~1.2.6",
"msw": "^0.47.4",
"msw": "^0.49.0",
"nanoid": "^3.2.0",
"node-fetch": "~2.6.7",
"p-queue": "^6.0.0",
@@ -1396,6 +1510,7 @@
"@types/semver": "~7.2.0",
"@types/stream-chain": "~2.0.1",
"@types/stream-json": "~1.7.1",
"@types/styled-components": "^5.1.11",
"@types/tar-stream": "^2.2.2",
"@types/through2": "^2.0.36",
"@types/tmp": "^0.1.0",
@@ -1410,12 +1525,13 @@
"@vscode/vsce": "^2.15.0",
"ansi-colors": "^4.1.1",
"applicationinsights": "^2.3.5",
"babel-loader": "^8.2.5",
"cross-env": "^7.0.3",
"css-loader": "~3.1.0",
"del": "^6.0.0",
"esbuild": "^0.15.15",
"eslint": "^8.23.1",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-etc": "^2.0.2",
"eslint-plugin-github": "^4.4.1",
"eslint-plugin-jest-dom": "^4.0.2",
"eslint-plugin-prettier": "^4.2.1",
@@ -1425,19 +1541,20 @@
"file-loader": "^6.2.0",
"glob": "^7.1.4",
"gulp": "^4.0.2",
"gulp-esbuild": "^0.10.5",
"gulp-replace": "^1.1.3",
"gulp-sourcemaps": "^3.0.0",
"gulp-typescript": "^5.0.1",
"husky": "~4.3.8",
"husky": "^8.0.0",
"jest": "^29.0.3",
"jest-environment-jsdom": "^29.0.3",
"jest-runner-vscode": "^3.0.1",
"lint-staged": "~10.2.2",
"lint-staged": "~13.2.0",
"mini-css-extract-plugin": "^2.6.1",
"npm-run-all": "^4.1.5",
"patch-package": "^6.5.0",
"prettier": "^2.7.1",
"tar-stream": "^2.2.0",
"tar-stream": "^3.0.0",
"through2": "^4.0.2",
"ts-jest": "^29.0.1",
"ts-json-schema-generator": "^1.1.2",
@@ -1445,14 +1562,8 @@
"ts-node": "^10.7.0",
"ts-protoc-gen": "^0.9.0",
"typescript": "^4.5.5",
"webpack": "^5.62.2",
"webpack-cli": "^4.6.0"
},
"husky": {
"hooks": {
"pre-commit": "npm run format-staged",
"pre-push": "npm run lint && scripts/forbid-test-only"
}
"webpack": "^5.76.0",
"webpack-cli": "^5.0.1"
},
"lint-staged": {
"./**/*.{json,css,scss}": [

View File

@@ -20,8 +20,8 @@ import { throttling } from "@octokit/plugin-throttling";
import { getFiles } from "./util/files";
import type { GitHubApiRequest } from "../src/mocks/gh-api-request";
import { isGetVariantAnalysisRequest } from "../src/mocks/gh-api-request";
import { VariantAnalysis } from "../src/remote-queries/gh-api/variant-analysis";
import { RepositoryWithMetadata } from "../src/remote-queries/gh-api/repository";
import { VariantAnalysis } from "../src/variant-analysis/gh-api/variant-analysis";
import { RepositoryWithMetadata } from "../src/variant-analysis/gh-api/repository";
const extensionDirectory = resolve(__dirname, "..");
const scenariosDirectory = resolve(extensionDirectory, "src/mocks/scenarios");
@@ -136,7 +136,7 @@ async function addFieldsToScenarios() {
}
}
addFieldsToScenarios().catch((e) => {
addFieldsToScenarios().catch((e: unknown) => {
console.error(e);
process.exit(2);
});

View File

@@ -72,7 +72,7 @@ async function fixScenarioFiles() {
}
}
fixScenarioFiles().catch((e) => {
fixScenarioFiles().catch((e: unknown) => {
console.error(e);
process.exit(2);
});

View File

@@ -28,7 +28,7 @@ async function lintScenarios() {
throw new Error(`Invalid schema: ${ajv.errorsText()}`);
}
const validate = await ajv.compile(schema);
const validate = ajv.compile(schema);
let invalidFiles = 0;
@@ -66,7 +66,7 @@ async function lintScenarios() {
}
}
lintScenarios().catch((e) => {
lintScenarios().catch((e: unknown) => {
console.error(e);
process.exit(2);
});

View File

@@ -0,0 +1,241 @@
/**
* This scripts helps finding the original source file and line number for a
* given file and line number in the compiled extension. It currently only
* works with released extensions.
*
* Usage: npx ts-node scripts/source-map.ts <version-number> <filename>:<line>:<column>
* For example: npx ts-node scripts/source-map.ts v1.7.8 "/Users/user/.vscode/extensions/github.vscode-codeql-1.7.8/out/extension.js:131164:13"
*
* Alternative usage: npx ts-node scripts/source-map.ts <version-number> <multi-line-stacktrace>
* For example: npx ts-node scripts/source-map.ts v1.7.8 'Error: Failed to find CodeQL distribution.
* at CodeQLCliServer.getCodeQlPath (/Users/user/.vscode/extensions/github.vscode-codeql-1.7.8/out/extension.js:131164:13)
* at CodeQLCliServer.launchProcess (/Users/user/.vscode/extensions/github.vscode-codeql-1.7.8/out/extension.js:131169:24)
* at CodeQLCliServer.runCodeQlCliInternal (/Users/user/.vscode/extensions/github.vscode-codeql-1.7.8/out/extension.js:131194:24)
* at CodeQLCliServer.runJsonCodeQlCliCommand (/Users/user/.vscode/extensions/github.vscode-codeql-1.7.8/out/extension.js:131330:20)
* at CodeQLCliServer.resolveRam (/Users/user/.vscode/extensions/github.vscode-codeql-1.7.8/out/extension.js:131455:12)
* at QueryServerClient2.startQueryServerImpl (/Users/user/.vscode/extensions/github.vscode-codeql-1.7.8/out/extension.js:138618:21)'
*/
import { spawnSync } from "child_process";
import { basename, resolve } from "path";
import { pathExists, readJSON } from "fs-extra";
import { RawSourceMap, SourceMapConsumer } from "source-map";
import { Open } from "unzipper";
if (process.argv.length !== 4) {
console.error(
"Expected 2 arguments - the version number and the filename:line number",
);
}
const stackLineRegex =
/at (?<name>.*)? \((?<file>.*):(?<line>\d+):(?<column>\d+)\)/gm;
const versionNumber = process.argv[2].startsWith("v")
? process.argv[2]
: `v${process.argv[2]}`;
const stacktrace = process.argv[3];
async function extractSourceMap() {
const releaseAssetsDirectory = resolve(
__dirname,
"..",
"release-assets",
versionNumber,
);
const sourceMapsDirectory = resolve(
__dirname,
"..",
"artifacts",
"source-maps",
versionNumber,
);
if (!(await pathExists(sourceMapsDirectory))) {
console.log("Downloading source maps...");
const release = runGhJSON<Release>([
"release",
"view",
versionNumber,
"--json",
"id,name,assets",
]);
const sourcemapAsset = release.assets.find(
(asset) => asset.name === `vscode-codeql-sourcemaps-${versionNumber}.zip`,
);
if (sourcemapAsset) {
// This downloads a ZIP file of the source maps
runGh([
"release",
"download",
versionNumber,
"--pattern",
sourcemapAsset.name,
"--dir",
releaseAssetsDirectory,
]);
const file = await Open.file(
resolve(releaseAssetsDirectory, sourcemapAsset.name),
);
await file.extract({ path: sourceMapsDirectory });
} else {
const workflowRuns = runGhJSON<WorkflowRunListItem[]>([
"run",
"list",
"--workflow",
"release.yml",
"--branch",
versionNumber,
"--json",
"databaseId,number",
]);
if (workflowRuns.length !== 1) {
throw new Error(
`Expected exactly one workflow run for ${versionNumber}, got ${workflowRuns.length}`,
);
}
const workflowRun = workflowRuns[0];
runGh([
"run",
"download",
workflowRun.databaseId.toString(),
"--name",
"vscode-codeql-sourcemaps",
"--dir",
sourceMapsDirectory,
]);
}
}
if (stacktrace.includes("at")) {
const rawSourceMaps = new Map<string, RawSourceMap>();
const mappedStacktrace = await replaceAsync(
stacktrace,
stackLineRegex,
async (match, name, file, line, column) => {
if (!rawSourceMaps.has(file)) {
const rawSourceMap: RawSourceMap = await readJSON(
resolve(sourceMapsDirectory, `${basename(file)}.map`),
);
rawSourceMaps.set(file, rawSourceMap);
}
const originalPosition = await SourceMapConsumer.with(
rawSourceMaps.get(file) as RawSourceMap,
null,
async function (consumer) {
return consumer.originalPositionFor({
line: parseInt(line, 10),
column: parseInt(column, 10),
});
},
);
if (!originalPosition.source) {
return match;
}
const originalFilename = resolve(file, "..", originalPosition.source);
return `at ${originalPosition.name ?? name} (${originalFilename}:${
originalPosition.line
}:${originalPosition.column})`;
},
);
console.log(mappedStacktrace);
} else {
// This means it's just a filename:line:column
const [filename, line, column] = stacktrace.split(":", 3);
const fileBasename = basename(filename);
const sourcemapName = `${fileBasename}.map`;
const sourcemapPath = resolve(sourceMapsDirectory, sourcemapName);
if (!(await pathExists(sourcemapPath))) {
throw new Error(`No source map found for ${fileBasename}`);
}
const rawSourceMap: RawSourceMap = await readJSON(sourcemapPath);
const originalPosition = await SourceMapConsumer.with(
rawSourceMap,
null,
async function (consumer) {
return consumer.originalPositionFor({
line: parseInt(line, 10),
column: parseInt(column, 10),
});
},
);
if (!originalPosition.source) {
throw new Error(`No source found for ${stacktrace}`);
}
const originalFilename = resolve(filename, "..", originalPosition.source);
console.log(
`${originalFilename}:${originalPosition.line}:${originalPosition.column}`,
);
}
}
extractSourceMap().catch((e: unknown) => {
console.error(e);
process.exit(2);
});
function runGh(args: readonly string[]): string {
const gh = spawnSync("gh", args);
if (gh.status !== 0) {
throw new Error(
`Failed to get the source map for ${versionNumber}: ${gh.stderr}`,
);
}
return gh.stdout.toString("utf-8");
}
function runGhJSON<T>(args: readonly string[]): T {
return JSON.parse(runGh(args));
}
type ReleaseAsset = {
id: string;
name: string;
};
type Release = {
id: string;
name: string;
assets: ReleaseAsset[];
};
type WorkflowRunListItem = {
databaseId: number;
number: number;
};
async function replaceAsync(
str: string,
regex: RegExp,
replacer: (substring: string, ...args: any[]) => Promise<string>,
) {
const promises: Array<Promise<string>> = [];
str.replace(regex, (match, ...args) => {
const promise = replacer(match, ...args);
promises.push(promise);
return match;
});
const data = await Promise.all(promises);
return str.replace(regex, () => data.shift() as string);
}

View File

@@ -24,6 +24,7 @@ export type WebviewPanelConfig = {
view: WebviewView;
preserveFocus?: boolean;
additionalOptions?: WebviewPanelOptions & WebviewOptions;
allowWasmEval?: boolean;
};
export abstract class AbstractWebview<
@@ -51,7 +52,7 @@ export abstract class AbstractWebview<
}
protected async getPanel(): Promise<WebviewPanel> {
if (this.panel == undefined) {
if (this.panel === undefined) {
const { ctx } = this;
// This is an async method, so in theory this method can be called concurrently. To ensure that we don't
@@ -116,6 +117,7 @@ export abstract class AbstractWebview<
config.view,
{
allowInlineStyles: true,
allowWasmEval: !!config.allowWasmEval,
},
);
this.push(

View File

@@ -0,0 +1,90 @@
import { Uri, window } from "vscode";
import { withProgress } from "./progress";
import { AstViewer } from "./astViewer";
import {
TemplatePrintAstProvider,
TemplatePrintCfgProvider,
} from "./contextual/templateProvider";
import { compileAndRunQuery } from "./local-queries";
import { QueryRunner } from "./queryRunner";
import { QueryHistoryManager } from "./query-history/query-history-manager";
import { DatabaseUI } from "./local-databases-ui";
import { ResultsView } from "./interface";
import { AstCfgCommands } from "./common/commands";
type AstCfgOptions = {
queryRunner: QueryRunner;
queryHistoryManager: QueryHistoryManager;
databaseUI: DatabaseUI;
localQueryResultsView: ResultsView;
queryStorageDir: string;
astViewer: AstViewer;
astTemplateProvider: TemplatePrintAstProvider;
cfgTemplateProvider: TemplatePrintCfgProvider;
};
export function getAstCfgCommands({
queryRunner,
queryHistoryManager,
databaseUI,
localQueryResultsView,
queryStorageDir,
astViewer,
astTemplateProvider,
cfgTemplateProvider,
}: AstCfgOptions): AstCfgCommands {
const viewAst = async (selectedFile: Uri) =>
withProgress(
async (progress, token) => {
const ast = await astTemplateProvider.provideAst(
progress,
token,
selectedFile ?? window.activeTextEditor?.document.uri,
);
if (ast) {
astViewer.updateRoots(await ast.getRoots(), ast.db, ast.fileName);
}
},
{
cancellable: true,
title: "Calculate AST",
},
);
const viewCfg = async () =>
withProgress(
async (progress, token) => {
const res = await cfgTemplateProvider.provideCfgUri(
window.activeTextEditor?.document,
);
if (res) {
await compileAndRunQuery(
queryRunner,
queryHistoryManager,
databaseUI,
localQueryResultsView,
queryStorageDir,
false,
res[0],
progress,
token,
undefined,
);
}
},
{
title: "Calculating Control Flow Graph",
cancellable: true,
},
);
return {
"codeQL.viewAst": viewAst,
"codeQL.viewAstContextExplorer": viewAst,
"codeQL.viewAstContextEditor": viewAst,
"codeQL.viewCfg": viewCfg,
"codeQL.viewCfgContextExplorer": viewCfg,
"codeQL.viewCfgContextEditor": viewCfg,
};
}

View File

@@ -15,7 +15,7 @@ import {
} from "vscode";
import { basename } from "path";
import { DatabaseItem } from "./databases";
import { DatabaseItem } from "./local-databases";
import { UrlValue, BqrsId } from "./pure/bqrs-cli-types";
import { showLocation } from "./interface-utils";
import {
@@ -23,9 +23,11 @@ import {
isWholeFileLoc,
isLineColumnLoc,
} from "./pure/bqrs-utils";
import { commandRunner } from "./commandRunner";
import { DisposableObject } from "./pure/disposable-object";
import { showAndLogErrorMessage } from "./helpers";
import { showAndLogExceptionWithTelemetry } from "./helpers";
import { asError, getErrorMessage } from "./pure/helpers-pure";
import { redactableError } from "./pure/errors";
import { AstViewerCommands } from "./common/commands";
export interface AstItem {
id: BqrsId;
@@ -53,15 +55,6 @@ class AstViewerDataProvider
readonly onDidChangeTreeData: Event<AstItem | undefined> =
this._onDidChangeTreeData.event;
constructor() {
super();
this.push(
commandRunner("codeQLAstViewer.gotoCode", async (item: AstItem) => {
await showLocation(item.fileLocation);
}),
);
}
refresh(): void {
this._onDidChangeTreeData.fire(undefined);
}
@@ -124,16 +117,20 @@ export class AstViewer extends DisposableObject {
this.push(this.treeView);
this.push(this.treeDataProvider);
this.push(
commandRunner("codeQLAstViewer.clear", async () => {
this.clear();
}),
);
this.push(
window.onDidChangeTextEditorSelection(this.updateTreeSelection, this),
);
}
getCommands(): AstViewerCommands {
return {
"codeQLAstViewer.clear": async () => this.clear(),
"codeQLAstViewer.gotoCode": async (item: AstItem) => {
await showLocation(item.fileLocation);
},
};
}
updateRoots(roots: AstItem[], db: DatabaseItem, fileUri: Uri) {
this.treeDataProvider.roots = roots;
this.treeDataProvider.db = db;
@@ -146,7 +143,12 @@ export class AstViewer extends DisposableObject {
() => {
/**/
},
(err) => showAndLogErrorMessage(err),
(error: unknown) =>
showAndLogExceptionWithTelemetry(
redactableError(
asError(error),
)`Failed to reveal AST: ${getErrorMessage(error)}`,
),
);
}
@@ -204,7 +206,12 @@ export class AstViewer extends DisposableObject {
() => {
/**/
},
(err) => showAndLogErrorMessage(err),
(error: unknown) =>
showAndLogExceptionWithTelemetry(
redactableError(
asError(error),
)`Failed to reveal AST: ${getErrorMessage(error)}`,
),
);
}
}

View File

@@ -1,114 +1,60 @@
import * as vscode from "vscode";
import * as Octokit from "@octokit/rest";
import { retry } from "@octokit/plugin-retry";
import { Credentials } from "./common/authentication";
const GITHUB_AUTH_PROVIDER_ID = "github";
// We need 'repo' scope for triggering workflows and 'gist' scope for exporting results to Gist.
// We need 'repo' scope for triggering workflows, 'gist' scope for exporting results to Gist,
// and 'read:packages' for reading private CodeQL packages.
// For a comprehensive list of scopes, see:
// https://docs.github.com/apps/building-oauth-apps/understanding-scopes-for-oauth-apps
const SCOPES = ["repo", "gist"];
const SCOPES = ["repo", "gist", "read:packages"];
/**
* Handles authentication to GitHub, using the VS Code [authentication API](https://code.visualstudio.com/api/references/vscode-api#authentication).
*/
export class Credentials {
export class VSCodeCredentials implements Credentials {
/**
* A specific octokit to return, otherwise a new authenticated octokit will be created when needed.
*/
private octokit: Octokit.Octokit | undefined;
// Explicitly make the constructor private, so that we can't accidentally call the constructor from outside the class
// without also initializing the class.
// eslint-disable-next-line @typescript-eslint/no-empty-function
private constructor() {}
/**
* Initializes an instance of credentials with an octokit instance.
*
* Do not call this method until you know you actually need an instance of credentials.
* since calling this method will require the user to log in.
*
* @param context The extension context.
* @returns An instance of credentials.
*/
static async initialize(
context: vscode.ExtensionContext,
): Promise<Credentials> {
const c = new Credentials();
c.registerListeners(context);
c.octokit = await c.createOctokit(false);
return c;
}
/**
* Initializes an instance of credentials with an octokit instance using
* a token from the user's GitHub account. This method is meant to be
* used non-interactive environments such as tests.
*
* @param overrideToken The GitHub token to use for authentication.
* @returns An instance of credentials.
*/
static async initializeWithToken(overrideToken: string) {
const c = new Credentials();
c.octokit = await c.createOctokit(false, overrideToken);
return c;
}
private async createOctokit(
createIfNone: boolean,
overrideToken?: string,
): Promise<Octokit.Octokit | undefined> {
if (overrideToken) {
return new Octokit.Octokit({ auth: overrideToken, retry });
}
const session = await vscode.authentication.getSession(
GITHUB_AUTH_PROVIDER_ID,
SCOPES,
{ createIfNone },
);
if (session) {
return new Octokit.Octokit({
auth: session.accessToken,
retry,
});
} else {
return undefined;
}
}
registerListeners(context: vscode.ExtensionContext): void {
// Sessions are changed when a user logs in or logs out.
context.subscriptions.push(
vscode.authentication.onDidChangeSessions(async (e) => {
if (e.provider.id === GITHUB_AUTH_PROVIDER_ID) {
this.octokit = await this.createOctokit(false);
}
}),
);
}
/**
* Creates or returns an instance of Octokit.
*
* @param requireAuthentication Whether the Octokit instance needs to be authenticated as user.
* @returns An instance of Octokit.
*/
async getOctokit(requireAuthentication = true): Promise<Octokit.Octokit> {
async getOctokit(): Promise<Octokit.Octokit> {
if (this.octokit) {
return this.octokit;
}
this.octokit = await this.createOctokit(requireAuthentication);
const accessToken = await this.getAccessToken();
if (!this.octokit) {
if (requireAuthentication) {
throw new Error("Did not initialize Octokit.");
}
return new Octokit.Octokit({
auth: accessToken,
retry,
});
}
// We don't want to set this in this.octokit because that would prevent
// authenticating when requireCredentials is true.
return new Octokit.Octokit({ retry });
}
return this.octokit;
async getAccessToken(): Promise<string> {
const session = await vscode.authentication.getSession(
GITHUB_AUTH_PROVIDER_ID,
SCOPES,
{ createIfNone: true },
);
return session.accessToken;
}
async getExistingAccessToken(): Promise<string | undefined> {
const session = await vscode.authentication.getSession(
GITHUB_AUTH_PROVIDER_ID,
SCOPES,
{ createIfNone: false },
);
return session?.accessToken;
}
}

View File

@@ -1,3 +1,4 @@
import { EOL } from "os";
import { spawn } from "child-process-promise";
import * as child_process from "child_process";
import { readFile } from "fs-extra";
@@ -6,7 +7,7 @@ import * as sarif from "sarif";
import { SemVer } from "semver";
import { Readable } from "stream";
import { StringDecoder } from "string_decoder";
import * as tk from "tree-kill";
import tk from "tree-kill";
import { promisify } from "util";
import { CancellationToken, commands, Disposable, Uri } from "vscode";
@@ -25,7 +26,9 @@ import { QueryMetadata, SortDirection } from "./pure/interface-types";
import { Logger, ProgressReporter } from "./common";
import { CompilationMessage } from "./pure/legacy-messages";
import { sarifParser } from "./sarif-parser";
import { dbSchemeToLanguage, walkDirectory } from "./helpers";
import { walkDirectory } from "./helpers";
import { App } from "./common/app";
import { QueryLanguage } from "./common/query-language";
/**
* The version of the SARIF format that we are using.
@@ -121,14 +124,6 @@ export interface SourceInfo {
*/
export type ResolvedTests = string[];
/**
* Options for `codeql test run`.
*/
export interface TestRunOptions {
cancellationToken?: CancellationToken;
logger?: Logger;
}
/**
* Event fired by `codeql test run`.
*/
@@ -156,6 +151,10 @@ interface BqrsDecodeOptions {
entities?: string[];
}
export type OnLineCallback = (
line: string,
) => Promise<string | undefined> | string | undefined;
/**
* This class manages a cli server started by `codeql execute cli-server` to
* run commands without the overhead of starting a new java
@@ -191,6 +190,7 @@ export class CodeQLCliServer implements Disposable {
public quiet = false;
constructor(
private readonly app: App,
private distributionProvider: DistributionProvider,
private cliConfig: CliConfig,
private logger: Logger,
@@ -288,7 +288,7 @@ export class CodeQLCliServer implements Disposable {
);
}
return await spawnServer(
return spawnServer(
codeQlPath,
"CodeQL CLI Server",
["execute", "cli-server"],
@@ -304,6 +304,7 @@ export class CodeQLCliServer implements Disposable {
command: string[],
commandArgs: string[],
description: string,
onLine?: OnLineCallback,
): Promise<string> {
const stderrBuffers: Buffer[] = [];
if (this.commandInProcess) {
@@ -328,6 +329,22 @@ export class CodeQLCliServer implements Disposable {
await new Promise<void>((resolve, reject) => {
// Start listening to stdout
process.stdout.addListener("data", (newData: Buffer) => {
if (onLine) {
void (async () => {
const response = await onLine(newData.toString("utf-8"));
if (!response) {
return;
}
process.stdin.write(`${response}${EOL}`);
// Remove newData from stdoutBuffers because the data has been consumed
// by the onLine callback.
stdoutBuffers.splice(stdoutBuffers.indexOf(newData), 1);
})();
}
stdoutBuffers.push(newData);
// If the buffer ends in '0' then exit.
// We don't have to check the middle as no output will be written after the null until
@@ -360,7 +377,7 @@ export class CodeQLCliServer implements Disposable {
this.killProcessIfRunning();
// Report the error (if there is a stderr then use that otherwise just report the error cod or nodejs error)
const newError =
stderrBuffers.length == 0
stderrBuffers.length === 0
? new Error(`${description} failed: ${err}`)
: new Error(
`${description} failed: ${Buffer.concat(stderrBuffers).toString(
@@ -431,7 +448,7 @@ export class CodeQLCliServer implements Disposable {
void logStream(child.stderr!, logger);
}
for await (const event of await splitStreamAtSeparators(child.stdout!, [
for await (const event of splitStreamAtSeparators(child.stdout!, [
"\0",
])) {
yield event;
@@ -460,10 +477,15 @@ export class CodeQLCliServer implements Disposable {
command: string[],
commandArgs: string[],
description: string,
cancellationToken?: CancellationToken,
logger?: Logger,
{
cancellationToken,
logger,
}: {
cancellationToken?: CancellationToken;
logger?: Logger;
} = {},
): AsyncGenerator<EventType, void, unknown> {
for await (const event of await this.runAsyncCodeQlCliCommandInternal(
for await (const event of this.runAsyncCodeQlCliCommandInternal(
command,
commandArgs,
cancellationToken,
@@ -487,13 +509,20 @@ export class CodeQLCliServer implements Disposable {
* @param commandArgs The arguments to pass to the `codeql` command.
* @param description Description of the action being run, to be shown in log and error messages.
* @param progressReporter Used to output progress messages, e.g. to the status bar.
* @param onLine Used for responding to interactive output on stdout/stdin.
* @returns The contents of the command's stdout, if the command succeeded.
*/
runCodeQlCliCommand(
command: string[],
commandArgs: string[],
description: string,
progressReporter?: ProgressReporter,
{
progressReporter,
onLine,
}: {
progressReporter?: ProgressReporter;
onLine?: OnLineCallback;
} = {},
): Promise<string> {
if (progressReporter) {
progressReporter.report({ message: description });
@@ -503,10 +532,12 @@ export class CodeQLCliServer implements Disposable {
// Construct the command that actually does the work
const callback = (): void => {
try {
this.runCodeQlCliInternal(command, commandArgs, description).then(
resolve,
reject,
);
this.runCodeQlCliInternal(
command,
commandArgs,
description,
onLine,
).then(resolve, reject);
} catch (err) {
reject(err);
}
@@ -522,32 +553,38 @@ export class CodeQLCliServer implements Disposable {
}
/**
* Runs a CodeQL CLI command, returning the output as JSON.
* Runs a CodeQL CLI command, parsing the output as JSON.
* @param command The `codeql` command to be run, provided as an array of command/subcommand names.
* @param commandArgs The arguments to pass to the `codeql` command.
* @param description Description of the action being run, to be shown in log and error messages.
* @param addFormat Whether or not to add commandline arguments to specify the format as JSON.
* @param progressReporter Used to output progress messages, e.g. to the status bar.
* @param onLine Used for responding to interactive output on stdout/stdin.
* @returns The contents of the command's stdout, if the command succeeded.
*/
async runJsonCodeQlCliCommand<OutputType>(
command: string[],
commandArgs: string[],
description: string,
addFormat = true,
progressReporter?: ProgressReporter,
{
addFormat = true,
progressReporter,
onLine,
}: {
addFormat?: boolean;
progressReporter?: ProgressReporter;
onLine?: OnLineCallback;
} = {},
): Promise<OutputType> {
let args: string[] = [];
if (addFormat)
// Add format argument first, in case commandArgs contains positional parameters.
args = args.concat(["--format", "json"]);
args = args.concat(commandArgs);
const result = await this.runCodeQlCliCommand(
command,
args,
description,
const result = await this.runCodeQlCliCommand(command, args, description, {
progressReporter,
);
onLine,
});
try {
return JSON.parse(result) as OutputType;
} catch (err) {
@@ -559,6 +596,72 @@ export class CodeQLCliServer implements Disposable {
}
}
/**
* Runs a CodeQL CLI command with authentication, parsing the output as JSON.
*
* This method is intended for use with commands that accept a `--github-auth-stdin` argument. This
* will be added to the command line arguments automatically if an access token is available.
*
* When the argument is given to the command, the CLI server will prompt for the access token on
* stdin. This method will automatically respond to the prompt with the access token.
*
* There are a few race conditions that can potentially happen:
* 1. The user logs in after the command has started. In this case, no access token will be given.
* 2. The user logs out after the command has started. In this case, the user will be prompted
* to login again. If they cancel the login, the old access token that was present before the
* command was started will be used.
*
* @param command The `codeql` command to be run, provided as an array of command/subcommand names.
* @param commandArgs The arguments to pass to the `codeql` command.
* @param description Description of the action being run, to be shown in log and error messages.
* @param addFormat Whether or not to add commandline arguments to specify the format as JSON.
* @param progressReporter Used to output progress messages, e.g. to the status bar.
* @returns The contents of the command's stdout, if the command succeeded.
*/
async runJsonCodeQlCliCommandWithAuthentication<OutputType>(
command: string[],
commandArgs: string[],
description: string,
{
addFormat,
progressReporter,
}: {
addFormat?: boolean;
progressReporter?: ProgressReporter;
} = {},
): Promise<OutputType> {
const accessToken = await this.app.credentials.getExistingAccessToken();
const extraArgs = accessToken ? ["--github-auth-stdin"] : [];
return this.runJsonCodeQlCliCommand(
command,
[...extraArgs, ...commandArgs],
description,
{
addFormat,
progressReporter,
onLine: async (line) => {
if (line.startsWith("Enter value for --github-auth-stdin")) {
try {
return await this.app.credentials.getAccessToken();
} catch (e) {
// If the user cancels the authentication prompt, we still need to give a value to the CLI.
// By giving a potentially invalid value, the user will just get a 401/403 when they try to access a
// private package and the access token is invalid.
// This code path is very rare to hit. It would only be hit if the user is logged in when
// starting the command, then logging out before the getAccessToken() is called again and
// then cancelling the authentication prompt.
return accessToken;
}
}
return undefined;
},
},
);
}
/**
* Resolve the library path and dbscheme for a query.
* @param workspaces The current open workspaces
@@ -623,7 +726,9 @@ export class CodeQLCliServer implements Disposable {
["resolve", "qlref"],
subcommandArgs,
"Resolving qlref",
false,
{
addFormat: false,
},
);
}
@@ -651,7 +756,13 @@ export class CodeQLCliServer implements Disposable {
public async *runTests(
testPaths: string[],
workspaces: string[],
options: TestRunOptions,
{
cancellationToken,
logger,
}: {
cancellationToken?: CancellationToken;
logger?: Logger;
},
): AsyncGenerator<TestCompleted, void, unknown> {
const subcommandArgs = this.cliConfig.additionalTestArguments.concat([
...this.getAdditionalPacksArg(workspaces),
@@ -660,12 +771,14 @@ export class CodeQLCliServer implements Disposable {
...testPaths,
]);
for await (const event of await this.runAsyncCodeQlCliCommand<TestCompleted>(
for await (const event of this.runAsyncCodeQlCliCommand<TestCompleted>(
["test", "run"],
subcommandArgs,
"Run CodeQL Tests",
options.cancellationToken,
options.logger,
{
cancellationToken,
logger,
},
)) {
yield event;
}
@@ -696,7 +809,9 @@ export class CodeQLCliServer implements Disposable {
["resolve", "ml-models"],
args,
"Resolving ML models",
false,
{
addFormat: false,
},
);
}
@@ -720,8 +835,9 @@ export class CodeQLCliServer implements Disposable {
["resolve", "ram"],
args,
"Resolving RAM settings",
true,
progressReporter,
{
progressReporter,
},
);
}
/**
@@ -1034,10 +1150,7 @@ export class CodeQLCliServer implements Disposable {
];
if (targetDbScheme) {
args.push("--target-dbscheme", targetDbScheme);
if (
allowDowngradesIfPossible &&
(await this.cliConstraints.supportsDowngrades())
) {
if (allowDowngradesIfPossible) {
args.push("--allow-downgrades");
}
}
@@ -1050,24 +1163,32 @@ export class CodeQLCliServer implements Disposable {
/**
* Gets information about available qlpacks
* @param additionalPacks A list of directories to search for qlpacks before searching in `searchPath`.
* @param searchPath A list of directories to search for packs not found in `additionalPacks`. If undefined,
* the default CLI search path is used.
* @param additionalPacks A list of directories to search for qlpacks.
* @param extensionPacksOnly Whether to only search for extension packs. If true, only extension packs will
* be returned. If false, all packs will be returned.
* @returns A dictionary mapping qlpack name to the directory it comes from
*/
resolveQlpacks(
async resolveQlpacks(
additionalPacks: string[],
searchPath?: string[],
extensionPacksOnly = false,
): Promise<QlpacksInfo> {
const args = this.getAdditionalPacksArg(additionalPacks);
if (searchPath?.length) {
args.push("--search-path", join(...searchPath));
if (extensionPacksOnly) {
if (!(await this.cliConstraints.supportsQlpacksKind())) {
void this.logger.log(
"Warning: Running with extension packs is only supported by CodeQL CLI v2.12.3 or later.",
);
return {};
}
args.push("--kind", "extension", "--no-recursive");
}
return this.runJsonCodeQlCliCommand<QlpacksInfo>(
["resolve", "qlpacks"],
args,
"Resolving qlpack information",
`Resolving qlpack information${
extensionPacksOnly ? " (extension packs only)" : ""
}`,
);
}
@@ -1091,9 +1212,11 @@ export class CodeQLCliServer implements Disposable {
*/
public async getSupportedLanguages(): Promise<string[]> {
if (!this._supportedLanguages) {
// Get the intersection of resolveLanguages with the list of hardcoded languages in dbSchemeToLanguage.
// Get the intersection of resolveLanguages with the list of languages in QueryLanguage.
const resolvedLanguages = Object.keys(await this.resolveLanguages());
const hardcodedLanguages = Object.values(dbSchemeToLanguage);
const hardcodedLanguages = Object.values(QueryLanguage).map((s) =>
s.toString(),
);
this._supportedLanguages = resolvedLanguages.filter((lang) =>
hardcodedLanguages.includes(lang),
@@ -1119,10 +1242,8 @@ export class CodeQLCliServer implements Disposable {
if (searchPath !== undefined) {
args.push("--search-path", join(...searchPath));
}
if (await this.cliConstraints.supportsAllowLibraryPacksInResolveQueries()) {
// All of our usage of `codeql resolve queries` needs to handle library packs.
args.push("--allow-library-packs");
}
// All of our usage of `codeql resolve queries` needs to handle library packs.
args.push("--allow-library-packs");
args.push(suite);
return this.runJsonCodeQlCliCommand<string[]>(
["resolve", "queries"],
@@ -1131,24 +1252,58 @@ export class CodeQLCliServer implements Disposable {
);
}
/**
* Adds a core language QL library pack for the given query language as a dependency
* of the current package, and then installs them. This command modifies the qlpack.yml
* file of the current package. Formatting and comments will be removed.
* @param dir The directory where QL pack exists.
* @param language The language of the QL pack.
*/
async packAdd(dir: string, queryLanguage: QueryLanguage) {
const args = ["--dir", dir];
args.push(`codeql/${queryLanguage}-all`);
return this.runJsonCodeQlCliCommandWithAuthentication(
["pack", "add"],
args,
`Adding and installing ${queryLanguage} pack dependency.`,
{
addFormat: false,
},
);
}
/**
* Downloads a specified pack.
* @param packs The `<package-scope/name[@version]>` of the packs to download.
*/
async packDownload(packs: string[]) {
return this.runJsonCodeQlCliCommand(
return this.runJsonCodeQlCliCommandWithAuthentication(
["pack", "download"],
packs,
"Downloading packs",
);
}
async packInstall(dir: string, forceUpdate = false) {
async packInstall(
dir: string,
{ forceUpdate = false, workspaceFolders = [] as string[] } = {},
) {
const args = [dir];
if (forceUpdate) {
args.push("--mode", "update");
}
return this.runJsonCodeQlCliCommand(
if (workspaceFolders?.length > 0) {
if (await this.cliConstraints.supportsAdditionalPacksInstall()) {
args.push(
// Allow prerelease packs from the ql submodule.
"--allow-prerelease",
// Allow the use of --additional-packs argument without issueing a warning
"--no-strict-mode",
...this.getAdditionalPacksArg(workspaceFolders),
);
}
}
return this.runJsonCodeQlCliCommandWithAuthentication(
["pack", "install"],
args,
"Installing pack dependencies",
@@ -1169,7 +1324,7 @@ export class CodeQLCliServer implements Disposable {
...this.getAdditionalPacksArg(workspaceFolders),
];
return this.runJsonCodeQlCliCommand(
return this.runJsonCodeQlCliCommandWithAuthentication(
["pack", "bundle"],
args,
"Bundling pack",
@@ -1200,7 +1355,7 @@ export class CodeQLCliServer implements Disposable {
): Promise<{ [pack: string]: string }> {
// Uses the default `--mode use-lock`, which creates the lock file if it doesn't exist.
const results: { [pack: string]: string } =
await this.runJsonCodeQlCliCommand(
await this.runJsonCodeQlCliCommandWithAuthentication(
["pack", "resolve-dependencies"],
[dir],
"Resolving pack dependencies",
@@ -1209,12 +1364,9 @@ export class CodeQLCliServer implements Disposable {
}
async generateDil(qloFile: string, outFile: string): Promise<void> {
const extraArgs = (await this.cliConstraints.supportsDecompileDil())
? ["--kind", "dil", "-o", outFile, qloFile]
: ["-o", outFile, qloFile];
await this.runCodeQlCliCommand(
["query", "decompile"],
extraArgs,
["--kind", "dil", "-o", outFile, qloFile],
"Generating DIL",
);
}
@@ -1250,6 +1402,17 @@ export class CodeQLCliServer implements Disposable {
private getAdditionalPacksArg(paths: string[]): string[] {
return paths.length ? ["--additional-packs", paths.join(delimiter)] : [];
}
public async useExtensionPacks(): Promise<boolean> {
return (
this.cliConfig.useExtensionPacks &&
(await this.cliConstraints.supportsQlpacksKind())
);
}
public async setUseExtensionPacks(useExtensionPacks: boolean) {
await this.cliConfig.setUseExtensionPacks(useExtensionPacks);
}
}
/**
@@ -1461,7 +1624,7 @@ const lineEndings = ["\r\n", "\r", "\n"];
* @param logger The logger that will consume the stream output.
*/
async function logStream(stream: Readable, logger: Logger): Promise<void> {
for await (const line of await splitStreamAtSeparators(stream, lineEndings)) {
for await (const line of splitStreamAtSeparators(stream, lineEndings)) {
// Await the result of log here in order to ensure the logs are written in the correct order.
await logger.log(line);
}
@@ -1492,56 +1655,6 @@ export function shouldDebugCliServer() {
}
export class CliVersionConstraint {
/**
* CLI version where --kind=DIL was introduced
*/
public static CLI_VERSION_WITH_DECOMPILE_KIND_DIL = new SemVer("2.3.0");
/**
* CLI version where languages are exposed during a `codeql resolve database` command.
*/
public static CLI_VERSION_WITH_LANGUAGE = new SemVer("2.4.1");
public static CLI_VERSION_WITH_NONDESTURCTIVE_UPGRADES = new SemVer("2.4.2");
/**
* CLI version where `codeql resolve upgrades` supports
* the `--allow-downgrades` flag
*/
public static CLI_VERSION_WITH_DOWNGRADES = new SemVer("2.4.4");
/**
* CLI version where the `codeql resolve qlref` command is available.
*/
public static CLI_VERSION_WITH_RESOLVE_QLREF = new SemVer("2.5.1");
/**
* CLI version where database registration was introduced
*/
public static CLI_VERSION_WITH_DB_REGISTRATION = new SemVer("2.4.1");
/**
* CLI version where the `--allow-library-packs` option to `codeql resolve queries` was
* introduced.
*/
public static CLI_VERSION_WITH_ALLOW_LIBRARY_PACKS_IN_RESOLVE_QUERIES =
new SemVer("2.6.1");
/**
* CLI version where the `database unbundle` subcommand was introduced.
*/
public static CLI_VERSION_WITH_DATABASE_UNBUNDLE = new SemVer("2.6.0");
/**
* CLI version where the `--no-precompile` option for pack creation was introduced.
*/
public static CLI_VERSION_WITH_NO_PRECOMPILE = new SemVer("2.7.1");
/**
* CLI version where remote queries (variant analysis) are supported.
*/
public static CLI_VERSION_REMOTE_QUERIES = new SemVer("2.6.3");
/**
* CLI version where building QLX packs for remote queries is supported.
* (The options were _accepted_ by a few earlier versions, but only from
@@ -1549,11 +1662,6 @@ export class CliVersionConstraint {
*/
public static CLI_VERSION_QLX_REMOTE = new SemVer("2.11.3");
/**
* CLI version where the `resolve ml-models` subcommand was introduced.
*/
public static CLI_VERSION_WITH_RESOLVE_ML_MODELS = new SemVer("2.7.3");
/**
* CLI version where the `resolve ml-models` subcommand was enhanced to work with packaging.
*/
@@ -1561,16 +1669,6 @@ export class CliVersionConstraint {
"2.10.0",
);
/**
* CLI version where the `--old-eval-stats` option to the query server was introduced.
*/
public static CLI_VERSION_WITH_OLD_EVAL_STATS = new SemVer("2.7.4");
/**
* CLI version where packaging was introduced.
*/
public static CLI_VERSION_WITH_PACKAGING = new SemVer("2.6.0");
/**
* CLI version where the `--evaluator-log` and related options to the query server were introduced,
* on a per-query server basis.
@@ -1603,6 +1701,18 @@ export class CliVersionConstraint {
*/
public static CLI_VERSION_WITH_WORKSPACE_RFERENCES = new SemVer("2.11.3");
/**
* CLI version that supports the `--kind` option for the `resolve qlpacks` command.
*/
public static CLI_VERSION_WITH_QLPACKS_KIND = new SemVer("2.12.3");
/**
* CLI version that supports the `--additional-packs` option for the `pack install` command.
*/
public static CLI_VERSION_WITH_ADDITIONAL_PACKS_INSTALL = new SemVer(
"2.12.4",
);
constructor(private readonly cli: CodeQLCliServer) {
/**/
}
@@ -1611,94 +1721,16 @@ export class CliVersionConstraint {
return (await this.cli.getVersion()).compare(v) >= 0;
}
public async supportsDecompileDil() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_DECOMPILE_KIND_DIL,
);
}
public async supportsLanguageName() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_LANGUAGE,
);
}
public async supportsNonDestructiveUpgrades() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_NONDESTURCTIVE_UPGRADES,
);
}
public async supportsDowngrades() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_DOWNGRADES,
);
}
public async supportsResolveQlref() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_RESOLVE_QLREF,
);
}
public async supportsAllowLibraryPacksInResolveQueries() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_ALLOW_LIBRARY_PACKS_IN_RESOLVE_QUERIES,
);
}
async supportsDatabaseRegistration() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_DB_REGISTRATION,
);
}
async supportsDatabaseUnbundle() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_DATABASE_UNBUNDLE,
);
}
async supportsNoPrecompile() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_NO_PRECOMPILE,
);
}
async supportsRemoteQueries() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_REMOTE_QUERIES,
);
}
async supportsQlxRemote() {
return this.isVersionAtLeast(CliVersionConstraint.CLI_VERSION_QLX_REMOTE);
}
async supportsResolveMlModels() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_RESOLVE_ML_MODELS,
);
}
async supportsPreciseResolveMlModels() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_PRECISE_RESOLVE_ML_MODELS,
);
}
async supportsOldEvalStats() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_OLD_EVAL_STATS,
);
}
async supportsPackaging() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_PACKAGING,
);
}
async supportsStructuredEvalLog() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_STRUCTURED_EVAL_LOG,
@@ -1738,4 +1770,16 @@ export class CliVersionConstraint {
CliVersionConstraint.CLI_VERSION_WITH_WORKSPACE_RFERENCES,
);
}
async supportsQlpacksKind() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_QLPACKS_KIND,
);
}
async supportsAdditionalPacksInstall() {
return this.isVersionAtLeast(
CliVersionConstraint.CLI_VERSION_WITH_ADDITIONAL_PACKS_INSTALL,
);
}
}

View File

@@ -1,63 +1,13 @@
import { commands, Disposable } from "vscode";
import {
CancellationToken,
ProgressOptions,
window as Window,
commands,
Disposable,
ProgressLocation,
} from "vscode";
import { showAndLogErrorMessage, showAndLogWarningMessage } from "./helpers";
showAndLogExceptionWithTelemetry,
showAndLogWarningMessage,
} from "./helpers";
import { extLogger } from "./common";
import { getErrorMessage, getErrorStack } from "./pure/helpers-pure";
import { asError, getErrorMessage, getErrorStack } from "./pure/helpers-pure";
import { telemetryListener } from "./telemetry";
export class UserCancellationException extends Error {
/**
* @param message The error message
* @param silent If silent is true, then this exception will avoid showing a warning message to the user.
*/
constructor(message?: string, public readonly silent = false) {
super(message);
}
}
export interface ProgressUpdate {
/**
* The current step
*/
step: number;
/**
* The maximum step. This *should* be constant for a single job.
*/
maxStep: number;
/**
* The current progress message
*/
message: string;
}
export type ProgressCallback = (p: ProgressUpdate) => void;
/**
* A task that handles command invocations from `commandRunner`
* and includes a progress monitor.
*
*
* Arguments passed to the command handler are passed along,
* untouched to this `ProgressTask` instance.
*
* @param progress a progress handler function. Call this
* function with a `ProgressUpdate` instance in order to
* denote some progress being achieved on this task.
* @param token a cencellation token
* @param args arguments passed to this task passed on from
* `commands.registerCommand`.
*/
export type ProgressTask<R> = (
progress: ProgressCallback,
token: CancellationToken,
...args: any[]
) => Thenable<R>;
import { redactableError } from "./pure/errors";
import { UserCancellationException } from "./progress";
/**
* A task that handles command invocations from `commandRunner`.
@@ -67,43 +17,7 @@ export type ProgressTask<R> = (
* @param args arguments passed to this task passed on from
* `commands.registerCommand`.
*/
type NoProgressTask = (...args: any[]) => Promise<any>;
/**
* This mediates between the kind of progress callbacks we want to
* write (where we *set* current progress position and give
* `maxSteps`) and the kind vscode progress api expects us to write
* (which increment progress by a certain amount out of 100%).
*
* Where possible, the `commandRunner` function below should be used
* instead of this function. The commandRunner is meant for wrapping
* top-level commands and provides error handling and other support
* automatically.
*
* Only use this function if you need a progress monitor and the
* control flow does not always come from a command (eg- during
* extension activation, or from an internal language server
* request).
*/
export function withProgress<R>(
options: ProgressOptions,
task: ProgressTask<R>,
...args: any[]
): Thenable<R> {
let progressAchieved = 0;
return Window.withProgress(options, (progress, token) => {
return task(
(p) => {
const { message, step, maxStep } = p;
const increment = (100 * (step - progressAchieved)) / maxStep;
progressAchieved = step;
progress.report({ message, increment });
},
token,
...args,
);
});
}
export type NoProgressTask = (...args: any[]) => Promise<any>;
/**
* A generic wrapper for command registration. This wrapper adds uniform error handling for commands.
@@ -117,6 +31,7 @@ export function withProgress<R>(
export function commandRunner(
commandId: string,
task: NoProgressTask,
outputLogger = extLogger,
): Disposable {
return commands.registerCommand(commandId, async (...args: any[]) => {
const startTime = Date.now();
@@ -125,128 +40,37 @@ export function commandRunner(
try {
return await task(...args);
} catch (e) {
const errorMessage = `${getErrorMessage(e) || e} (${commandId})`;
error = e instanceof Error ? e : new Error(errorMessage);
error = asError(e);
const errorMessage = redactableError(error)`${
getErrorMessage(e) || e
} (${commandId})`;
const errorStack = getErrorStack(e);
if (e instanceof UserCancellationException) {
// User has cancelled this action manually
if (e.silent) {
void extLogger.log(errorMessage);
void outputLogger.log(errorMessage.fullMessage);
} else {
void showAndLogWarningMessage(errorMessage);
void showAndLogWarningMessage(errorMessage.fullMessage, {
outputLogger,
});
}
} else {
// Include the full stack in the error log only.
const fullMessage = errorStack
? `${errorMessage}\n${errorStack}`
: errorMessage;
void showAndLogErrorMessage(errorMessage, {
fullMessage,
});
}
return undefined;
} finally {
const executionTime = Date.now() - startTime;
telemetryListener.sendCommandUsage(commandId, executionTime, error);
}
});
}
/**
* A generic wrapper for command registration. This wrapper adds uniform error handling,
* progress monitoring, and cancellation for commands.
*
* @param commandId The ID of the command to register.
* @param task The task to run. It is passed directly to `commands.registerCommand`. Any
* arguments to the command handler are passed on to the task after the progress callback
* and cancellation token.
* @param progressOptions Progress options to be sent to the progress monitor.
*/
export function commandRunnerWithProgress<R>(
commandId: string,
task: ProgressTask<R>,
progressOptions: Partial<ProgressOptions>,
outputLogger = extLogger,
): Disposable {
return commands.registerCommand(commandId, async (...args: any[]) => {
const startTime = Date.now();
let error: Error | undefined;
const progressOptionsWithDefaults = {
location: ProgressLocation.Notification,
...progressOptions,
};
try {
return await withProgress(progressOptionsWithDefaults, task, ...args);
} catch (e) {
const errorMessage = `${getErrorMessage(e) || e} (${commandId})`;
error = e instanceof Error ? e : new Error(errorMessage);
const errorStack = getErrorStack(e);
if (e instanceof UserCancellationException) {
// User has cancelled this action manually
if (e.silent) {
void outputLogger.log(errorMessage);
} else {
void showAndLogWarningMessage(errorMessage, { outputLogger });
}
} else {
// Include the full stack in the error log only.
const fullMessage = errorStack
? `${errorMessage}\n${errorStack}`
: errorMessage;
void showAndLogErrorMessage(errorMessage, {
? `${errorMessage.fullMessage}\n${errorStack}`
: errorMessage.fullMessage;
void showAndLogExceptionWithTelemetry(errorMessage, {
outputLogger,
fullMessage,
extraTelemetryProperties: {
command: commandId,
},
});
}
return undefined;
} finally {
const executionTime = Date.now() - startTime;
telemetryListener.sendCommandUsage(commandId, executionTime, error);
telemetryListener?.sendCommandUsage(commandId, executionTime, error);
}
});
}
/**
* Displays a progress monitor that indicates how much progess has been made
* reading from a stream.
*
* @param readable The stream to read progress from
* @param messagePrefix A prefix for displaying the message
* @param totalNumBytes Total number of bytes in this stream
* @param progress The progress callback used to set messages
*/
export function reportStreamProgress(
readable: NodeJS.ReadableStream,
messagePrefix: string,
totalNumBytes?: number,
progress?: ProgressCallback,
) {
if (progress && totalNumBytes) {
let numBytesDownloaded = 0;
const bytesToDisplayMB = (numBytes: number): string =>
`${(numBytes / (1024 * 1024)).toFixed(1)} MB`;
const updateProgress = () => {
progress({
step: numBytesDownloaded,
maxStep: totalNumBytes,
message: `${messagePrefix} [${bytesToDisplayMB(
numBytesDownloaded,
)} of ${bytesToDisplayMB(totalNumBytes)}]`,
});
};
// Display the progress straight away rather than waiting for the first chunk.
updateProgress();
readable.on("data", (data) => {
numBytesDownloaded += data.length;
updateProgress();
});
} else if (progress) {
progress({
step: 1,
maxStep: 2,
message: `${messagePrefix} (Size unknown)`,
});
}
}

View File

@@ -1,14 +1,21 @@
import { Credentials } from "./authentication";
import { Disposable } from "../pure/disposable-object";
import { AppEventEmitter } from "./events";
import { Logger } from "./logging";
import { Memento } from "./memento";
import { AppCommandManager } from "./commands";
export interface App {
createEventEmitter<T>(): AppEventEmitter<T>;
executeCommand(command: string, ...args: any): Thenable<void>;
mode: AppMode;
subscriptions: Disposable[];
extensionPath: string;
globalStoragePath: string;
workspaceStoragePath?: string;
readonly mode: AppMode;
readonly logger: Logger;
readonly subscriptions: Disposable[];
readonly extensionPath: string;
readonly globalStoragePath: string;
readonly workspaceStoragePath?: string;
readonly workspaceState: Memento;
readonly credentials: Credentials;
readonly commands: AppCommandManager;
}
export enum AppMode {

View File

@@ -0,0 +1,34 @@
import * as Octokit from "@octokit/rest";
/**
* An interface providing methods for obtaining access tokens
* or an octokit instance for making HTTP requests.
*/
export interface Credentials {
/**
* Returns an authenticated instance of Octokit.
* May prompt the user to log in and grant permission to use their
* token, if they have not already done so.
*
* @returns An instance of Octokit.
*/
getOctokit(): Promise<Octokit.Octokit>;
/**
* Returns an OAuth access token.
* May prompt the user to log in and grant permission to use their
* token, if they have not already done so.
*
* @returns An OAuth access token.
*/
getAccessToken(): Promise<string>;
/**
* Returns an OAuth access token if one is available.
* If a token is not available this will return undefined and
* will not prompt the user to log in.
*
* @returns An OAuth access token, or undefined.
*/
getExistingAccessToken(): Promise<string | undefined>;
}

View File

@@ -0,0 +1,278 @@
import type { CommandManager } from "../packages/commands";
import type { Uri, Range } from "vscode";
import type { AstItem } from "../astViewer";
import type { DbTreeViewItem } from "../databases/ui/db-tree-view-item";
import type { DatabaseItem } from "../local-databases";
import type { QueryHistoryInfo } from "../query-history/query-history-info";
import type { RepositoriesFilterSortStateWithIds } from "../pure/variant-analysis-filter-sort";
import type { TestTreeNode } from "../test-tree-node";
import type {
VariantAnalysis,
VariantAnalysisScannedRepository,
VariantAnalysisScannedRepositoryResult,
} from "../variant-analysis/shared/variant-analysis";
// A command function matching the signature that VS Code calls when
// a command on a selection is invoked.
export type SelectionCommandFunction<Item> = (
singleItem: Item,
multiSelect: Item[],
) => Promise<void>;
// A command function matching the signature that VS Code calls when
// a command on a selection is invoked when canSelectMany is false.
export type SingleSelectionCommandFunction<Item> = (
singleItem: Item,
) => Promise<void>;
/**
* Contains type definitions for all commands used by the extension.
*
* To add a new command first define its type here, then provide
* the implementation in the corresponding `getCommands` function.
*/
// Builtin commands where the implementation is provided by VS Code and not by this extension.
// See https://code.visualstudio.com/api/references/commands
export type BuiltInVsCodeCommands = {
"markdown.showPreviewToSide": (uri: Uri) => Promise<void>;
setContext: (
key: `${"codeql" | "codeQL"}${string}`,
value: unknown,
) => Promise<void>;
"workbench.action.reloadWindow": () => Promise<void>;
};
// Commands that are available before the extension is fully activated.
// These commands are *not* registered using the command manager, but can
// be invoked using the command manager.
export type PreActivationCommands = {
"codeQL.checkForUpdatesToCLI": () => Promise<void>;
};
// Base commands not tied directly to a module like e.g. variant analysis.
export type BaseCommands = {
"codeQL.openDocumentation": () => Promise<void>;
"codeQL.showLogs": () => Promise<void>;
"codeQL.authenticateToGitHub": () => Promise<void>;
"codeQL.copyVersion": () => Promise<void>;
"codeQL.restartQueryServer": () => Promise<void>;
};
// Commands used when working with queries in the editor
export type QueryEditorCommands = {
"codeQL.openReferencedFile": (selectedQuery: Uri) => Promise<void>;
"codeQL.openReferencedFileContextEditor": (
selectedQuery: Uri,
) => Promise<void>;
"codeQL.openReferencedFileContextExplorer": (
selectedQuery: Uri,
) => Promise<void>;
"codeQL.previewQueryHelp": (selectedQuery: Uri) => Promise<void>;
};
// Commands used for running local queries
export type LocalQueryCommands = {
"codeQL.runQuery": (uri?: Uri) => Promise<void>;
"codeQL.runQueryContextEditor": (uri?: Uri) => Promise<void>;
"codeQL.runQueryOnMultipleDatabases": (uri?: Uri) => Promise<void>;
"codeQL.runQueryOnMultipleDatabasesContextEditor": (
uri?: Uri,
) => Promise<void>;
"codeQL.runQueries": SelectionCommandFunction<Uri>;
"codeQL.quickEval": (uri: Uri) => Promise<void>;
"codeQL.quickEvalContextEditor": (uri: Uri) => Promise<void>;
"codeQL.codeLensQuickEval": (uri: Uri, range: Range) => Promise<void>;
"codeQL.quickQuery": () => Promise<void>;
};
export type ResultsViewCommands = {
"codeQLQueryResults.up": () => Promise<void>;
"codeQLQueryResults.down": () => Promise<void>;
"codeQLQueryResults.left": () => Promise<void>;
"codeQLQueryResults.right": () => Promise<void>;
"codeQLQueryResults.nextPathStep": () => Promise<void>;
"codeQLQueryResults.previousPathStep": () => Promise<void>;
};
// Commands used for the query history panel
export type QueryHistoryCommands = {
// Commands in the "navigation" group
"codeQLQueryHistory.sortByName": () => Promise<void>;
"codeQLQueryHistory.sortByDate": () => Promise<void>;
"codeQLQueryHistory.sortByCount": () => Promise<void>;
// Commands in the context menu or in the hover menu
"codeQLQueryHistory.openQueryTitleMenu": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.openQueryContextMenu": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.removeHistoryItemTitleMenu": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.removeHistoryItemContextMenu": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.removeHistoryItemContextInline": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.renameItem": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.compareWith": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.showEvalLog": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.showEvalLogSummary": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.showEvalLogViewer": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.showQueryLog": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.showQueryText": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.openQueryDirectory": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.cancel": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.exportResults": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.viewCsvResults": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.viewCsvAlerts": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.viewSarifAlerts": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.viewDil": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.itemClicked": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.openOnGithub": SelectionCommandFunction<QueryHistoryInfo>;
"codeQLQueryHistory.copyRepoList": SelectionCommandFunction<QueryHistoryInfo>;
// Commands in the command palette
"codeQL.exportSelectedVariantAnalysisResults": () => Promise<void>;
};
// Commands used for the local databases panel
export type LocalDatabasesCommands = {
// Command palette commands
"codeQL.chooseDatabaseFolder": () => Promise<void>;
"codeQL.chooseDatabaseArchive": () => Promise<void>;
"codeQL.chooseDatabaseInternet": () => Promise<void>;
"codeQL.chooseDatabaseGithub": () => Promise<void>;
"codeQL.upgradeCurrentDatabase": () => Promise<void>;
"codeQL.clearCache": () => Promise<void>;
// Explorer context menu
"codeQL.setCurrentDatabase": (uri: Uri) => Promise<void>;
// Database panel view title commands
"codeQLDatabases.chooseDatabaseFolder": () => Promise<void>;
"codeQLDatabases.chooseDatabaseArchive": () => Promise<void>;
"codeQLDatabases.chooseDatabaseInternet": () => Promise<void>;
"codeQLDatabases.chooseDatabaseGithub": () => Promise<void>;
"codeQLDatabases.sortByName": () => Promise<void>;
"codeQLDatabases.sortByDateAdded": () => Promise<void>;
// Database panel context menu
"codeQLDatabases.setCurrentDatabase": (
databaseItem: DatabaseItem,
) => Promise<void>;
// Database panel selection commands
"codeQLDatabases.removeDatabase": SelectionCommandFunction<DatabaseItem>;
"codeQLDatabases.upgradeDatabase": SelectionCommandFunction<DatabaseItem>;
"codeQLDatabases.renameDatabase": SelectionCommandFunction<DatabaseItem>;
"codeQLDatabases.openDatabaseFolder": SelectionCommandFunction<DatabaseItem>;
"codeQLDatabases.addDatabaseSource": SelectionCommandFunction<DatabaseItem>;
// Codespace template commands
"codeQL.setDefaultTourDatabase": () => Promise<void>;
// Internal commands
"codeQLDatabases.removeOrphanedDatabases": () => Promise<void>;
};
// Commands tied to variant analysis
export type VariantAnalysisCommands = {
"codeQL.autoDownloadVariantAnalysisResult": (
scannedRepo: VariantAnalysisScannedRepository,
variantAnalysisSummary: VariantAnalysis,
) => Promise<void>;
"codeQL.copyVariantAnalysisRepoList": (
variantAnalysisId: number,
filterSort?: RepositoriesFilterSortStateWithIds,
) => Promise<void>;
"codeQL.loadVariantAnalysisRepoResults": (
variantAnalysisId: number,
repositoryFullName: string,
) => Promise<VariantAnalysisScannedRepositoryResult>;
"codeQL.monitorVariantAnalysis": (
variantAnalysis: VariantAnalysis,
) => Promise<void>;
"codeQL.openVariantAnalysisLogs": (
variantAnalysisId: number,
) => Promise<void>;
"codeQL.openVariantAnalysisView": (
variantAnalysisId: number,
) => Promise<void>;
"codeQL.runVariantAnalysis": (uri?: Uri) => Promise<void>;
"codeQL.runVariantAnalysisContextEditor": (uri?: Uri) => Promise<void>;
};
export type DatabasePanelCommands = {
"codeQLVariantAnalysisRepositories.openConfigFile": () => Promise<void>;
"codeQLVariantAnalysisRepositories.addNewDatabase": () => Promise<void>;
"codeQLVariantAnalysisRepositories.addNewList": () => Promise<void>;
"codeQLVariantAnalysisRepositories.setupControllerRepository": () => Promise<void>;
"codeQLVariantAnalysisRepositories.setSelectedItem": SingleSelectionCommandFunction<DbTreeViewItem>;
"codeQLVariantAnalysisRepositories.setSelectedItemContextMenu": SingleSelectionCommandFunction<DbTreeViewItem>;
"codeQLVariantAnalysisRepositories.openOnGitHubContextMenu": SingleSelectionCommandFunction<DbTreeViewItem>;
"codeQLVariantAnalysisRepositories.renameItemContextMenu": SingleSelectionCommandFunction<DbTreeViewItem>;
"codeQLVariantAnalysisRepositories.removeItemContextMenu": SingleSelectionCommandFunction<DbTreeViewItem>;
};
export type AstCfgCommands = {
"codeQL.viewAst": (selectedFile: Uri) => Promise<void>;
"codeQL.viewAstContextExplorer": (selectedFile: Uri) => Promise<void>;
"codeQL.viewAstContextEditor": (selectedFile: Uri) => Promise<void>;
"codeQL.viewCfg": () => Promise<void>;
"codeQL.viewCfgContextExplorer": () => Promise<void>;
"codeQL.viewCfgContextEditor": () => Promise<void>;
};
export type AstViewerCommands = {
"codeQLAstViewer.clear": () => Promise<void>;
"codeQLAstViewer.gotoCode": (item: AstItem) => Promise<void>;
};
export type PackagingCommands = {
"codeQL.installPackDependencies": () => Promise<void>;
"codeQL.downloadPacks": () => Promise<void>;
};
export type EvalLogViewerCommands = {
"codeQLEvalLogViewer.clear": () => Promise<void>;
};
export type SummaryLanguageSupportCommands = {
"codeQL.gotoQL": () => Promise<void>;
};
export type TestUICommands = {
"codeQLTests.showOutputDifferences": (node: TestTreeNode) => Promise<void>;
"codeQLTests.acceptOutput": (node: TestTreeNode) => Promise<void>;
};
export type MockGitHubApiServerCommands = {
"codeQL.mockGitHubApiServer.startRecording": () => Promise<void>;
"codeQL.mockGitHubApiServer.saveScenario": () => Promise<void>;
"codeQL.mockGitHubApiServer.cancelRecording": () => Promise<void>;
"codeQL.mockGitHubApiServer.loadScenario": () => Promise<void>;
"codeQL.mockGitHubApiServer.unloadScenario": () => Promise<void>;
};
// All commands where the implementation is provided by this activated extension.
export type AllExtensionCommands = BaseCommands &
QueryEditorCommands &
ResultsViewCommands &
QueryHistoryCommands &
LocalDatabasesCommands &
VariantAnalysisCommands &
DatabasePanelCommands &
AstCfgCommands &
AstViewerCommands &
PackagingCommands &
EvalLogViewerCommands &
SummaryLanguageSupportCommands &
Partial<TestUICommands> &
MockGitHubApiServerCommands;
export type AllCommands = AllExtensionCommands &
PreActivationCommands &
BuiltInVsCodeCommands;
export type AppCommandManager = CommandManager<AllCommands>;
// Separate command manager because it uses a different logger
export type QueryServerCommands = LocalQueryCommands;
export type QueryServerCommandManager = CommandManager<QueryServerCommands>;

View File

@@ -0,0 +1,77 @@
import { OWNER_REGEX, REPO_REGEX } from "../pure/helpers-pure";
/**
* Checks if a string is a valid GitHub NWO.
* @param identifier The GitHub NWO
* @returns
*/
export function isValidGitHubNwo(identifier: string): boolean {
return validGitHubNwoOrOwner(identifier, "nwo");
}
/**
* Checks if a string is a valid GitHub owner.
* @param identifier The GitHub owner
* @returns
*/
export function isValidGitHubOwner(identifier: string): boolean {
return validGitHubNwoOrOwner(identifier, "owner");
}
function validGitHubNwoOrOwner(
identifier: string,
kind: "owner" | "nwo",
): boolean {
return kind === "owner"
? OWNER_REGEX.test(identifier)
: REPO_REGEX.test(identifier);
}
/**
* Extracts an NWO from a GitHub URL.
* @param githubUrl The GitHub repository URL
* @return The corresponding NWO, or undefined if the URL is not valid
*/
export function getNwoFromGitHubUrl(githubUrl: string): string | undefined {
return getNwoOrOwnerFromGitHubUrl(githubUrl, "nwo");
}
/**
* Extracts an owner from a GitHub URL.
* @param githubUrl The GitHub repository URL
* @return The corresponding Owner, or undefined if the URL is not valid
*/
export function getOwnerFromGitHubUrl(githubUrl: string): string | undefined {
return getNwoOrOwnerFromGitHubUrl(githubUrl, "owner");
}
function getNwoOrOwnerFromGitHubUrl(
githubUrl: string,
kind: "owner" | "nwo",
): string | undefined {
try {
let paths: string[];
const urlElements = githubUrl.split("/");
if (
urlElements[0] === "github.com" ||
urlElements[0] === "www.github.com"
) {
paths = githubUrl.split("/").slice(1);
} else {
const uri = new URL(githubUrl);
if (uri.hostname !== "github.com" && uri.hostname !== "www.github.com") {
return;
}
paths = uri.pathname.split("/").filter((segment: string) => segment);
}
const owner = `${paths[0]}`;
if (kind === "owner") {
return owner ? owner : undefined;
}
const nwo = `${paths[0]}/${paths[1]}`;
return paths[1] ? nwo : undefined;
} catch (e) {
// Ignore the error here, since we catch failures at a higher level.
return;
}
}

View File

@@ -1,3 +1,4 @@
export * from "./logger";
export * from "./tee-logger";
export * from "./vscode/loggers";
export * from "./vscode/output-channel-logger";

View File

@@ -1,9 +1,6 @@
export interface LogOptions {
// If false, don't output a trailing newline for the log entry. Default true.
trailingNewline?: boolean;
// If specified, add this log entry to the log file at the specified location.
additionalLogLocation?: string;
}
export interface Logger {
@@ -25,11 +22,4 @@ export interface Logger {
* @param preserveFocus When `true` the channel will not take focus.
*/
show(preserveFocus?: boolean): void;
/**
* Remove the log at the specified location.
*
* @param location log to remove
*/
removeAdditionalLogLocation(location: string | undefined): void;
}

View File

@@ -0,0 +1,68 @@
import { appendFile, ensureFile } from "fs-extra";
import { isAbsolute } from "path";
import { getErrorMessage } from "../../pure/helpers-pure";
import { Logger, LogOptions } from "./logger";
/**
* An implementation of {@link Logger} that sends the output both to another {@link Logger}
* and to a file.
*
* The first time a message is written, an additional banner is written to the underlying logger
* pointing the user to the "side log" file.
*/
export class TeeLogger implements Logger {
private emittedRedirectMessage = false;
private error = false;
public constructor(
private readonly logger: Logger,
private readonly location: string,
) {
if (!isAbsolute(location)) {
throw new Error(
`Additional Log Location must be an absolute path: ${location}`,
);
}
}
async log(message: string, options = {} as LogOptions): Promise<void> {
if (!this.emittedRedirectMessage) {
this.emittedRedirectMessage = true;
const msg = `| Log being saved to ${this.location} |`;
const separator = new Array(msg.length).fill("-").join("");
await this.logger.log(separator);
await this.logger.log(msg);
await this.logger.log(separator);
}
if (!this.error) {
try {
const trailingNewline = options.trailingNewline ?? true;
await ensureFile(this.location);
await appendFile(
this.location,
message + (trailingNewline ? "\n" : ""),
{
encoding: "utf8",
},
);
} catch (e) {
// Write an error message to the primary log, and stop trying to write to the side log.
this.error = true;
const errorMessage = getErrorMessage(e);
await this.logger.log(
`Error writing to additional log file: ${errorMessage}`,
);
}
}
if (!this.error) {
await this.logger.log(message, options);
}
}
show(preserveFocus?: boolean): void {
this.logger.show(preserveFocus);
}
}

View File

@@ -1,6 +1,4 @@
import { window as Window, OutputChannel, Progress } from "vscode";
import { ensureFile, appendFile } from "fs-extra";
import { isAbsolute } from "path";
import { Logger, LogOptions } from "../logger";
import { DisposableObject } from "../../../pure/disposable-object";
@@ -9,10 +7,6 @@ import { DisposableObject } from "../../../pure/disposable-object";
*/
export class OutputChannelLogger extends DisposableObject implements Logger {
public readonly outputChannel: OutputChannel;
private readonly additionalLocations = new Map<
string,
AdditionalLogLocation
>();
isCustomLogDirectory: boolean;
constructor(title: string) {
@@ -32,27 +26,6 @@ export class OutputChannelLogger extends DisposableObject implements Logger {
} else {
this.outputChannel.append(message);
}
if (options.additionalLogLocation) {
if (!isAbsolute(options.additionalLogLocation)) {
throw new Error(
`Additional Log Location must be an absolute path: ${options.additionalLogLocation}`,
);
}
const logPath = options.additionalLogLocation;
let additional = this.additionalLocations.get(logPath);
if (!additional) {
const msg = `| Log being saved to ${logPath} |`;
const separator = new Array(msg.length).fill("-").join("");
this.outputChannel.appendLine(separator);
this.outputChannel.appendLine(msg);
this.outputChannel.appendLine(separator);
additional = new AdditionalLogLocation(logPath);
this.additionalLocations.set(logPath, additional);
}
await additional.log(message, options);
}
} catch (e) {
if (e instanceof Error && e.message === "Channel has been closed") {
// Output channel is closed logging to console instead
@@ -69,31 +42,6 @@ export class OutputChannelLogger extends DisposableObject implements Logger {
show(preserveFocus?: boolean): void {
this.outputChannel.show(preserveFocus);
}
removeAdditionalLogLocation(location: string | undefined): void {
if (location) {
this.additionalLocations.delete(location);
}
}
}
class AdditionalLogLocation {
constructor(private location: string) {}
async log(message: string, options = {} as LogOptions): Promise<void> {
if (options.trailingNewline === undefined) {
options.trailingNewline = true;
}
await ensureFile(this.location);
await appendFile(
this.location,
message + (options.trailingNewline ? "\n" : ""),
{
encoding: "utf8",
},
);
}
}
export type ProgressReporter = Progress<{ message: string }>;

View File

@@ -0,0 +1,44 @@
/**
* A memento represents a storage utility. It can store and retrieve
* values.
*
* It is an interface used by the VS Code API. We replicate it here
* to avoid the dependency to the VS Code API.
*/
export interface Memento {
/**
* Returns the stored keys.
*
* @return The stored keys.
*/
keys(): readonly string[];
/**
* Return a value.
*
* @param key A string.
* @return The stored value or `undefined`.
*/
get<T>(key: string): T | undefined;
/**
* Return a value.
*
* @param key A string.
* @param defaultValue A value that should be returned when there is no
* value (`undefined`) with the given key.
* @return The stored value or the defaultValue.
*/
get<T>(key: string, defaultValue: T): T;
/**
* Store a value. The value must be JSON-stringifyable.
*
* *Note* that using `undefined` as value removes the key from the underlying
* storage.
*
* @param key A string.
* @param value A value. MUST not contain cyclic references.
*/
update(key: string, value: any): Thenable<void>;
}

View File

@@ -0,0 +1,37 @@
export enum QueryLanguage {
CSharp = "csharp",
Cpp = "cpp",
Go = "go",
Java = "java",
Javascript = "javascript",
Python = "python",
Ruby = "ruby",
Swift = "swift",
}
export const PACKS_BY_QUERY_LANGUAGE = {
[QueryLanguage.Cpp]: ["codeql/cpp-queries"],
[QueryLanguage.CSharp]: [
"codeql/csharp-queries",
"codeql/csharp-solorigate-queries",
],
[QueryLanguage.Go]: ["codeql/go-queries"],
[QueryLanguage.Java]: ["codeql/java-queries"],
[QueryLanguage.Javascript]: [
"codeql/javascript-queries",
"codeql/javascript-experimental-atm-queries",
],
[QueryLanguage.Python]: ["codeql/python-queries"],
[QueryLanguage.Ruby]: ["codeql/ruby-queries"],
};
export const dbSchemeToLanguage = {
"semmlecode.javascript.dbscheme": "javascript",
"semmlecode.cpp.dbscheme": "cpp",
"semmlecode.dbscheme": "java",
"semmlecode.python.dbscheme": "python",
"semmlecode.csharp.dbscheme": "csharp",
"go.dbscheme": "go",
"ruby.dbscheme": "ruby",
"swift.dbscheme": "swift",
};

View File

@@ -1,13 +1,13 @@
/**
* Represents a result that can be either a value or some errors.
*/
export class ValueResult<TValue> {
export class ValueResult<TValue, TError> {
private constructor(
private readonly errorMsgs: string[],
private readonly errs: TError[],
private readonly val?: TValue,
) {}
public static ok<TValue>(value: TValue): ValueResult<TValue> {
public static ok<TValue, TError>(value: TValue): ValueResult<TValue, TError> {
if (value === undefined) {
throw new Error("Value must be set for successful result");
}
@@ -15,30 +15,30 @@ export class ValueResult<TValue> {
return new ValueResult([], value);
}
public static fail<TValue>(errorMsgs: string[]): ValueResult<TValue> {
if (errorMsgs.length === 0) {
throw new Error(
"At least one error message must be set for a failed result",
);
public static fail<TValue, TError>(
errors: TError[],
): ValueResult<TValue, TError> {
if (errors.length === 0) {
throw new Error("At least one error must be set for a failed result");
}
return new ValueResult<TValue>(errorMsgs, undefined);
return new ValueResult<TValue, TError>(errors, undefined);
}
public get isOk(): boolean {
return this.errorMsgs.length === 0;
return this.errs.length === 0;
}
public get isFailure(): boolean {
return this.errorMsgs.length > 0;
return this.errs.length > 0;
}
public get errors(): string[] {
if (!this.errorMsgs) {
public get errors(): TError[] {
if (!this.errs) {
throw new Error("Cannot get error for successful result");
}
return this.errorMsgs;
return this.errs;
}
public get value(): TValue {

View File

@@ -0,0 +1,35 @@
import { commands } from "vscode";
import { commandRunner, NoProgressTask } from "../../commandRunner";
import { CommandFunction, CommandManager } from "../../packages/commands";
import { OutputChannelLogger } from "../logging";
/**
* Create a command manager for VSCode, wrapping the commandRunner
* and vscode.executeCommand.
*/
export function createVSCodeCommandManager<
Commands extends Record<string, CommandFunction>,
>(outputLogger?: OutputChannelLogger): CommandManager<Commands> {
return new CommandManager((commandId, task: NoProgressTask) => {
return commandRunner(commandId, task, outputLogger);
}, wrapExecuteCommand);
}
/**
* wrapExecuteCommand wraps commands.executeCommand to satisfy that the
* type is a Promise. Type script does not seem to be smart enough
* to figure out that `ReturnType<Commands[CommandName]>` is actually
* a Promise, so we need to add a second layer of wrapping and unwrapping
* (The `Promise<Awaited<` part) to get the right types.
*/
async function wrapExecuteCommand<
Commands extends Record<string, CommandFunction>,
CommandName extends keyof Commands & string = keyof Commands & string,
>(
commandName: CommandName,
...args: Parameters<Commands[CommandName]>
): Promise<Awaited<ReturnType<Commands[CommandName]>>> {
return await commands.executeCommand<
Awaited<ReturnType<Commands[CommandName]>>
>(commandName, ...args);
}

View File

@@ -1,13 +1,27 @@
import * as vscode from "vscode";
import { VSCodeCredentials } from "../../authentication";
import { Disposable } from "../../pure/disposable-object";
import { App, AppMode } from "../app";
import { AppEventEmitter } from "../events";
import { extLogger, Logger, queryServerLogger } from "../logging";
import { Memento } from "../memento";
import { VSCodeAppEventEmitter } from "./events";
import { AppCommandManager, QueryServerCommandManager } from "../commands";
import { createVSCodeCommandManager } from "./commands";
export class ExtensionApp implements App {
public readonly credentials: VSCodeCredentials;
public readonly commands: AppCommandManager;
public readonly queryServerCommands: QueryServerCommandManager;
public constructor(
public readonly extensionContext: vscode.ExtensionContext,
) {}
) {
this.credentials = new VSCodeCredentials();
this.commands = createVSCodeCommandManager();
this.queryServerCommands = createVSCodeCommandManager(queryServerLogger);
extensionContext.subscriptions.push(this.commands);
}
public get extensionPath(): string {
return this.extensionContext.extensionPath;
@@ -21,6 +35,10 @@ export class ExtensionApp implements App {
return this.extensionContext.storageUri?.fsPath;
}
public get workspaceState(): Memento {
return this.extensionContext.workspaceState;
}
public get subscriptions(): Disposable[] {
return this.extensionContext.subscriptions;
}
@@ -36,11 +54,11 @@ export class ExtensionApp implements App {
}
}
public get logger(): Logger {
return extLogger;
}
public createEventEmitter<T>(): AppEventEmitter<T> {
return new VSCodeAppEventEmitter<T>();
}
public executeCommand(command: string, ...args: any): Thenable<void> {
return vscode.commands.executeCommand(command, args);
}
}

View File

@@ -7,7 +7,7 @@ import {
} from "../pure/interface-types";
import { Logger } from "../common";
import { CodeQLCliServer } from "../cli";
import { DatabaseManager } from "../databases";
import { DatabaseManager } from "../local-databases";
import { jumpToLocation } from "../interface-utils";
import {
transformBqrsResultSet,
@@ -16,9 +16,12 @@ import {
} from "../pure/bqrs-cli-types";
import resultsDiff from "./resultsDiff";
import { CompletedLocalQueryInfo } from "../query-results";
import { getErrorMessage } from "../pure/helpers-pure";
import { HistoryItemLabelProvider } from "../history-item-label-provider";
import { assertNever, getErrorMessage } from "../pure/helpers-pure";
import { HistoryItemLabelProvider } from "../query-history/history-item-label-provider";
import { AbstractWebview, WebviewPanelConfig } from "../abstract-webview";
import { telemetryListener } from "../telemetry";
import { redactableError } from "../pure/errors";
import { showAndLogExceptionWithTelemetry } from "../helpers";
interface ComparePair {
from: CompletedLocalQueryInfo;
@@ -118,6 +121,9 @@ export class CompareView extends AbstractWebview<
case "changeCompare":
await this.changeTable(msg.newResultSetName);
telemetryListener?.sendUIInteraction(
"compare-view-change-table-to-compare",
);
break;
case "viewSourceFile":
@@ -126,7 +132,25 @@ export class CompareView extends AbstractWebview<
case "openQuery":
await this.openQuery(msg.kind);
telemetryListener?.sendUIInteraction(
`compare-view-open-${msg.kind}-query`,
);
break;
case "telemetry":
telemetryListener?.sendUIInteraction(msg.action);
break;
case "unhandledError":
void showAndLogExceptionWithTelemetry(
redactableError(
msg.error,
)`Unhandled error in result comparison view: ${msg.error.message}`,
);
break;
default:
assertNever(msg);
}
}

View File

@@ -56,15 +56,6 @@ export class Setting {
.getConfiguration(this.parent.qualifiedName)
.update(this.name, value, target);
}
inspect<T>(): InspectionResult<T> | undefined {
if (this.parent === undefined) {
throw new Error("Cannot update the value of a root setting.");
}
return workspace
.getConfiguration(this.parent.qualifiedName)
.inspect(this.name);
}
}
export interface InspectionResult<T> {
@@ -146,6 +137,10 @@ const DEBUG_SETTING = new Setting("debug", RUNNING_QUERIES_SETTING);
const MAX_PATHS = new Setting("maxPaths", RUNNING_QUERIES_SETTING);
const RUNNING_TESTS_SETTING = new Setting("runningTests", ROOT_SETTING);
const RESULTS_DISPLAY_SETTING = new Setting("resultsDisplay", ROOT_SETTING);
const USE_EXTENSION_PACKS = new Setting(
"useExtensionPacks",
RUNNING_QUERIES_SETTING,
);
export const ADDITIONAL_TEST_ARGUMENTS_SETTING = new Setting(
"additionalTestArguments",
@@ -205,6 +200,7 @@ const CLI_SETTINGS = [
NUMBER_OF_TEST_THREADS_SETTING,
NUMBER_OF_THREADS_SETTING,
MAX_PATHS,
USE_EXTENSION_PACKS,
];
export interface CliConfig {
@@ -212,7 +208,9 @@ export interface CliConfig {
numberTestThreads: number;
numberThreads: number;
maxPaths: number;
useExtensionPacks: boolean;
onDidChangeConfiguration?: Event<void>;
setUseExtensionPacks: (useExtensionPacks: boolean) => Promise<void>;
}
export abstract class ConfigListener extends DisposableObject {
@@ -348,7 +346,7 @@ export class QueryServerConfigListener
if (memory === null) {
return undefined;
}
if (memory == 0 || typeof memory !== "number") {
if (memory === 0 || typeof memory !== "number") {
void extLogger.log(
`Ignoring value '${memory}' for setting ${MEMORY_SETTING.qualifiedName}`,
);
@@ -409,6 +407,19 @@ export class CliConfigListener extends ConfigListener implements CliConfig {
return MAX_PATHS.getValue<number>();
}
public get useExtensionPacks(): boolean {
// currently, we are restricting the values of this setting to 'all' or 'none'.
return USE_EXTENSION_PACKS.getValue() === "all";
}
// Exposed for testing only
public async setUseExtensionPacks(newUseExtensionPacks: boolean) {
await USE_EXTENSION_PACKS.updateValue(
newUseExtensionPacks ? "all" : "none",
ConfigurationTarget.Global,
);
}
protected handleDidChangeConfiguration(e: ConfigurationChangeEvent): void {
this.handleDidChangeConfigurationForRelevantSettings(CLI_SETTINGS, e);
}
@@ -476,49 +487,7 @@ export const NO_CACHE_AST_VIEWER = new Setting(
);
// Settings for variant analysis
const REMOTE_QUERIES_SETTING = new Setting("variantAnalysis", ROOT_SETTING);
/**
* Lists of GitHub repositories that you want to query remotely via the "Run Variant Analysis" command.
* Note: This command is only available for internal users.
*
* This setting should be a JSON object where each key is a user-specified name (string),
* and the value is an array of GitHub repositories (of the form `<owner>/<repo>`).
*/
const REMOTE_REPO_LISTS = new Setting(
"repositoryLists",
REMOTE_QUERIES_SETTING,
);
export function getRemoteRepositoryLists():
| Record<string, string[]>
| undefined {
return REMOTE_REPO_LISTS.getValue<Record<string, string[]>>() || undefined;
}
export async function setRemoteRepositoryLists(
lists: Record<string, string[]> | undefined,
) {
await REMOTE_REPO_LISTS.updateValue(lists, ConfigurationTarget.Global);
}
/**
* Path to a file that contains lists of GitHub repositories that you want to query remotely via
* the "Run Variant Analysis" command.
* Note: This command is only available for internal users.
*
* This setting should be a path to a JSON file that contains a JSON object where each key is a
* user-specified name (string), and the value is an array of GitHub repositories
* (of the form `<owner>/<repo>`).
*/
const REPO_LISTS_PATH = new Setting(
"repositoryListsPath",
REMOTE_QUERIES_SETTING,
);
export function getRemoteRepositoryListsPath(): string | undefined {
return REPO_LISTS_PATH.getValue<string>() || undefined;
}
const VARIANT_ANALYSIS_SETTING = new Setting("variantAnalysis", ROOT_SETTING);
/**
* The name of the "controller" repository that you want to use with the "Run Variant Analysis" command.
@@ -528,7 +497,7 @@ export function getRemoteRepositoryListsPath(): string | undefined {
*/
const REMOTE_CONTROLLER_REPO = new Setting(
"controllerRepo",
REMOTE_QUERIES_SETTING,
VARIANT_ANALYSIS_SETTING,
);
export function getRemoteControllerRepo(): string | undefined {
@@ -539,12 +508,33 @@ export async function setRemoteControllerRepo(repo: string | undefined) {
await REMOTE_CONTROLLER_REPO.updateValue(repo, ConfigurationTarget.Global);
}
export interface VariantAnalysisConfig {
controllerRepo: string | undefined;
onDidChangeConfiguration?: Event<void>;
}
export class VariantAnalysisConfigListener
extends ConfigListener
implements VariantAnalysisConfig
{
protected handleDidChangeConfiguration(e: ConfigurationChangeEvent): void {
this.handleDidChangeConfigurationForRelevantSettings(
[VARIANT_ANALYSIS_SETTING],
e,
);
}
public get controllerRepo(): string | undefined {
return getRemoteControllerRepo();
}
}
/**
* The branch of "github/codeql-variant-analysis-action" to use with the "Run Variant Analysis" command.
* Default value is "main".
* Note: This command is only available for internal users.
*/
const ACTION_BRANCH = new Setting("actionBranch", REMOTE_QUERIES_SETTING);
const ACTION_BRANCH = new Setting("actionBranch", VARIANT_ANALYSIS_SETTING);
export function getActionBranch(): string {
return ACTION_BRANCH.getValue<string>() || "main";
@@ -558,19 +548,6 @@ export function isVariantAnalysisLiveResultsEnabled(): boolean {
return true;
}
/**
* A flag indicating whether to use the new query run experience which involves
* using a new database panel.
*/
const NEW_QUERY_RUN_EXPERIENCE = new Setting(
"newQueryRunExperience",
ROOT_SETTING,
);
export function isNewQueryRunExperienceEnabled(): boolean {
return !!NEW_QUERY_RUN_EXPERIENCE.getValue<boolean>();
}
// Settings for mocking the GitHub API.
const MOCK_GH_API_SERVER = new Setting("mockGitHubApiServer", ROOT_SETTING);
@@ -618,3 +595,16 @@ export class MockGitHubApiConfigListener
export function getMockGitHubApiServerScenariosPath(): string | undefined {
return MOCK_GH_API_SERVER_SCENARIOS_PATH.getValue<string>();
}
/**
* Enables features that are specific to the codespaces-codeql template workspace from
* https://github.com/github/codespaces-codeql.
*/
export const CODESPACES_TEMPLATE = new Setting(
"codespacesTemplate",
ROOT_SETTING,
);
export function isCodespacesTemplate() {
return !!CODESPACES_TEMPLATE.getValue<boolean>();
}

View File

@@ -1,6 +1,6 @@
import { CodeQLCliServer } from "../cli";
import { DecodedBqrsChunk, BqrsId, EntityValue } from "../pure/bqrs-cli-types";
import { DatabaseItem } from "../databases";
import { DatabaseItem } from "../local-databases";
import { ChildAstItem, AstItem } from "../astViewer";
import fileRangeFromURI from "./fileRangeFromURI";
import { Uri } from "vscode";

View File

@@ -2,7 +2,7 @@ import * as vscode from "vscode";
import { UrlValue, LineColumnLocation } from "../pure/bqrs-cli-types";
import { isEmptyPath } from "../pure/bqrs-utils";
import { DatabaseItem } from "../databases";
import { DatabaseItem } from "../local-databases";
export default function fileRangeFromURI(
uri: UrlValue | undefined,

View File

@@ -9,9 +9,9 @@ import {
ResultSetSchema,
} from "../pure/bqrs-cli-types";
import { CodeQLCliServer } from "../cli";
import { DatabaseManager, DatabaseItem } from "../databases";
import { DatabaseManager, DatabaseItem } from "../local-databases";
import fileRangeFromURI from "./fileRangeFromURI";
import { ProgressCallback } from "../commandRunner";
import { ProgressCallback } from "../progress";
import { KeyType } from "./keyType";
import {
qlpackOfDatabase,
@@ -128,9 +128,9 @@ function createTemplates(path: string): Record<string, string> {
function isValidSelect(selectInfo: ResultSetSchema | undefined) {
return (
selectInfo &&
selectInfo.columns.length == 3 &&
selectInfo.columns[0].kind == ColumnKindCode.ENTITY &&
selectInfo.columns[1].kind == ColumnKindCode.ENTITY &&
selectInfo.columns[2].kind == ColumnKindCode.STRING
selectInfo.columns.length === 3 &&
selectInfo.columns[0].kind === ColumnKindCode.ENTITY &&
selectInfo.columns[1].kind === ColumnKindCode.ENTITY &&
selectInfo.columns[2].kind === ColumnKindCode.STRING
);
}

View File

@@ -7,17 +7,19 @@ import {
getPrimaryDbscheme,
getQlPackForDbscheme,
getOnDiskWorkspaceFolders,
showAndLogErrorMessage,
QlPacksForLanguage,
showAndLogExceptionWithTelemetry,
} from "../helpers";
import { KeyType, kindOfKeyType, nameOfKeyType, tagOfKeyType } from "./keyType";
import { CodeQLCliServer } from "../cli";
import { DatabaseItem } from "../databases";
import { DatabaseItem } from "../local-databases";
import { extLogger } from "../common";
import { createInitialQueryInfo } from "../run-queries-shared";
import { CancellationToken, Uri } from "vscode";
import { ProgressCallback } from "../commandRunner";
import { ProgressCallback } from "../progress";
import { QueryRunner } from "../queryRunner";
import { redactableError } from "../pure/errors";
import { QLPACK_FILENAMES } from "../pure/ql";
export async function qlpackOfDatabase(
cli: CodeQLCliServer,
@@ -74,39 +76,12 @@ export async function resolveQueries(
qlpacks: QlPacksForLanguage,
keyType: KeyType,
): Promise<string[]> {
const cliCanHandleLibraryPack =
await cli.cliConstraints.supportsAllowLibraryPacksInResolveQueries();
const packsToSearch: string[] = [];
let blameCli: boolean;
if (cliCanHandleLibraryPack) {
// The CLI can handle both library packs and query packs, so search both packs in order.
packsToSearch.push(qlpacks.dbschemePack);
if (qlpacks.queryPack !== undefined) {
packsToSearch.push(qlpacks.queryPack);
}
// If we don't find the query, it's because it's not there, not because the CLI was unable to
// search the pack.
blameCli = false;
} else {
// Older CLIs can't handle `codeql resolve queries` with a suite that references a library pack.
if (qlpacks.dbschemePackIsLibraryPack) {
if (qlpacks.queryPack !== undefined) {
// Just search the query pack, because some older library/query releases still had the
// contextual queries in the query pack.
packsToSearch.push(qlpacks.queryPack);
}
// If we don't find it, it's because the CLI was unable to search the library pack that
// actually contains the query. Blame any failure on the CLI, not the packs.
blameCli = true;
} else {
// We have an old CLI, but the dbscheme pack is old enough that it's still a unified pack with
// both libraries and queries. Just search that pack.
packsToSearch.push(qlpacks.dbschemePack);
// Any CLI should be able to search the single query pack, so if we don't find it, it's
// because the language doesn't support it.
blameCli = false;
}
// The CLI can handle both library packs and query packs, so search both packs in order.
packsToSearch.push(qlpacks.dbschemePack);
if (qlpacks.queryPack !== undefined) {
packsToSearch.push(qlpacks.queryPack);
}
const queries = await resolveQueriesFromPacks(cli, packsToSearch, keyType);
@@ -115,26 +90,16 @@ export async function resolveQueries(
}
// No queries found. Determine the correct error message for the various scenarios.
const errorMessage = blameCli
? `Your current version of the CodeQL CLI, '${
(await cli.getVersion()).version
}', \
is unable to use contextual queries from recent versions of the standard CodeQL libraries. \
Please upgrade to the latest version of the CodeQL CLI.`
: `No ${nameOfKeyType(keyType)} queries (tagged "${tagOfKeyType(
keyType,
)}") could be found in the current library path. \
Try upgrading the CodeQL libraries. If that doesn't work, then ${nameOfKeyType(
keyType,
)} queries are not yet available \
for this language.`;
const keyTypeName = nameOfKeyType(keyType);
const keyTypeTag = tagOfKeyType(keyType);
const joinedPacksToSearch = packsToSearch.join(", ");
const error = redactableError`No ${keyTypeName} queries (tagged "${keyTypeTag}") could be found in the \
current library path (tried searching the following packs: ${joinedPacksToSearch}). \
Try upgrading the CodeQL libraries. If that doesn't work, then ${keyTypeName} queries are not yet available \
for this language.`;
void showAndLogErrorMessage(errorMessage);
throw new Error(
`Couldn't find any queries tagged ${tagOfKeyType(
keyType,
)} in any of the following packs: ${packsToSearch.join(", ")}.`,
);
void showAndLogExceptionWithTelemetry(error);
throw error;
}
async function resolveContextualQuery(
@@ -149,7 +114,7 @@ async function resolveContextualQuery(
// Work out the enclosing pack.
const packContents = await cli.packPacklist(query, false);
const packFilePath = packContents.find((p) =>
["codeql-pack.yml", "qlpack.yml"].includes(basename(p)),
QLPACK_FILENAMES.includes(basename(p)),
);
if (packFilePath === undefined) {
// Should not happen; we already resolved this query.

View File

@@ -4,7 +4,6 @@ import {
Location,
LocationLink,
Position,
ProgressLocation,
ReferenceContext,
ReferenceProvider,
TextDocument,
@@ -17,9 +16,9 @@ import {
zipArchiveScheme,
} from "../archive-filesystem-provider";
import { CodeQLCliServer } from "../cli";
import { DatabaseManager } from "../databases";
import { DatabaseManager } from "../local-databases";
import { CachedOperation } from "../helpers";
import { ProgressCallback, withProgress } from "../commandRunner";
import { ProgressCallback, withProgress } from "../progress";
import AstBuilder from "./astBuilder";
import { KeyType } from "./keyType";
import {
@@ -73,11 +72,6 @@ export class TemplateQueryDefinitionProvider implements DefinitionProvider {
private async getDefinitions(uriString: string): Promise<LocationLink[]> {
return withProgress(
{
location: ProgressLocation.Notification,
cancellable: true,
title: "Finding definitions",
},
async (progress, token) => {
return getLocationsForUriString(
this.cli,
@@ -91,6 +85,10 @@ export class TemplateQueryDefinitionProvider implements DefinitionProvider {
(src, _dest) => src === uriString,
);
},
{
cancellable: true,
title: "Finding definitions",
},
);
}
}
@@ -136,11 +134,6 @@ export class TemplateQueryReferenceProvider implements ReferenceProvider {
private async getReferences(uriString: string): Promise<FullLocationLink[]> {
return withProgress(
{
location: ProgressLocation.Notification,
cancellable: true,
title: "Finding references",
},
async (progress, token) => {
return getLocationsForUriString(
this.cli,
@@ -154,6 +147,10 @@ export class TemplateQueryReferenceProvider implements ReferenceProvider {
(src, _dest) => src === uriString,
);
},
{
cancellable: true,
title: "Finding references",
},
);
}
}

View File

@@ -16,12 +16,16 @@ import { basename, join } from "path";
import * as Octokit from "@octokit/rest";
import { retry } from "@octokit/plugin-retry";
import { DatabaseManager, DatabaseItem } from "./databases";
import { DatabaseManager, DatabaseItem } from "./local-databases";
import { showAndLogInformationMessage, tmpDir } from "./helpers";
import { reportStreamProgress, ProgressCallback } from "./commandRunner";
import { reportStreamProgress, ProgressCallback } from "./progress";
import { extLogger } from "./common";
import { Credentials } from "./authentication";
import { REPO_REGEX, getErrorMessage } from "./pure/helpers-pure";
import { getErrorMessage } from "./pure/helpers-pure";
import {
getNwoFromGitHubUrl,
isValidGitHubNwo,
} from "./common/github-url-identifier-helper";
import { Credentials } from "./common/authentication";
/**
* Prompts a user to fetch a database from a remote location. Database is assumed to be an archive file.
@@ -96,19 +100,16 @@ export async function promptImportGithubDatabase(
return;
}
if (!looksLikeGithubRepo(githubRepo)) {
const nwo = getNwoFromGitHubUrl(githubRepo) || githubRepo;
if (!isValidGitHubNwo(nwo)) {
throw new Error(`Invalid GitHub repository: ${githubRepo}`);
}
const octokit = credentials
? await credentials.getOctokit(true)
? await credentials.getOctokit()
: new Octokit.Octokit({ retry });
const result = await convertGithubNwoToDatabaseUrl(
githubRepo,
octokit,
progress,
);
const result = await convertGithubNwoToDatabaseUrl(nwo, octokit, progress);
if (!result) {
return;
}
@@ -149,74 +150,6 @@ export async function promptImportGithubDatabase(
return;
}
/**
* Prompts a user to fetch a database from lgtm.
* User enters a project url and then the user is asked which language
* to download (if there is more than one)
*
* @param databaseManager the DatabaseManager
* @param storagePath where to store the unzipped database.
*/
export async function promptImportLgtmDatabase(
databaseManager: DatabaseManager,
storagePath: string,
progress: ProgressCallback,
token: CancellationToken,
cli?: CodeQLCliServer,
): Promise<DatabaseItem | undefined> {
progress({
message: "Choose project",
step: 1,
maxStep: 2,
});
const lgtmUrl = await window.showInputBox({
prompt:
"Enter the project slug or URL on LGTM (e.g., g/github/codeql or https://lgtm.com/projects/g/github/codeql)",
});
if (!lgtmUrl) {
return;
}
if (looksLikeLgtmUrl(lgtmUrl)) {
const databaseUrl = await convertLgtmUrlToDatabaseUrl(lgtmUrl, progress);
if (databaseUrl) {
const item = await databaseArchiveFetcher(
databaseUrl,
{},
databaseManager,
storagePath,
undefined,
progress,
token,
cli,
);
if (item) {
await commands.executeCommand("codeQLDatabases.focus");
void showAndLogInformationMessage(
"Database downloaded and imported successfully.",
);
}
return item;
}
} else {
throw new Error(`Invalid LGTM URL: ${lgtmUrl}`);
}
return;
}
export async function retrieveCanonicalRepoName(lgtmUrl: string) {
const givenRepoName = extractProjectSlug(lgtmUrl);
const response = await checkForFailingResponse(
await fetch(`https://api.github.com/repos/${givenRepoName}`),
"Failed to locate the repository on github",
);
const repo = await response.json();
if (!repo || !repo.full_name) {
return;
}
return repo.full_name;
}
/**
* Imports a database from a local archive.
*
@@ -388,7 +321,7 @@ async function readAndUnzip(
step: 9,
message: `Unzipping into ${basename(unzipPath)}`,
});
if (cli && (await cli.cliConstraints.supportsDatabaseUnbundle())) {
if (cli) {
// Use the `database unbundle` command if the installed cli version supports it
await cli.databaseUnbundle(zipFile, unzipPath);
} else {
@@ -509,57 +442,8 @@ export async function findDirWithFile(
return;
}
/**
* The URL pattern is https://github.com/{owner}/{name}/{subpages}.
*
* This function accepts any URL that matches the pattern above. It also accepts just the
* name with owner (NWO): `<owner>/<repo>`.
*
* @param githubRepo The GitHub repository URL or NWO
*
* @return true if this looks like a valid GitHub repository URL or NWO
*/
export function looksLikeGithubRepo(
githubRepo: string | undefined,
): githubRepo is string {
if (!githubRepo) {
return false;
}
if (REPO_REGEX.test(githubRepo) || convertGitHubUrlToNwo(githubRepo)) {
return true;
}
return false;
}
/**
* Converts a GitHub repository URL to the corresponding NWO.
* @param githubUrl The GitHub repository URL
* @return The corresponding NWO, or undefined if the URL is not valid
*/
function convertGitHubUrlToNwo(githubUrl: string): string | undefined {
try {
const uri = Uri.parse(githubUrl, true);
if (uri.scheme !== "https") {
return;
}
if (uri.authority !== "github.com" && uri.authority !== "www.github.com") {
return;
}
const paths = uri.path.split("/").filter((segment: string) => segment);
const nwo = `${paths[0]}/${paths[1]}`;
if (REPO_REGEX.test(nwo)) {
return nwo;
}
return;
} catch (e) {
// Ignore the error here, since we catch failures at a higher level.
// In particular: returning undefined leads to an error in 'promptImportGithubDatabase'.
return;
}
}
export async function convertGithubNwoToDatabaseUrl(
githubRepo: string,
nwo: string,
octokit: Octokit.Octokit,
progress: ProgressCallback,
): Promise<
@@ -571,7 +455,6 @@ export async function convertGithubNwoToDatabaseUrl(
| undefined
> {
try {
const nwo = convertGitHubUrlToNwo(githubRepo) || githubRepo;
const [owner, repo] = nwo.split("/");
const response = await octokit.request(
@@ -593,131 +476,10 @@ export async function convertGithubNwoToDatabaseUrl(
};
} catch (e) {
void extLogger.log(`Error: ${getErrorMessage(e)}`);
throw new Error(`Unable to get database for '${githubRepo}'`);
throw new Error(`Unable to get database for '${nwo}'`);
}
}
/**
* The URL pattern is https://lgtm.com/projects/{provider}/{org}/{name}/{irrelevant-subpages}.
* There are several possibilities for the provider: in addition to GitHub.com (g),
* LGTM currently hosts projects from Bitbucket (b), GitLab (gl) and plain git (git).
*
* This function accepts any url that matches the pattern above. It also accepts the
* raw project slug, e.g., `g/myorg/myproject`
*
* After the `{provider}/{org}/{name}` path components, there may be the components
* related to sub pages.
*
* @param lgtmUrl The URL to the lgtm project
*
* @return true if this looks like an LGTM project url
*/
// exported for testing
export function looksLikeLgtmUrl(
lgtmUrl: string | undefined,
): lgtmUrl is string {
if (!lgtmUrl) {
return false;
}
if (convertRawLgtmSlug(lgtmUrl)) {
return true;
}
try {
const uri = Uri.parse(lgtmUrl, true);
if (uri.scheme !== "https") {
return false;
}
if (uri.authority !== "lgtm.com" && uri.authority !== "www.lgtm.com") {
return false;
}
const paths = uri.path.split("/").filter((segment: string) => segment);
return paths.length >= 4 && paths[0] === "projects";
} catch (e) {
return false;
}
}
function convertRawLgtmSlug(maybeSlug: string): string | undefined {
if (!maybeSlug) {
return;
}
const segments = maybeSlug.split("/");
const providers = ["g", "gl", "b", "git"];
if (segments.length === 3 && providers.includes(segments[0])) {
return `https://lgtm.com/projects/${maybeSlug}`;
}
return;
}
function extractProjectSlug(lgtmUrl: string): string | undefined {
// Only matches the '/g/' provider (github)
const re = new RegExp("https://lgtm.com/projects/g/(.*[^/])");
const match = lgtmUrl.match(re);
if (!match) {
return;
}
return match[1];
}
// exported for testing
export async function convertLgtmUrlToDatabaseUrl(
lgtmUrl: string,
progress: ProgressCallback,
) {
try {
lgtmUrl = convertRawLgtmSlug(lgtmUrl) || lgtmUrl;
let projectJson = await downloadLgtmProjectMetadata(lgtmUrl);
if (projectJson.code === 404) {
// fallback check for github repositories with same name but different case
// will fail for other providers
let canonicalName = await retrieveCanonicalRepoName(lgtmUrl);
if (!canonicalName) {
throw new Error(`Project was not found at ${lgtmUrl}.`);
}
canonicalName = convertRawLgtmSlug(`g/${canonicalName}`);
projectJson = await downloadLgtmProjectMetadata(canonicalName);
if (projectJson.code === 404) {
throw new Error("Failed to download project from LGTM.");
}
}
const languages =
projectJson?.languages?.map(
(lang: { language: string }) => lang.language,
) || [];
const language = await promptForLanguage(languages, progress);
if (!language) {
return;
}
return `https://lgtm.com/${[
"api",
"v1.0",
"snapshots",
projectJson.id,
language,
].join("/")}`;
} catch (e) {
void extLogger.log(`Error: ${getErrorMessage(e)}`);
throw new Error(`Invalid LGTM URL: ${lgtmUrl}`);
}
}
async function downloadLgtmProjectMetadata(lgtmUrl: string): Promise<any> {
const uri = Uri.parse(lgtmUrl, true);
const paths = ["api", "v1.0"]
.concat(uri.path.split("/").filter((segment: string) => segment))
.slice(0, 6);
const projectUrl = `https://lgtm.com/${paths.join("/")}`;
const projectResponse = await fetch(projectUrl);
return projectResponse.json();
}
async function promptForLanguage(
languages: string[],
progress: ProgressCallback,

View File

@@ -1,3 +1,3 @@
### Databases
This folder contains code for the new experimental databases panel and new query run experience.
This folder contains tests for the variant analysis repository panel.

View File

@@ -1,19 +1,43 @@
import { pathExists, writeJSON, readJSON, readJSONSync } from "fs-extra";
import { pathExists, outputJSON, readJSON, readJSONSync } from "fs-extra";
import { join } from "path";
import {
clearLocalDbConfig,
cloneDbConfig,
DbConfig,
ExpandedDbItem,
initializeLocalDbConfig,
removeLocalDb,
removeLocalList,
removeRemoteList,
removeRemoteOwner,
removeRemoteRepo,
renameLocalDb,
renameLocalList,
renameRemoteList,
SelectedDbItem,
DB_CONFIG_VERSION,
SelectedDbItemKind,
} from "./db-config";
import * as chokidar from "chokidar";
import { DisposableObject, DisposeHandler } from "../../pure/disposable-object";
import { DbConfigValidator } from "./db-config-validator";
import { ValueResult } from "../../common/value-result";
import { App } from "../../common/app";
import { AppEvent, AppEventEmitter } from "../../common/events";
import {
DbConfigValidationError,
DbConfigValidationErrorKind,
} from "../db-validation-errors";
import { ValueResult } from "../../common/value-result";
import {
LocalDatabaseDbItem,
LocalListDbItem,
RemoteUserDefinedListDbItem,
DbItem,
DbItemKind,
} from "../db-item";
export class DbConfigStore extends DisposableObject {
public static readonly databaseConfigFileName = "databases.json";
public readonly onDidChangeConfig: AppEvent<void>;
private readonly onDidChangeConfigEventEmitter: AppEventEmitter<void>;
@@ -21,14 +45,17 @@ export class DbConfigStore extends DisposableObject {
private readonly configValidator: DbConfigValidator;
private config: DbConfig | undefined;
private configErrors: string[];
private configErrors: DbConfigValidationError[];
private configWatcher: chokidar.FSWatcher | undefined;
public constructor(app: App) {
public constructor(
private readonly app: App,
private readonly shouldWatchConfig = true,
) {
super();
const storagePath = app.workspaceStoragePath || app.globalStoragePath;
this.configPath = join(storagePath, "workspace-databases.json");
this.configPath = join(storagePath, DbConfigStore.databaseConfigFileName);
this.config = this.createEmptyConfig();
this.configErrors = [];
@@ -40,7 +67,9 @@ export class DbConfigStore extends DisposableObject {
public async initialize(): Promise<void> {
await this.loadConfig();
this.watchConfig();
if (this.shouldWatchConfig) {
this.watchConfig();
}
}
public dispose(disposeHandler?: DisposeHandler): void {
@@ -48,7 +77,7 @@ export class DbConfigStore extends DisposableObject {
this.configWatcher?.unwatch(this.configPath);
}
public getConfig(): ValueResult<DbConfig> {
public getConfig(): ValueResult<DbConfig, DbConfigValidationError> {
if (this.config) {
// Clone the config so that it's not modified outside of this class.
return ValueResult.ok(cloneDbConfig(this.config));
@@ -69,7 +98,7 @@ export class DbConfigStore extends DisposableObject {
throw Error("Cannot select database item if config is not loaded");
}
const config: DbConfig = {
const config = {
...this.config,
selected: dbItem,
};
@@ -77,46 +106,269 @@ export class DbConfigStore extends DisposableObject {
await this.writeConfig(config);
}
public async updateExpandedState(expandedItems: ExpandedDbItem[]) {
public async removeDbItem(dbItem: DbItem): Promise<void> {
if (!this.config) {
throw Error("Cannot update expansion state if config is not loaded");
throw Error("Cannot remove item if config is not loaded");
}
const config: DbConfig = {
...this.config,
expanded: expandedItems,
};
let config: DbConfig;
switch (dbItem.kind) {
case DbItemKind.LocalList:
config = removeLocalList(this.config, dbItem.listName);
break;
case DbItemKind.RemoteUserDefinedList:
config = removeRemoteList(this.config, dbItem.listName);
break;
case DbItemKind.LocalDatabase:
// When we start using local databases these need to be removed from disk as well.
config = removeLocalDb(
this.config,
dbItem.databaseName,
dbItem.parentListName,
);
break;
case DbItemKind.RemoteRepo:
config = removeRemoteRepo(
this.config,
dbItem.repoFullName,
dbItem.parentListName,
);
break;
case DbItemKind.RemoteOwner:
config = removeRemoteOwner(this.config, dbItem.ownerName);
break;
default:
throw Error(`Type '${dbItem.kind}' cannot be removed`);
}
await this.writeConfig(config);
}
public async addRemoteRepo(
repoNwo: string,
parentList?: string,
): Promise<void> {
if (!this.config) {
throw Error("Cannot add variant analysis repo if config is not loaded");
}
if (repoNwo === "") {
throw Error("Repository name cannot be empty");
}
if (this.doesRemoteDbExist(repoNwo, parentList)) {
throw Error(
`A variant analysis repository with the name '${repoNwo}' already exists`,
);
}
const config = cloneDbConfig(this.config);
if (parentList) {
const parent = config.databases.variantAnalysis.repositoryLists.find(
(list) => list.name === parentList,
);
if (!parent) {
throw Error(`Cannot find parent list '${parentList}'`);
} else {
parent.repositories.push(repoNwo);
}
} else {
config.databases.variantAnalysis.repositories.push(repoNwo);
}
await this.writeConfig(config);
}
public async addRemoteOwner(owner: string): Promise<void> {
if (!this.config) {
throw Error("Cannot add owner if config is not loaded");
}
if (owner === "") {
throw Error("Owner name cannot be empty");
}
if (this.doesRemoteOwnerExist(owner)) {
throw Error(`An owner with the name '${owner}' already exists`);
}
const config = cloneDbConfig(this.config);
config.databases.variantAnalysis.owners.push(owner);
await this.writeConfig(config);
}
public async addLocalList(listName: string): Promise<void> {
if (!this.config) {
throw Error("Cannot add local list if config is not loaded");
}
this.validateLocalListName(listName);
const config = cloneDbConfig(this.config);
config.databases.local.lists.push({
name: listName,
databases: [],
});
await this.writeConfig(config);
}
public async addRemoteList(listName: string): Promise<void> {
if (!this.config) {
throw Error("Cannot add remote list if config is not loaded");
throw Error("Cannot add variant analysis list if config is not loaded");
}
const config: DbConfig = cloneDbConfig(this.config);
config.databases.remote.repositoryLists.push({
this.validateRemoteListName(listName);
const config = cloneDbConfig(this.config);
config.databases.variantAnalysis.repositoryLists.push({
name: listName,
repositories: [],
});
// TODO: validate that the name doesn't already exist
await this.writeConfig(config);
}
public async renameLocalList(
currentDbItem: LocalListDbItem,
newName: string,
) {
if (!this.config) {
throw Error("Cannot rename local list if config is not loaded");
}
this.validateLocalListName(newName);
const updatedConfig = renameLocalList(
this.config,
currentDbItem.listName,
newName,
);
await this.writeConfig(updatedConfig);
}
public async renameRemoteList(
currentDbItem: RemoteUserDefinedListDbItem,
newName: string,
) {
if (!this.config) {
throw Error(
"Cannot rename variant analysis list if config is not loaded",
);
}
this.validateRemoteListName(newName);
const updatedConfig = renameRemoteList(
this.config,
currentDbItem.listName,
newName,
);
await this.writeConfig(updatedConfig);
}
public async renameLocalDb(
currentDbItem: LocalDatabaseDbItem,
newName: string,
parentListName?: string,
): Promise<void> {
if (!this.config) {
throw Error("Cannot rename local db if config is not loaded");
}
this.validateLocalDbName(newName);
const updatedConfig = renameLocalDb(
this.config,
currentDbItem.databaseName,
newName,
parentListName,
);
await this.writeConfig(updatedConfig);
}
public doesRemoteListExist(listName: string): boolean {
if (!this.config) {
throw Error(
"Cannot check variant analysis list existence if config is not loaded",
);
}
return this.config.databases.variantAnalysis.repositoryLists.some(
(l) => l.name === listName,
);
}
public doesLocalListExist(listName: string): boolean {
if (!this.config) {
throw Error("Cannot check local list existence if config is not loaded");
}
return this.config.databases.local.lists.some((l) => l.name === listName);
}
public doesLocalDbExist(dbName: string, listName?: string): boolean {
if (!this.config) {
throw Error(
"Cannot check variant analysis repository existence if config is not loaded",
);
}
if (listName) {
return this.config.databases.local.lists.some(
(l) =>
l.name === listName && l.databases.some((d) => d.name === dbName),
);
}
return this.config.databases.local.databases.some((d) => d.name === dbName);
}
public doesRemoteDbExist(dbName: string, listName?: string): boolean {
if (!this.config) {
throw Error(
"Cannot check variant analysis repository existence if config is not loaded",
);
}
if (listName) {
return this.config.databases.variantAnalysis.repositoryLists.some(
(l) => l.name === listName && l.repositories.includes(dbName),
);
}
return this.config.databases.variantAnalysis.repositories.includes(dbName);
}
public doesRemoteOwnerExist(owner: string): boolean {
if (!this.config) {
throw Error("Cannot check owner existence if config is not loaded");
}
return this.config.databases.variantAnalysis.owners.includes(owner);
}
private async writeConfig(config: DbConfig): Promise<void> {
await writeJSON(this.configPath, config, {
clearLocalDbConfig(config);
await outputJSON(this.configPath, config, {
spaces: 2,
});
}
private async loadConfig(): Promise<void> {
if (!(await pathExists(this.configPath))) {
void this.app.logger.log(
`Creating new database config file at ${this.configPath}`,
);
await this.writeConfig(this.createEmptyConfig());
}
await this.readConfig();
void this.app.logger.log(`Database config loaded from ${this.configPath}`);
}
private async readConfig(): Promise<void> {
@@ -124,14 +376,34 @@ export class DbConfigStore extends DisposableObject {
try {
newConfig = await readJSON(this.configPath);
} catch (e) {
this.configErrors = [`Failed to read config file: ${this.configPath}`];
this.configErrors = [
{
kind: DbConfigValidationErrorKind.InvalidJson,
message: `Failed to read config file: ${this.configPath}`,
},
];
}
if (newConfig) {
initializeLocalDbConfig(newConfig);
this.configErrors = this.configValidator.validate(newConfig);
}
this.config = this.configErrors.length === 0 ? newConfig : undefined;
if (this.configErrors.length === 0) {
this.config = newConfig;
await this.app.commands.execute(
"setContext",
"codeQLVariantAnalysisRepositories.configError",
false,
);
} else {
this.config = undefined;
await this.app.commands.execute(
"setContext",
"codeQLVariantAnalysisRepositories.configError",
true,
);
}
}
private readConfigSync(): void {
@@ -139,28 +411,59 @@ export class DbConfigStore extends DisposableObject {
try {
newConfig = readJSONSync(this.configPath);
} catch (e) {
this.configErrors = [`Failed to read config file: ${this.configPath}`];
this.configErrors = [
{
kind: DbConfigValidationErrorKind.InvalidJson,
message: `Failed to read config file: ${this.configPath}`,
},
];
}
if (newConfig) {
initializeLocalDbConfig(newConfig);
this.configErrors = this.configValidator.validate(newConfig);
}
this.config = this.configErrors.length === 0 ? newConfig : undefined;
if (this.configErrors.length === 0) {
this.config = newConfig;
void this.app.commands.execute(
"setContext",
"codeQLVariantAnalysisRepositories.configError",
false,
);
} else {
this.config = undefined;
void this.app.commands.execute(
"setContext",
"codeQLVariantAnalysisRepositories.configError",
true,
);
}
this.onDidChangeConfigEventEmitter.fire();
}
private watchConfig(): void {
this.configWatcher = chokidar.watch(this.configPath).on("change", () => {
this.readConfigSync();
});
this.configWatcher = chokidar
.watch(this.configPath, {
// In some cases, change events are emitted while the file is still
// being written. The awaitWriteFinish option tells the watcher to
// poll the file size, holding its add and change events until the size
// does not change for a configurable amount of time. We set that time
// to 1 second, but it may need to be adjusted if there are issues.
awaitWriteFinish: {
stabilityThreshold: 1000,
},
})
.on("change", () => {
this.readConfigSync();
});
}
private createEmptyConfig(): DbConfig {
return {
version: DB_CONFIG_VERSION,
databases: {
remote: {
variantAnalysis: {
repositoryLists: [],
owners: [],
repositories: [],
@@ -170,7 +473,42 @@ export class DbConfigStore extends DisposableObject {
databases: [],
},
},
expanded: [],
selected: {
kind: SelectedDbItemKind.VariantAnalysisSystemDefinedList,
listName: "top_10",
},
};
}
private validateLocalListName(listName: string): void {
if (listName === "") {
throw Error("List name cannot be empty");
}
if (this.doesLocalListExist(listName)) {
throw Error(`A local list with the name '${listName}' already exists`);
}
}
private validateRemoteListName(listName: string): void {
if (listName === "") {
throw Error("List name cannot be empty");
}
if (this.doesRemoteListExist(listName)) {
throw Error(
`A variant analysis list with the name '${listName}' already exists`,
);
}
}
private validateLocalDbName(dbName: string): void {
if (dbName === "") {
throw Error("Database name cannot be empty");
}
if (this.doesLocalDbExist(dbName)) {
throw Error(`A local database with the name '${dbName}' already exists`);
}
}
}

View File

@@ -1,29 +1,145 @@
import { readJsonSync } from "fs-extra";
import { resolve } from "path";
import Ajv from "ajv";
import { DbConfig } from "./db-config";
import Ajv, { ValidateFunction } from "ajv";
import { clearLocalDbConfig, DbConfig } from "./db-config";
import { findDuplicateStrings } from "../../pure/text-utils";
import {
DbConfigValidationError,
DbConfigValidationErrorKind,
} from "../db-validation-errors";
export class DbConfigValidator {
private readonly schema: any;
private readonly validateSchemaFn: ValidateFunction;
constructor(extensionPath: string) {
const schemaPath = resolve(
extensionPath,
"workspace-databases-schema.json",
);
this.schema = readJsonSync(schemaPath);
const schemaPath = resolve(extensionPath, "databases-schema.json");
const schema = readJsonSync(schemaPath);
const schemaValidator = new Ajv({ allErrors: true });
this.validateSchemaFn = schemaValidator.compile(schema);
}
public validate(dbConfig: DbConfig): string[] {
const ajv = new Ajv({ allErrors: true });
ajv.validate(this.schema, dbConfig);
public validate(dbConfig: DbConfig): DbConfigValidationError[] {
const localDbs = clearLocalDbConfig(dbConfig);
if (ajv.errors) {
return ajv.errors.map(
(error) => `${error.instancePath} ${error.message}`,
);
this.validateSchemaFn(dbConfig);
if (this.validateSchemaFn.errors) {
return this.validateSchemaFn.errors.map((error) => ({
kind: DbConfigValidationErrorKind.InvalidConfig,
message: `${error.instancePath} ${error.message}`,
}));
}
return [];
// Add any local db config back so that we have a config
// object that respects its type and validation can happen
// as normal.
if (localDbs) {
dbConfig.databases.local = localDbs;
}
return [
...this.validateDbListNames(dbConfig),
...this.validateDbNames(dbConfig),
...this.validateDbNamesInLists(dbConfig),
...this.validateOwners(dbConfig),
];
}
private validateDbListNames(dbConfig: DbConfig): DbConfigValidationError[] {
const errors: DbConfigValidationError[] = [];
const buildError = (dups: string[]) => ({
kind: DbConfigValidationErrorKind.DuplicateNames,
message: `There are database lists with the same name: ${dups.join(
", ",
)}`,
});
const duplicateLocalDbLists = findDuplicateStrings(
dbConfig.databases.local.lists.map((n) => n.name),
);
if (duplicateLocalDbLists.length > 0) {
errors.push(buildError(duplicateLocalDbLists));
}
const duplicateRemoteDbLists = findDuplicateStrings(
dbConfig.databases.variantAnalysis.repositoryLists.map((n) => n.name),
);
if (duplicateRemoteDbLists.length > 0) {
errors.push(buildError(duplicateRemoteDbLists));
}
return errors;
}
private validateDbNames(dbConfig: DbConfig): DbConfigValidationError[] {
const errors: DbConfigValidationError[] = [];
const buildError = (dups: string[]) => ({
kind: DbConfigValidationErrorKind.DuplicateNames,
message: `There are databases with the same name: ${dups.join(", ")}`,
});
const duplicateLocalDbs = findDuplicateStrings(
dbConfig.databases.local.databases.map((d) => d.name),
);
if (duplicateLocalDbs.length > 0) {
errors.push(buildError(duplicateLocalDbs));
}
const duplicateRemoteDbs = findDuplicateStrings(
dbConfig.databases.variantAnalysis.repositories,
);
if (duplicateRemoteDbs.length > 0) {
errors.push(buildError(duplicateRemoteDbs));
}
return errors;
}
private validateDbNamesInLists(
dbConfig: DbConfig,
): DbConfigValidationError[] {
const errors: DbConfigValidationError[] = [];
const buildError = (listName: string, dups: string[]) => ({
kind: DbConfigValidationErrorKind.DuplicateNames,
message: `There are databases with the same name in the ${listName} list: ${dups.join(
", ",
)}`,
});
for (const list of dbConfig.databases.local.lists) {
const dups = findDuplicateStrings(list.databases.map((d) => d.name));
if (dups.length > 0) {
errors.push(buildError(list.name, dups));
}
}
for (const list of dbConfig.databases.variantAnalysis.repositoryLists) {
const dups = findDuplicateStrings(list.repositories);
if (dups.length > 0) {
errors.push(buildError(list.name, dups));
}
}
return errors;
}
private validateOwners(dbConfig: DbConfig): DbConfigValidationError[] {
const errors: DbConfigValidationError[] = [];
const dups = findDuplicateStrings(
dbConfig.databases.variantAnalysis.owners,
);
if (dups.length > 0) {
errors.push({
kind: DbConfigValidationErrorKind.DuplicateNames,
message: `There are owners with the same name: ${dups.join(", ")}`,
});
}
return errors;
}
}

View File

@@ -1,13 +1,16 @@
// Contains models for the data we want to store in the database config
// Contains models and consts for the data we want to store in the database config.
// Changes to these models should be done carefully and account for backwards compatibility of data.
export const DB_CONFIG_VERSION = 1;
export interface DbConfig {
version: number;
databases: DbConfigDatabases;
expanded: ExpandedDbItem[];
selected?: SelectedDbItem;
}
export interface DbConfigDatabases {
remote: RemoteDbConfig;
variantAnalysis: RemoteDbConfig;
local: LocalDbConfig;
}
@@ -15,17 +18,17 @@ export type SelectedDbItem =
| SelectedLocalUserDefinedList
| SelectedLocalDatabase
| SelectedRemoteSystemDefinedList
| SelectedRemoteUserDefinedList
| SelectedVariantAnalysisUserDefinedList
| SelectedRemoteOwner
| SelectedRemoteRepository;
export enum SelectedDbItemKind {
LocalUserDefinedList = "localUserDefinedList",
LocalDatabase = "localDatabase",
RemoteSystemDefinedList = "remoteSystemDefinedList",
RemoteUserDefinedList = "remoteUserDefinedList",
RemoteOwner = "remoteOwner",
RemoteRepository = "remoteRepository",
VariantAnalysisSystemDefinedList = "variantAnalysisSystemDefinedList",
VariantAnalysisUserDefinedList = "variantAnalysisUserDefinedList",
VariantAnalysisOwner = "variantAnalysisOwner",
VariantAnalysisRepository = "variantAnalysisRepository",
}
export interface SelectedLocalUserDefinedList {
@@ -40,22 +43,22 @@ export interface SelectedLocalDatabase {
}
export interface SelectedRemoteSystemDefinedList {
kind: SelectedDbItemKind.RemoteSystemDefinedList;
kind: SelectedDbItemKind.VariantAnalysisSystemDefinedList;
listName: string;
}
export interface SelectedRemoteUserDefinedList {
kind: SelectedDbItemKind.RemoteUserDefinedList;
export interface SelectedVariantAnalysisUserDefinedList {
kind: SelectedDbItemKind.VariantAnalysisUserDefinedList;
listName: string;
}
export interface SelectedRemoteOwner {
kind: SelectedDbItemKind.RemoteOwner;
kind: SelectedDbItemKind.VariantAnalysisOwner;
ownerName: string;
}
export interface SelectedRemoteRepository {
kind: SelectedDbItemKind.RemoteRepository;
kind: SelectedDbItemKind.VariantAnalysisRepository;
repositoryName: string;
listName?: string;
}
@@ -88,49 +91,19 @@ export interface LocalDatabase {
storagePath: string;
}
export type ExpandedDbItem =
| RootLocalExpandedDbItem
| LocalUserDefinedListExpandedDbItem
| RootRemoteExpandedDbItem
| RemoteUserDefinedListExpandedDbItem;
export enum ExpandedDbItemKind {
RootLocal = "rootLocal",
LocalUserDefinedList = "localUserDefinedList",
RootRemote = "rootRemote",
RemoteUserDefinedList = "remoteUserDefinedList",
}
export interface RootLocalExpandedDbItem {
kind: ExpandedDbItemKind.RootLocal;
}
export interface LocalUserDefinedListExpandedDbItem {
kind: ExpandedDbItemKind.LocalUserDefinedList;
listName: string;
}
export interface RootRemoteExpandedDbItem {
kind: ExpandedDbItemKind.RootRemote;
}
export interface RemoteUserDefinedListExpandedDbItem {
kind: ExpandedDbItemKind.RemoteUserDefinedList;
listName: string;
}
export function cloneDbConfig(config: DbConfig): DbConfig {
return {
version: config.version,
databases: {
remote: {
repositoryLists: config.databases.remote.repositoryLists.map(
variantAnalysis: {
repositoryLists: config.databases.variantAnalysis.repositoryLists.map(
(list) => ({
name: list.name,
repositories: [...list.repositories],
}),
),
owners: [...config.databases.remote.owners],
repositories: [...config.databases.remote.repositories],
owners: [...config.databases.variantAnalysis.owners],
repositories: [...config.databases.variantAnalysis.repositories],
},
local: {
lists: config.databases.local.lists.map((list) => ({
@@ -140,13 +113,255 @@ export function cloneDbConfig(config: DbConfig): DbConfig {
databases: config.databases.local.databases.map((db) => ({ ...db })),
},
},
expanded: config.expanded.map(cloneDbConfigExpandedItem),
selected: config.selected
? cloneDbConfigSelectedItem(config.selected)
: undefined,
};
}
export function renameLocalList(
originalConfig: DbConfig,
currentListName: string,
newListName: string,
): DbConfig {
const config = cloneDbConfig(originalConfig);
const list = getLocalList(config, currentListName);
list.name = newListName;
if (
config.selected?.kind === SelectedDbItemKind.LocalUserDefinedList ||
config.selected?.kind === SelectedDbItemKind.LocalDatabase
) {
if (config.selected.listName === currentListName) {
config.selected.listName = newListName;
}
}
return config;
}
export function renameRemoteList(
originalConfig: DbConfig,
currentListName: string,
newListName: string,
): DbConfig {
const config = cloneDbConfig(originalConfig);
const list = getRemoteList(config, currentListName);
list.name = newListName;
if (
config.selected?.kind ===
SelectedDbItemKind.VariantAnalysisUserDefinedList ||
config.selected?.kind === SelectedDbItemKind.VariantAnalysisRepository
) {
if (config.selected.listName === currentListName) {
config.selected.listName = newListName;
}
}
return config;
}
export function renameLocalDb(
originalConfig: DbConfig,
currentDbName: string,
newDbName: string,
parentListName?: string,
): DbConfig {
const config = cloneDbConfig(originalConfig);
if (parentListName) {
const list = getLocalList(config, parentListName);
const dbIndex = list.databases.findIndex((db) => db.name === currentDbName);
if (dbIndex === -1) {
throw Error(
`Cannot find database '${currentDbName}' in list '${parentListName}'`,
);
}
list.databases[dbIndex].name = newDbName;
} else {
const dbIndex = config.databases.local.databases.findIndex(
(db) => db.name === currentDbName,
);
if (dbIndex === -1) {
throw Error(`Cannot find database '${currentDbName}' in local databases`);
}
config.databases.local.databases[dbIndex].name = newDbName;
}
if (
config.selected?.kind === SelectedDbItemKind.LocalDatabase &&
config.selected.databaseName === currentDbName
) {
config.selected.databaseName = newDbName;
}
return config;
}
export function removeLocalList(
originalConfig: DbConfig,
listName: string,
): DbConfig {
const config = cloneDbConfig(originalConfig);
config.databases.local.lists = config.databases.local.lists.filter(
(list) => list.name !== listName,
);
if (config.selected?.kind === SelectedDbItemKind.LocalUserDefinedList) {
config.selected = undefined;
}
if (
config.selected?.kind === SelectedDbItemKind.LocalDatabase &&
config.selected?.listName === listName
) {
config.selected = undefined;
}
return config;
}
export function removeRemoteList(
originalConfig: DbConfig,
listName: string,
): DbConfig {
const config = cloneDbConfig(originalConfig);
config.databases.variantAnalysis.repositoryLists =
config.databases.variantAnalysis.repositoryLists.filter(
(list) => list.name !== listName,
);
if (
config.selected?.kind === SelectedDbItemKind.VariantAnalysisUserDefinedList
) {
config.selected = undefined;
}
if (
config.selected?.kind === SelectedDbItemKind.VariantAnalysisRepository &&
config.selected?.listName === listName
) {
config.selected = undefined;
}
return config;
}
export function removeLocalDb(
originalConfig: DbConfig,
databaseName: string,
parentListName?: string,
): DbConfig {
const config = cloneDbConfig(originalConfig);
if (parentListName) {
const parentList = getLocalList(config, parentListName);
parentList.databases = parentList.databases.filter(
(db) => db.name !== databaseName,
);
} else {
config.databases.local.databases = config.databases.local.databases.filter(
(db) => db.name !== databaseName,
);
}
if (
config.selected?.kind === SelectedDbItemKind.LocalDatabase &&
config.selected?.databaseName === databaseName &&
config.selected?.listName === parentListName
) {
config.selected = undefined;
}
return config;
}
export function removeRemoteRepo(
originalConfig: DbConfig,
repoFullName: string,
parentListName?: string,
): DbConfig {
const config = cloneDbConfig(originalConfig);
if (parentListName) {
const parentList = getRemoteList(config, parentListName);
parentList.repositories = parentList.repositories.filter(
(r) => r !== repoFullName,
);
} else {
config.databases.variantAnalysis.repositories =
config.databases.variantAnalysis.repositories.filter(
(r) => r !== repoFullName,
);
}
if (
config.selected?.kind === SelectedDbItemKind.VariantAnalysisRepository &&
config.selected?.repositoryName === repoFullName &&
config.selected?.listName === parentListName
) {
config.selected = undefined;
}
return config;
}
export function removeRemoteOwner(
originalConfig: DbConfig,
ownerName: string,
): DbConfig {
const config = cloneDbConfig(originalConfig);
config.databases.variantAnalysis.owners =
config.databases.variantAnalysis.owners.filter((o) => o !== ownerName);
if (
config.selected?.kind === SelectedDbItemKind.VariantAnalysisOwner &&
config.selected?.ownerName === ownerName
) {
config.selected = undefined;
}
return config;
}
/**
* Removes local db config from a db config object, if one is set.
* We do this because we don't want to expose this feature to users
* yet (since it's only partially implemented), but we also don't want
* to remove all the code we've already implemented.
* @param config The config object to change.
* @returns Any removed local db config.
*/
export function clearLocalDbConfig(
config: DbConfig,
): LocalDbConfig | undefined {
let localDbs = undefined;
if (config && config.databases && config.databases.local) {
localDbs = config.databases.local;
delete (config.databases as any).local;
}
return localDbs;
}
/**
* Initializes the local db config, if the config object contains
* database configuration.
* @param config The config object to change.
*/
export function initializeLocalDbConfig(config: DbConfig): void {
if (config.databases) {
config.databases.local = { lists: [], databases: [] };
}
}
function cloneDbConfigSelectedItem(selected: SelectedDbItem): SelectedDbItem {
switch (selected.kind) {
case SelectedDbItemKind.LocalUserDefinedList:
@@ -160,40 +375,51 @@ function cloneDbConfigSelectedItem(selected: SelectedDbItem): SelectedDbItem {
databaseName: selected.databaseName,
listName: selected.listName,
};
case SelectedDbItemKind.RemoteSystemDefinedList:
case SelectedDbItemKind.VariantAnalysisSystemDefinedList:
return {
kind: SelectedDbItemKind.RemoteSystemDefinedList,
kind: SelectedDbItemKind.VariantAnalysisSystemDefinedList,
listName: selected.listName,
};
case SelectedDbItemKind.RemoteUserDefinedList:
case SelectedDbItemKind.VariantAnalysisUserDefinedList:
return {
kind: SelectedDbItemKind.RemoteUserDefinedList,
kind: SelectedDbItemKind.VariantAnalysisUserDefinedList,
listName: selected.listName,
};
case SelectedDbItemKind.RemoteOwner:
case SelectedDbItemKind.VariantAnalysisOwner:
return {
kind: SelectedDbItemKind.RemoteOwner,
kind: SelectedDbItemKind.VariantAnalysisOwner,
ownerName: selected.ownerName,
};
case SelectedDbItemKind.RemoteRepository:
case SelectedDbItemKind.VariantAnalysisRepository:
return {
kind: SelectedDbItemKind.RemoteRepository,
kind: SelectedDbItemKind.VariantAnalysisRepository,
repositoryName: selected.repositoryName,
listName: selected.listName,
};
}
}
function cloneDbConfigExpandedItem(item: ExpandedDbItem): ExpandedDbItem {
switch (item.kind) {
case ExpandedDbItemKind.RootLocal:
case ExpandedDbItemKind.RootRemote:
return { kind: item.kind };
case ExpandedDbItemKind.LocalUserDefinedList:
case ExpandedDbItemKind.RemoteUserDefinedList:
return {
kind: item.kind,
listName: item.listName,
};
function getLocalList(config: DbConfig, listName: string): LocalList {
const list = config.databases.local.lists.find((l) => l.name === listName);
if (!list) {
throw Error(`Cannot find local list '${listName}'`);
}
return list;
}
function getRemoteList(
config: DbConfig,
listName: string,
): RemoteRepositoryList {
const list = config.databases.variantAnalysis.repositoryLists.find(
(l) => l.name === listName,
);
if (!list) {
throw Error(`Cannot find variant analysis list '${listName}'`);
}
return list;
}

View File

@@ -1,7 +1,37 @@
import { ExpandedDbItem, ExpandedDbItemKind } from "./config/db-config";
import { DbItem, DbItemKind } from "./db-item";
import { DbItem, DbItemKind, flattenDbItems } from "./db-item";
export function calculateNewExpandedState(
export type ExpandedDbItem =
| RootLocalExpandedDbItem
| LocalUserDefinedListExpandedDbItem
| RootRemoteExpandedDbItem
| RemoteUserDefinedListExpandedDbItem;
export enum ExpandedDbItemKind {
RootLocal = "rootLocal",
LocalUserDefinedList = "localUserDefinedList",
RootRemote = "rootRemote",
RemoteUserDefinedList = "remoteUserDefinedList",
}
export interface RootLocalExpandedDbItem {
kind: ExpandedDbItemKind.RootLocal;
}
export interface LocalUserDefinedListExpandedDbItem {
kind: ExpandedDbItemKind.LocalUserDefinedList;
listName: string;
}
export interface RootRemoteExpandedDbItem {
kind: ExpandedDbItemKind.RootRemote;
}
export interface RemoteUserDefinedListExpandedDbItem {
kind: ExpandedDbItemKind.RemoteUserDefinedList;
listName: string;
}
export function updateExpandedItem(
currentExpandedItems: ExpandedDbItem[],
dbItem: DbItem,
itemExpanded: boolean,
@@ -20,6 +50,34 @@ export function calculateNewExpandedState(
}
}
export function replaceExpandedItem(
currentExpandedItems: ExpandedDbItem[],
currentDbItem: DbItem,
newDbItem: DbItem,
): ExpandedDbItem[] {
const newExpandedItems: ExpandedDbItem[] = [];
for (const item of currentExpandedItems) {
if (isDbItemEqualToExpandedDbItem(currentDbItem, item)) {
newExpandedItems.push(mapDbItemToExpandedDbItem(newDbItem));
} else {
newExpandedItems.push(item);
}
}
return newExpandedItems;
}
export function cleanNonExistentExpandedItems(
currentExpandedItems: ExpandedDbItem[],
dbItems: DbItem[],
): ExpandedDbItem[] {
const flattenedDbItems = flattenDbItems(dbItems);
return currentExpandedItems.filter((i) =>
flattenedDbItems.some((dbItem) => isDbItemEqualToExpandedDbItem(dbItem, i)),
);
}
function mapDbItemToExpandedDbItem(dbItem: DbItem): ExpandedDbItem {
switch (dbItem.kind) {
case DbItemKind.RootLocal:
@@ -60,7 +118,10 @@ function isDbItemEqualToExpandedDbItem(
expandedDbItem.kind === ExpandedDbItemKind.RemoteUserDefinedList &&
expandedDbItem.listName === dbItem.listName
);
default:
throw Error(`Unknown db item kind ${dbItem.kind}`);
case DbItemKind.LocalDatabase:
case DbItemKind.RemoteSystemDefinedList:
case DbItemKind.RemoteOwner:
case DbItemKind.RemoteRepo:
return false;
}
}

View File

@@ -0,0 +1,19 @@
import { DbItem, DbItemKind } from "./db-item";
export function getDbItemName(dbItem: DbItem): string | undefined {
switch (dbItem.kind) {
case DbItemKind.RootLocal:
case DbItemKind.RootRemote:
return undefined;
case DbItemKind.LocalList:
case DbItemKind.RemoteUserDefinedList:
case DbItemKind.RemoteSystemDefinedList:
return dbItem.listName;
case DbItemKind.RemoteOwner:
return dbItem.ownerName;
case DbItemKind.LocalDatabase:
return dbItem.databaseName;
case DbItemKind.RemoteRepo:
return dbItem.repoFullName;
}
}

View File

@@ -61,34 +61,34 @@ export function mapDbItemToSelectedDbItem(
case DbItemKind.RemoteUserDefinedList:
return {
kind: SelectedDbItemKind.RemoteUserDefinedList,
kind: SelectedDbItemKind.VariantAnalysisUserDefinedList,
listName: dbItem.listName,
};
case DbItemKind.RemoteSystemDefinedList:
return {
kind: SelectedDbItemKind.RemoteSystemDefinedList,
kind: SelectedDbItemKind.VariantAnalysisSystemDefinedList,
listName: dbItem.listName,
};
case DbItemKind.RemoteOwner:
return {
kind: SelectedDbItemKind.RemoteOwner,
kind: SelectedDbItemKind.VariantAnalysisOwner,
ownerName: dbItem.ownerName,
};
case DbItemKind.LocalDatabase:
return {
kind: SelectedDbItemKind.LocalDatabase,
listName: dbItem?.parentListName,
databaseName: dbItem.databaseName,
listName: dbItem?.parentListName,
};
case DbItemKind.RemoteRepo:
return {
kind: SelectedDbItemKind.RemoteRepository,
listName: dbItem?.parentListName,
kind: SelectedDbItemKind.VariantAnalysisRepository,
repositoryName: dbItem.repoFullName,
listName: dbItem?.parentListName,
};
}
}

View File

@@ -11,6 +11,25 @@ export enum DbItemKind {
RemoteRepo = "RemoteRepo",
}
export const remoteDbKinds = [
DbItemKind.RootRemote,
DbItemKind.RemoteSystemDefinedList,
DbItemKind.RemoteUserDefinedList,
DbItemKind.RemoteOwner,
DbItemKind.RemoteRepo,
];
export const localDbKinds = [
DbItemKind.RootLocal,
DbItemKind.LocalList,
DbItemKind.LocalDatabase,
];
export enum DbListKind {
Local = "Local",
Remote = "Remote",
}
export interface RootLocalDbItem {
kind: DbItemKind.RootLocal;
expanded: boolean;
@@ -130,3 +149,32 @@ const SelectableDbItemKinds = [
DbItemKind.RemoteOwner,
DbItemKind.RemoteRepo,
];
export function flattenDbItems(dbItems: DbItem[]): DbItem[] {
const allItems: DbItem[] = [];
for (const dbItem of dbItems) {
allItems.push(dbItem);
switch (dbItem.kind) {
case DbItemKind.RootLocal:
allItems.push(...flattenDbItems(dbItem.children));
break;
case DbItemKind.LocalList:
allItems.push(...flattenDbItems(dbItem.databases));
break;
case DbItemKind.RootRemote:
allItems.push(...flattenDbItems(dbItem.children));
break;
case DbItemKind.RemoteUserDefinedList:
allItems.push(...dbItem.repos);
break;
case DbItemKind.LocalDatabase:
case DbItemKind.RemoteSystemDefinedList:
case DbItemKind.RemoteOwner:
case DbItemKind.RemoteRepo:
break;
}
}
return allItems;
}

View File

@@ -2,19 +2,36 @@ import { App } from "../common/app";
import { AppEvent, AppEventEmitter } from "../common/events";
import { ValueResult } from "../common/value-result";
import { DbConfigStore } from "./config/db-config-store";
import { DbItem } from "./db-item";
import { calculateNewExpandedState } from "./db-item-expansion";
import {
DbItem,
DbItemKind,
DbListKind,
LocalDatabaseDbItem,
LocalListDbItem,
RemoteUserDefinedListDbItem,
} from "./db-item";
import {
updateExpandedItem,
replaceExpandedItem,
ExpandedDbItem,
cleanNonExistentExpandedItems,
} from "./db-item-expansion";
import {
getSelectedDbItem,
mapDbItemToSelectedDbItem,
} from "./db-item-selection";
import { createLocalTree, createRemoteTree } from "./db-tree-creator";
import { createRemoteTree } from "./db-tree-creator";
import { DbConfigValidationError } from "./db-validation-errors";
export class DbManager {
public readonly onDbItemsChanged: AppEvent<void>;
public static readonly DB_EXPANDED_STATE_KEY = "db_expanded";
private readonly onDbItemsChangesEventEmitter: AppEventEmitter<void>;
constructor(app: App, private readonly dbConfigStore: DbConfigStore) {
constructor(
private readonly app: App,
private readonly dbConfigStore: DbConfigStore,
) {
this.onDbItemsChangesEventEmitter = app.createEventEmitter<void>();
this.onDbItemsChanged = this.onDbItemsChangesEventEmitter.event;
@@ -24,25 +41,25 @@ export class DbManager {
}
public getSelectedDbItem(): DbItem | undefined {
const dbItems = this.getDbItems();
const dbItemsResult = this.getDbItems();
if (dbItems.isFailure) {
if (dbItemsResult.errors.length > 0) {
return undefined;
}
return getSelectedDbItem(dbItems.value);
return getSelectedDbItem(dbItemsResult.value);
}
public getDbItems(): ValueResult<DbItem[]> {
public getDbItems(): ValueResult<DbItem[], DbConfigValidationError> {
const configResult = this.dbConfigStore.getConfig();
if (configResult.isFailure) {
return ValueResult.fail(configResult.errors);
}
return ValueResult.ok([
createRemoteTree(configResult.value),
createLocalTree(configResult.value),
]);
const expandedItems = this.getExpandedItems();
const remoteTree = createRemoteTree(configResult.value, expandedItems);
return ValueResult.ok(remoteTree.children);
}
public getConfigPath(): string {
@@ -56,25 +73,155 @@ export class DbManager {
}
}
public async updateDbItemExpandedState(
public async removeDbItem(dbItem: DbItem): Promise<void> {
await this.dbConfigStore.removeDbItem(dbItem);
await this.removeDbItemFromExpandedState(dbItem);
}
public async removeDbItemFromExpandedState(dbItem: DbItem): Promise<void> {
// When collapsing or expanding a list we clean up the expanded state and remove
// all items that don't exist anymore.
await this.updateDbItemExpandedState(dbItem, false);
}
public async addDbItemToExpandedState(dbItem: DbItem): Promise<void> {
// When collapsing or expanding a list we clean up the expanded state and remove
// all items that don't exist anymore.
await this.updateDbItemExpandedState(dbItem, true);
}
public async addNewRemoteRepo(
nwo: string,
parentList?: string,
): Promise<void> {
await this.dbConfigStore.addRemoteRepo(nwo, parentList);
}
public async addNewRemoteOwner(owner: string): Promise<void> {
await this.dbConfigStore.addRemoteOwner(owner);
}
public async addNewList(
listKind: DbListKind,
listName: string,
): Promise<void> {
switch (listKind) {
case DbListKind.Local:
await this.dbConfigStore.addLocalList(listName);
break;
case DbListKind.Remote:
await this.dbConfigStore.addRemoteList(listName);
break;
default:
throw Error(`Unknown list kind '${listKind}'`);
}
}
public async renameList(
currentDbItem: LocalListDbItem | RemoteUserDefinedListDbItem,
newName: string,
): Promise<void> {
if (currentDbItem.kind === DbItemKind.LocalList) {
await this.dbConfigStore.renameLocalList(currentDbItem, newName);
} else if (currentDbItem.kind === DbItemKind.RemoteUserDefinedList) {
await this.dbConfigStore.renameRemoteList(currentDbItem, newName);
}
const newDbItem = { ...currentDbItem, listName: newName };
const newExpandedItems = replaceExpandedItem(
this.getExpandedItems(),
currentDbItem,
newDbItem,
);
await this.setExpandedItems(newExpandedItems);
}
public async renameLocalDb(
currentDbItem: LocalDatabaseDbItem,
newName: string,
): Promise<void> {
await this.dbConfigStore.renameLocalDb(
currentDbItem,
newName,
currentDbItem.parentListName,
);
}
public doesListExist(listKind: DbListKind, listName: string): boolean {
switch (listKind) {
case DbListKind.Local:
return this.dbConfigStore.doesLocalListExist(listName);
case DbListKind.Remote:
return this.dbConfigStore.doesRemoteListExist(listName);
default:
throw Error(`Unknown list kind '${listKind}'`);
}
}
public doesRemoteOwnerExist(owner: string): boolean {
return this.dbConfigStore.doesRemoteOwnerExist(owner);
}
public doesRemoteRepoExist(nwo: string, listName?: string): boolean {
return this.dbConfigStore.doesRemoteDbExist(nwo, listName);
}
public doesLocalDbExist(dbName: string, listName?: string): boolean {
return this.dbConfigStore.doesLocalDbExist(dbName, listName);
}
private getExpandedItems(): ExpandedDbItem[] {
const items = this.app.workspaceState.get<ExpandedDbItem[]>(
DbManager.DB_EXPANDED_STATE_KEY,
);
return items || [];
}
private async setExpandedItems(items: ExpandedDbItem[]): Promise<void> {
await this.app.workspaceState.update(
DbManager.DB_EXPANDED_STATE_KEY,
items,
);
}
private async updateExpandedItems(items: ExpandedDbItem[]): Promise<void> {
let itemsToStore;
const dbItemsResult = this.getDbItems();
if (dbItemsResult.isFailure) {
// Log an error but don't throw an exception since if the db items are failing
// to be read, then there is a bigger problem than the expanded state.
void this.app.logger.log(
`Could not read db items when calculating expanded state: ${JSON.stringify(
dbItemsResult.errors,
)}`,
);
itemsToStore = items;
} else {
itemsToStore = cleanNonExistentExpandedItems(items, dbItemsResult.value);
}
await this.setExpandedItems(itemsToStore);
}
private async updateDbItemExpandedState(
dbItem: DbItem,
itemExpanded: boolean,
): Promise<void> {
const configResult = this.dbConfigStore.getConfig();
if (configResult.isFailure) {
throw Error("Cannot update expanded state if config is not loaded");
}
const currentExpandedItems = this.getExpandedItems();
const newExpandedItems = calculateNewExpandedState(
configResult.value.expanded,
const newExpandedItems = updateExpandedItem(
currentExpandedItems,
dbItem,
itemExpanded,
);
await this.dbConfigStore.updateExpandedState(newExpandedItems);
}
public async addNewRemoteList(listName: string): Promise<void> {
await this.dbConfigStore.addRemoteList(listName);
await this.updateExpandedItems(newExpandedItems);
}
}

View File

@@ -1,16 +1,17 @@
import { window } from "vscode";
import { App, AppMode } from "../common/app";
import { App } from "../common/app";
import { extLogger } from "../common";
import { DisposableObject } from "../pure/disposable-object";
import { DbConfigStore } from "./config/db-config-store";
import { DbManager } from "./db-manager";
import { DbPanel } from "./ui/db-panel";
import { DbSelectionDecorationProvider } from "./ui/db-selection-decoration-provider";
import { isCanary, isNewQueryRunExperienceEnabled } from "../config";
import { DatabasePanelCommands } from "../common/commands";
export class DbModule extends DisposableObject {
public readonly dbManager: DbManager;
private readonly dbConfigStore: DbConfigStore;
private dbPanel: DbPanel | undefined;
private constructor(app: App) {
super();
@@ -19,32 +20,32 @@ export class DbModule extends DisposableObject {
this.dbManager = new DbManager(app, this.dbConfigStore);
}
public static async initialize(app: App): Promise<DbModule | undefined> {
if (
isCanary() &&
isNewQueryRunExperienceEnabled() &&
app.mode === AppMode.Development
) {
const dbModule = new DbModule(app);
app.subscriptions.push(dbModule);
public static async initialize(app: App): Promise<DbModule> {
const dbModule = new DbModule(app);
app.subscriptions.push(dbModule);
await dbModule.initialize();
return dbModule;
}
return undefined;
await dbModule.initialize(app);
return dbModule;
}
private async initialize(): Promise<void> {
public getCommands(): DatabasePanelCommands {
if (!this.dbPanel) {
throw new Error("Database panel not initialized");
}
return {
...this.dbPanel.getCommands(),
};
}
private async initialize(app: App): Promise<void> {
void extLogger.log("Initializing database module");
await this.dbConfigStore.initialize();
const dbPanel = new DbPanel(this.dbManager);
await dbPanel.initialize();
this.dbPanel = new DbPanel(this.dbManager, app.credentials);
this.push(dbPanel);
this.push(this.dbPanel);
this.push(this.dbConfigStore);
const dbSelectionDecorationProvider = new DbSelectionDecorationProvider();

View File

@@ -1,6 +1,5 @@
import {
DbConfig,
ExpandedDbItemKind,
LocalDatabase,
LocalList,
RemoteRepositoryList,
@@ -17,27 +16,32 @@ import {
RootLocalDbItem,
RootRemoteDbItem,
} from "./db-item";
import { ExpandedDbItem, ExpandedDbItemKind } from "./db-item-expansion";
export function createRemoteTree(dbConfig: DbConfig): RootRemoteDbItem {
export function createRemoteTree(
dbConfig: DbConfig,
expandedItems: ExpandedDbItem[],
): RootRemoteDbItem {
const systemDefinedLists = [
createSystemDefinedList(10, dbConfig),
createSystemDefinedList(100, dbConfig),
createSystemDefinedList(1000, dbConfig),
];
const userDefinedRepoLists = dbConfig.databases.remote.repositoryLists.map(
(r) => createRemoteUserDefinedList(r, dbConfig),
);
const owners = dbConfig.databases.remote.owners.map((o) =>
const userDefinedRepoLists =
dbConfig.databases.variantAnalysis.repositoryLists.map((r) =>
createVariantAnalysisUserDefinedList(r, dbConfig, expandedItems),
);
const owners = dbConfig.databases.variantAnalysis.owners.map((o) =>
createOwnerItem(o, dbConfig),
);
const repos = dbConfig.databases.remote.repositories.map((r) =>
const repos = dbConfig.databases.variantAnalysis.repositories.map((r) =>
createRepoItem(r, dbConfig),
);
const expanded =
dbConfig.expanded &&
dbConfig.expanded.some((e) => e.kind === ExpandedDbItemKind.RootRemote);
const expanded = expandedItems.some(
(e) => e.kind === ExpandedDbItemKind.RootRemote,
);
return {
kind: DbItemKind.RootRemote,
@@ -51,17 +55,20 @@ export function createRemoteTree(dbConfig: DbConfig): RootRemoteDbItem {
};
}
export function createLocalTree(dbConfig: DbConfig): RootLocalDbItem {
export function createLocalTree(
dbConfig: DbConfig,
expandedItems: ExpandedDbItem[],
): RootLocalDbItem {
const localLists = dbConfig.databases.local.lists.map((l) =>
createLocalList(l, dbConfig),
createLocalList(l, dbConfig, expandedItems),
);
const localDbs = dbConfig.databases.local.databases.map((l) =>
createLocalDb(l, dbConfig),
);
const expanded =
dbConfig.expanded &&
dbConfig.expanded.some((e) => e.kind === ExpandedDbItemKind.RootLocal);
const expanded = expandedItems.some(
(e) => e.kind === ExpandedDbItemKind.RootLocal,
);
return {
kind: DbItemKind.RootLocal,
@@ -78,7 +85,8 @@ function createSystemDefinedList(
const selected =
dbConfig.selected &&
dbConfig.selected.kind === SelectedDbItemKind.RemoteSystemDefinedList &&
dbConfig.selected.kind ===
SelectedDbItemKind.VariantAnalysisSystemDefinedList &&
dbConfig.selected.listName === listName;
return {
@@ -90,22 +98,22 @@ function createSystemDefinedList(
};
}
function createRemoteUserDefinedList(
function createVariantAnalysisUserDefinedList(
list: RemoteRepositoryList,
dbConfig: DbConfig,
expandedItems: ExpandedDbItem[],
): RemoteUserDefinedListDbItem {
const selected =
dbConfig.selected &&
dbConfig.selected.kind === SelectedDbItemKind.RemoteUserDefinedList &&
dbConfig.selected.kind ===
SelectedDbItemKind.VariantAnalysisUserDefinedList &&
dbConfig.selected.listName === list.name;
const expanded =
dbConfig.expanded &&
dbConfig.expanded.some(
(e) =>
e.kind === ExpandedDbItemKind.RemoteUserDefinedList &&
e.listName === list.name,
);
const expanded = expandedItems.some(
(e) =>
e.kind === ExpandedDbItemKind.RemoteUserDefinedList &&
e.listName === list.name,
);
return {
kind: DbItemKind.RemoteUserDefinedList,
@@ -119,7 +127,7 @@ function createRemoteUserDefinedList(
function createOwnerItem(owner: string, dbConfig: DbConfig): RemoteOwnerDbItem {
const selected =
dbConfig.selected &&
dbConfig.selected.kind === SelectedDbItemKind.RemoteOwner &&
dbConfig.selected.kind === SelectedDbItemKind.VariantAnalysisOwner &&
dbConfig.selected.ownerName === owner;
return {
@@ -136,7 +144,7 @@ function createRepoItem(
): RemoteRepoDbItem {
const selected =
dbConfig.selected &&
dbConfig.selected.kind === SelectedDbItemKind.RemoteRepository &&
dbConfig.selected.kind === SelectedDbItemKind.VariantAnalysisRepository &&
dbConfig.selected.repositoryName === repo &&
dbConfig.selected.listName === listName;
@@ -148,19 +156,21 @@ function createRepoItem(
};
}
function createLocalList(list: LocalList, dbConfig: DbConfig): LocalListDbItem {
function createLocalList(
list: LocalList,
dbConfig: DbConfig,
expandedItems: ExpandedDbItem[],
): LocalListDbItem {
const selected =
dbConfig.selected &&
dbConfig.selected.kind === SelectedDbItemKind.LocalUserDefinedList &&
dbConfig.selected.listName === list.name;
const expanded =
dbConfig.expanded &&
dbConfig.expanded.some(
(e) =>
e.kind === ExpandedDbItemKind.LocalUserDefinedList &&
e.listName === list.name,
);
const expanded = expandedItems.some(
(e) =>
e.kind === ExpandedDbItemKind.LocalUserDefinedList &&
e.listName === list.name,
);
return {
kind: DbItemKind.LocalList,

View File

@@ -0,0 +1,10 @@
export enum DbConfigValidationErrorKind {
InvalidJson = "InvalidJson",
InvalidConfig = "InvalidConfig",
DuplicateNames = "DuplicateNames",
}
export interface DbConfigValidationError {
kind: DbConfigValidationErrorKind;
message: string;
}

Some files were not shown because too many files have changed in this diff Show More