Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions common/config/rush/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion extensions/ql-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,9 @@
"vscode-languageclient": "^6.1.3",
"vscode-test-adapter-api": "~1.7.0",
"vscode-test-adapter-util": "~0.7.0",
"minimist": "~1.2.5"
"minimist": "~1.2.5",
"semver": "~7.3.2",
"@types/semver": "~7.2.0"
},
"devDependencies": {
"@types/chai": "^4.1.7",
Expand Down
85 changes: 3 additions & 82 deletions extensions/ql-vscode/src/cli-version.ts
Original file line number Diff line number Diff line change
@@ -1,96 +1,17 @@
import * as semver from "semver";
import { runCodeQlCliCommand } from "./cli";
import { Logger } from "./logging";

/**
* Get the version of a CodeQL CLI.
*/
export async function getCodeQlCliVersion(codeQlPath: string, logger: Logger): Promise<Version | undefined> {
export async function getCodeQlCliVersion(codeQlPath: string, logger: Logger): Promise<semver.SemVer | undefined> {
const output: string = await runCodeQlCliCommand(
codeQlPath,
["version"],
["--format=terse"],
"Checking CodeQL version",
logger
);
return tryParseVersionString(output.trim());
}

/**
* Try to parse a version string, returning undefined if we can't parse it.
*
* Version strings must contain a major, minor, and patch version. They may optionally
* start with "v" and may optionally contain some "tail" string after the major, minor, and
* patch versions, for example as in `v2.1.0+baf5bff`.
*/
export function tryParseVersionString(versionString: string): Version | undefined {
const match = versionString.match(versionRegex);
if (match === null) {
return undefined;
}
return {
buildMetadata: match[5],
majorVersion: Number.parseInt(match[1], 10),
minorVersion: Number.parseInt(match[2], 10),
patchVersion: Number.parseInt(match[3], 10),
prereleaseVersion: match[4],
rawString: versionString,
};
}

/**
* Regex for parsing semantic versions
*
* From the semver spec https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string
*/
const versionRegex = new RegExp(String.raw`^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)` +
String.raw`(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?` +
String.raw`(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$`);

/**
* A version of the CodeQL CLI.
*/
export interface Version {
/**
* Build metadata
*
* For example, this will be `abcdef0` for version 2.1.0-alpha.1+abcdef0.
* Build metadata must be ignored when comparing versions.
*/
buildMetadata: string | undefined;

/**
* Major version number
*
* For example, this will be `2` for version 2.1.0-alpha.1+abcdef0.
*/
majorVersion: number;

/**
* Minor version number
*
* For example, this will be `1` for version 2.1.0-alpha.1+abcdef0.
*/
minorVersion: number;

/**
* Patch version number
*
* For example, this will be `0` for version 2.1.0-alpha.1+abcdef0.
*/
patchVersion: number;

/**
* Prerelease version
*
* For example, this will be `alpha.1` for version 2.1.0-alpha.1+abcdef0.
* The prerelease version must be considered when comparing versions.
*/
prereleaseVersion: string | undefined;

/**
* Raw version string
*
* For example, this will be `2.1.0-alpha.1+abcdef0` for version 2.1.0-alpha.1+abcdef0.
*/
rawString: string;
return semver.parse(output.trim()) || undefined;
}
Loading