@@ -8,7 +8,10 @@ import type { Log } from "sarif";
8
8
import { SemVer } from "semver" ;
9
9
import type { Readable } from "stream" ;
10
10
import tk from "tree-kill" ;
11
- import type { CancellationToken , Disposable , Uri } from "vscode" ;
11
+ import type { CancellationToken , Disposable } from "vscode" ;
12
+ import { Uri } from "vscode" ;
13
+
14
+ import { existsSync } from "fs" ;
12
15
13
16
import type {
14
17
BqrsInfo ,
@@ -37,6 +40,11 @@ import { LOGGING_FLAGS } from "./cli-command";
37
40
import type { CliFeatures , VersionAndFeatures } from "./cli-version" ;
38
41
import { ExitCodeError , getCliError } from "./cli-errors" ;
39
42
import { UserCancellationException } from "../common/vscode/progress" ;
43
+ import type { LanguageClient } from "vscode-languageclient/node" ;
44
+ import {
45
+ DidChangeWatchedFilesNotification ,
46
+ FileChangeType ,
47
+ } from "vscode-languageclient/node" ;
40
48
41
49
/**
42
50
* The version of the SARIF format that we are using.
@@ -277,6 +285,7 @@ export class CodeQLCliServer implements Disposable {
277
285
278
286
constructor (
279
287
private readonly app : App ,
288
+ private readonly languageClient : LanguageClient ,
280
289
private distributionProvider : DistributionProvider ,
281
290
private cliConfig : CliConfig ,
282
291
public readonly logger : Logger ,
@@ -1584,11 +1593,13 @@ export class CodeQLCliServer implements Disposable {
1584
1593
async packAdd ( dir : string , queryLanguage : QueryLanguage ) {
1585
1594
const args = [ "--dir" , dir ] ;
1586
1595
args . push ( `codeql/${ queryLanguage } -all` ) ;
1587
- return this . runCodeQlCliCommand (
1596
+ const ret = await this . runCodeQlCliCommand (
1588
1597
[ "pack" , "add" ] ,
1589
1598
args ,
1590
1599
`Adding and installing ${ queryLanguage } pack dependency.` ,
1591
1600
) ;
1601
+ await this . notifyPackChanged ( dir ) ;
1602
+ return ret ;
1592
1603
}
1593
1604
1594
1605
/**
@@ -1628,11 +1639,13 @@ export class CodeQLCliServer implements Disposable {
1628
1639
...this . getAdditionalPacksArg ( workspaceFolders ) ,
1629
1640
) ;
1630
1641
}
1631
- return this . runJsonCodeQlCliCommandWithAuthentication (
1642
+ const ret = await this . runJsonCodeQlCliCommandWithAuthentication (
1632
1643
[ "pack" , "install" ] ,
1633
1644
args ,
1634
1645
"Installing pack dependencies" ,
1635
1646
) ;
1647
+ await this . notifyPackChanged ( dir ) ;
1648
+ return ret ;
1636
1649
}
1637
1650
1638
1651
/**
@@ -1750,6 +1763,29 @@ export class CodeQLCliServer implements Disposable {
1750
1763
this . _versionChangedListeners . push ( listener ) ;
1751
1764
}
1752
1765
1766
+ private async notifyPackChanged ( packDir : string ) {
1767
+ const packFilePath = join ( packDir , "codeql-pack.yml" ) ;
1768
+ if ( ! existsSync ( packFilePath ) ) {
1769
+ throw new Error ( `Pack file ${ packFilePath } does not exist` ) ;
1770
+ }
1771
+ await this . languageClient . sendNotification (
1772
+ DidChangeWatchedFilesNotification . type ,
1773
+ {
1774
+ changes : [
1775
+ {
1776
+ type : FileChangeType . Changed ,
1777
+ uri : Uri . file ( packFilePath ) . toString ( ) ,
1778
+ } ,
1779
+ ] ,
1780
+ } ,
1781
+ ) ;
1782
+
1783
+ // restarting the language client has the effect of removing compilation
1784
+ // errors in open ql/qll files that are caused by the pack not having been
1785
+ // installed previously:
1786
+ await this . languageClient . restart ( ) ;
1787
+ }
1788
+
1753
1789
private async refreshVersion ( ) : Promise < VersionAndFeatures > {
1754
1790
const distribution = await this . distributionProvider . getDistribution ( ) ;
1755
1791
switch ( distribution . kind ) {
0 commit comments