@@ -34,6 +34,7 @@ import { QueryLanguage } from "../common/query-language";
3434import { LINE_ENDINGS , splitStreamAtSeparators } from "../common/split-stream" ;
3535import type { Position } from "../query-server/messages" ;
3636import { LOGGING_FLAGS } from "./cli-command" ;
37+ import type { CliFeatures , VersionAndFeatures } from "./cli-version" ;
3738
3839/**
3940 * The version of the SARIF format that we are using.
@@ -193,7 +194,9 @@ type OnLineCallback = (
193194 line : string ,
194195) => Promise < string | undefined > | string | undefined ;
195196
196- type VersionChangedListener = ( newVersion : SemVer | undefined ) => void ;
197+ type VersionChangedListener = (
198+ newVersionAndFeatures : VersionAndFeatures | undefined ,
199+ ) => void ;
197200
198201/**
199202 * This class manages a cli server started by `codeql execute cli-server` to
@@ -211,8 +214,8 @@ export class CodeQLCliServer implements Disposable {
211214 /** A buffer with a single null byte. */
212215 nullBuffer : Buffer ;
213216
214- /** Version of current cli, lazily computed by the `getVersion()` method */
215- private _version : SemVer | undefined ;
217+ /** Version of current cli and its supported features , lazily computed by the `getVersion()` method */
218+ private _versionAndFeatures : VersionAndFeatures | undefined ;
216219
217220 private _versionChangedListeners : VersionChangedListener [ ] = [ ] ;
218221
@@ -288,7 +291,7 @@ export class CodeQLCliServer implements Disposable {
288291 const callback = ( ) : void => {
289292 try {
290293 this . killProcessIfRunning ( ) ;
291- this . _version = undefined ;
294+ this . _versionAndFeatures = undefined ;
292295 this . _supportedLanguages = undefined ;
293296 } finally {
294297 this . runNext ( ) ;
@@ -1417,6 +1420,27 @@ export class CodeQLCliServer implements Disposable {
14171420 ) ;
14181421 }
14191422
1423+ public async packCreate (
1424+ dir : string ,
1425+ workspaceFolders : string [ ] ,
1426+ outputPath : string ,
1427+ moreOptions : string [ ] ,
1428+ ) : Promise < void > {
1429+ const args = [
1430+ "--output" ,
1431+ outputPath ,
1432+ dir ,
1433+ ...moreOptions ,
1434+ ...this . getAdditionalPacksArg ( workspaceFolders ) ,
1435+ ] ;
1436+
1437+ return this . runJsonCodeQlCliCommandWithAuthentication (
1438+ [ "pack" , "create" ] ,
1439+ args ,
1440+ "Creating pack" ,
1441+ ) ;
1442+ }
1443+
14201444 async packBundle (
14211445 dir : string ,
14221446 workspaceFolders : string [ ] ,
@@ -1481,27 +1505,35 @@ export class CodeQLCliServer implements Disposable {
14811505 ) ;
14821506 }
14831507
1484- public async getVersion ( ) {
1485- if ( ! this . _version ) {
1508+ public async getVersion ( ) : Promise < SemVer > {
1509+ return ( await this . getVersionAndFeatures ( ) ) . version ;
1510+ }
1511+
1512+ public async getFeatures ( ) : Promise < CliFeatures > {
1513+ return ( await this . getVersionAndFeatures ( ) ) . features ;
1514+ }
1515+
1516+ public async getVersionAndFeatures ( ) : Promise < VersionAndFeatures > {
1517+ if ( ! this . _versionAndFeatures ) {
14861518 try {
1487- const newVersion = await this . refreshVersion ( ) ;
1488- this . _version = newVersion ;
1519+ const newVersionAndFeatures = await this . refreshVersion ( ) ;
1520+ this . _versionAndFeatures = newVersionAndFeatures ;
14891521 this . _versionChangedListeners . forEach ( ( listener ) =>
1490- listener ( newVersion ) ,
1522+ listener ( newVersionAndFeatures ) ,
14911523 ) ;
14921524
14931525 // this._version is only undefined upon config change, so we reset CLI-based context key only when necessary.
14941526 await this . app . commands . execute (
14951527 "setContext" ,
14961528 "codeql.supportsQuickEvalCount" ,
1497- newVersion . compare (
1529+ newVersionAndFeatures . version . compare (
14981530 CliVersionConstraint . CLI_VERSION_WITH_QUICK_EVAL_COUNT ,
14991531 ) >= 0 ,
15001532 ) ;
15011533 await this . app . commands . execute (
15021534 "setContext" ,
15031535 "codeql.supportsTrimCache" ,
1504- newVersion . compare (
1536+ newVersionAndFeatures . version . compare (
15051537 CliVersionConstraint . CLI_VERSION_WITH_TRIM_CACHE ,
15061538 ) >= 0 ,
15071539 ) ;
@@ -1512,23 +1544,23 @@ export class CodeQLCliServer implements Disposable {
15121544 throw e ;
15131545 }
15141546 }
1515- return this . _version ;
1547+ return this . _versionAndFeatures ;
15161548 }
15171549
15181550 public addVersionChangedListener ( listener : VersionChangedListener ) {
1519- if ( this . _version ) {
1520- listener ( this . _version ) ;
1551+ if ( this . _versionAndFeatures ) {
1552+ listener ( this . _versionAndFeatures ) ;
15211553 }
15221554 this . _versionChangedListeners . push ( listener ) ;
15231555 }
15241556
1525- private async refreshVersion ( ) {
1557+ private async refreshVersion ( ) : Promise < VersionAndFeatures > {
15261558 const distribution = await this . distributionProvider . getDistribution ( ) ;
15271559 switch ( distribution . kind ) {
15281560 case FindDistributionResultKind . CompatibleDistribution :
15291561 // eslint-disable-next-line no-fallthrough -- Intentional fallthrough
15301562 case FindDistributionResultKind . IncompatibleDistribution :
1531- return distribution . version ;
1563+ return distribution . versionAndFeatures ;
15321564
15331565 default :
15341566 // We should not get here because if no distributions are available, then
@@ -1745,4 +1777,8 @@ export class CliVersionConstraint {
17451777 CliVersionConstraint . CLI_VERSION_WITH_EXTENSIBLE_PREDICATE_METADATA ,
17461778 ) ;
17471779 }
1780+
1781+ async supportsMrvaPackCreate ( ) : Promise < boolean > {
1782+ return ( await this . cli . getFeatures ( ) ) . mrvaPackCreate === true ;
1783+ }
17481784}
0 commit comments