Remove LGTM references and commands

LGTM has been decommissioned. All code and tests for downloading
LGTM databases should be removed.
This commit is contained in:
Andrew Eisenberg
2022-12-16 09:14:49 -08:00
parent 8971bee31d
commit 0bf1fae2fe
8 changed files with 0 additions and 380 deletions

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,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

@@ -48,7 +48,6 @@
"onCommand:codeQLDatabases.chooseDatabaseArchive",
"onCommand:codeQLDatabases.chooseDatabaseInternet",
"onCommand:codeQLDatabases.chooseDatabaseGithub",
"onCommand:codeQLDatabases.chooseDatabaseLgtm",
"onCommand:codeQL.setCurrentDatabase",
"onCommand:codeQL.viewAst",
"onCommand:codeQL.viewCfg",
@@ -58,7 +57,6 @@
"onCommand:codeQL.chooseDatabaseArchive",
"onCommand:codeQL.chooseDatabaseInternet",
"onCommand:codeQL.chooseDatabaseGithub",
"onCommand:codeQL.chooseDatabaseLgtm",
"onCommand:codeQLDatabases.chooseDatabase",
"onCommand:codeQLDatabases.setCurrentDatabase",
"onCommand:codeQLDatabasesExperimental.openConfigFile",
@@ -410,14 +408,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"
@@ -486,10 +476,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",
@@ -728,11 +714,6 @@
"when": "view == codeQLDatabases",
"group": "navigation"
},
{
"command": "codeQLDatabases.chooseDatabaseLgtm",
"when": "config.codeQL.canary && view == codeQLDatabases",
"group": "navigation"
},
{
"command": "codeQLQueryHistory.openQuery",
"when": "view == codeQLQueryHistory",
@@ -997,10 +978,6 @@
"command": "codeQL.viewCfg",
"when": "resourceScheme == codeql-zip-archive && config.codeQL.canary"
},
{
"command": "codeQL.chooseDatabaseLgtm",
"when": "config.codeQL.canary"
},
{
"command": "codeQLDatabasesExperimental.openConfigFile",
"when": "false"
@@ -1061,10 +1038,6 @@
"command": "codeQLDatabases.chooseDatabaseGithub",
"when": "false"
},
{
"command": "codeQLDatabases.chooseDatabaseLgtm",
"when": "false"
},
{
"command": "codeQLDatabases.upgradeDatabase",
"when": "false"

View File

@@ -153,74 +153,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.
*
@@ -552,127 +484,6 @@ export async function convertGithubNwoToDatabaseUrl(
}
}
/**
* 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

@@ -33,7 +33,6 @@ import {
importArchiveDatabase,
promptImportGithubDatabase,
promptImportInternetDatabase,
promptImportLgtmDatabase,
} from "./databaseFetcher";
import { asyncFilter, getErrorMessage } from "./pure/helpers-pure";
import { Credentials } from "./authentication";
@@ -308,15 +307,6 @@ export class DatabaseUI extends DisposableObject {
},
),
);
this.push(
commandRunnerWithProgress(
"codeQLDatabases.chooseDatabaseLgtm",
this.handleChooseDatabaseLgtm,
{
title: "Adding database from LGTM",
},
),
);
this.push(
commandRunner(
"codeQLDatabases.setCurrentDatabase",
@@ -491,19 +481,6 @@ export class DatabaseUI extends DisposableObject {
);
};
handleChooseDatabaseLgtm = async (
progress: ProgressCallback,
token: CancellationToken,
): Promise<DatabaseItem | undefined> => {
return await promptImportLgtmDatabase(
this.databaseManager,
this.storagePath,
progress,
token,
this.queryServer?.cliServer,
);
};
async tryUpgradeCurrentDatabase(
progress: ProgressCallback,
token: CancellationToken,

View File

@@ -1369,16 +1369,6 @@ async function activateWithInstalledDistribution(
},
),
);
ctx.subscriptions.push(
commandRunnerWithProgress(
"codeQL.chooseDatabaseLgtm",
(progress: ProgressCallback, token: CancellationToken) =>
databaseUI.handleChooseDatabaseLgtm(progress, token),
{
title: "Adding database from LGTM",
},
),
);
ctx.subscriptions.push(
commandRunnerWithProgress(
"codeQL.chooseDatabaseInternet",

View File

@@ -5,7 +5,6 @@ import { CodeQLExtensionInterface } from "../../extension";
import { CodeQLCliServer } from "../../cli";
import { DatabaseManager } from "../../databases";
import {
promptImportLgtmDatabase,
importArchiveDatabase,
promptImportInternetDatabase,
} from "../../databaseFetcher";
@@ -17,9 +16,6 @@ jest.setTimeout(60_000);
* Run various integration tests for databases
*/
describe("Databases", () => {
const LGTM_URL =
"https://lgtm.com/projects/g/aeisenberg/angular-bind-notifier/";
let databaseManager: DatabaseManager;
let inputBoxStub: jest.SpiedFunction<typeof window.showInputBox>;
let cli: CodeQLCliServer;
@@ -71,27 +67,6 @@ describe("Databases", () => {
expect(dbItem.databaseUri.fsPath).toBe(join(storagePath, "db", "db"));
});
it("should add a database from lgtm with only one language", async () => {
inputBoxStub.mockResolvedValue(LGTM_URL);
let dbItem = await promptImportLgtmDatabase(
databaseManager,
storagePath,
progressCallback,
{} as CancellationToken,
cli,
);
expect(dbItem).toBeDefined();
dbItem = dbItem!;
expect(dbItem.name).toBe("aeisenberg_angular-bind-notifier_106179a");
expect(dbItem.databaseUri.fsPath).toBe(
join(
storagePath,
"javascript",
"aeisenberg_angular-bind-notifier_106179a",
),
);
});
it("should add a database from a url", async () => {
inputBoxStub.mockResolvedValue(DB_URL);

View File

@@ -5,8 +5,6 @@ import { QuickPickItem, window } from "vscode";
import {
convertGithubNwoToDatabaseUrl,
convertLgtmUrlToDatabaseUrl,
looksLikeLgtmUrl,
findDirWithFile,
} from "../../databaseFetcher";
import * as Octokit from "@octokit/rest";
@@ -131,64 +129,6 @@ describe("databaseFetcher", () => {
});
});
describe("convertLgtmUrlToDatabaseUrl", () => {
let quickPickSpy: jest.SpiedFunction<typeof window.showQuickPick>;
const progressSpy = jest.fn();
beforeEach(() => {
quickPickSpy = jest
.spyOn(window, "showQuickPick")
.mockResolvedValue(undefined);
});
it("should convert a project url to a database url", async () => {
quickPickSpy.mockResolvedValue("javascript" as unknown as QuickPickItem);
const lgtmUrl = "https://lgtm.com/projects/g/github/codeql";
const dbUrl = await convertLgtmUrlToDatabaseUrl(lgtmUrl, progressSpy);
expect(dbUrl).toBe(
"https://lgtm.com/api/v1.0/snapshots/1506465042581/javascript",
);
expect(quickPickSpy).toHaveBeenNthCalledWith(
1,
expect.arrayContaining(["javascript", "python"]),
expect.anything(),
);
});
it("should convert a project url to a database url with extra path segments", async () => {
quickPickSpy.mockResolvedValue("python" as unknown as QuickPickItem);
const lgtmUrl =
"https://lgtm.com/projects/g/github/codeql/subpage/subpage2?query=xxx";
const dbUrl = await convertLgtmUrlToDatabaseUrl(lgtmUrl, progressSpy);
expect(dbUrl).toBe(
"https://lgtm.com/api/v1.0/snapshots/1506465042581/python",
);
expect(progressSpy).toBeCalledTimes(1);
});
it("should convert a raw slug to a database url with extra path segments", async () => {
quickPickSpy.mockResolvedValue("python" as unknown as QuickPickItem);
const lgtmUrl = "g/github/codeql";
const dbUrl = await convertLgtmUrlToDatabaseUrl(lgtmUrl, progressSpy);
expect(dbUrl).toBe(
"https://lgtm.com/api/v1.0/snapshots/1506465042581/python",
);
expect(progressSpy).toBeCalledTimes(1);
});
it("should fail on a nonexistent project", async () => {
quickPickSpy.mockResolvedValue("javascript" as unknown as QuickPickItem);
const lgtmUrl = "https://lgtm.com/projects/g/github/hucairz";
await expect(
convertLgtmUrlToDatabaseUrl(lgtmUrl, progressSpy),
).rejects.toThrow(/Invalid LGTM URL/);
expect(progressSpy).toBeCalledTimes(0);
});
});
describe("looksLikeGithubRepo", () => {
it("should handle invalid urls", () => {
expect(looksLikeGithubRepo("")).toBe(false);
@@ -208,42 +148,6 @@ describe("databaseFetcher", () => {
});
});
describe("looksLikeLgtmUrl", () => {
it("should handle invalid urls", () => {
expect(looksLikeLgtmUrl("")).toBe(false);
expect(looksLikeLgtmUrl("http://lgtm.com/projects/g/github/codeql")).toBe(
false,
);
expect(
looksLikeLgtmUrl("https://ww.lgtm.com/projects/g/github/codeql"),
).toBe(false);
expect(looksLikeLgtmUrl("https://ww.lgtm.com/projects/g/github")).toBe(
false,
);
expect(looksLikeLgtmUrl("g/github")).toBe(false);
expect(looksLikeLgtmUrl("ggg/github/myproj")).toBe(false);
});
it("should handle valid urls", () => {
expect(
looksLikeLgtmUrl("https://lgtm.com/projects/g/github/codeql"),
).toBe(true);
expect(
looksLikeLgtmUrl("https://www.lgtm.com/projects/g/github/codeql"),
).toBe(true);
expect(
looksLikeLgtmUrl("https://lgtm.com/projects/g/github/codeql/sub/pages"),
).toBe(true);
expect(
looksLikeLgtmUrl(
"https://lgtm.com/projects/g/github/codeql/sub/pages?query=string",
),
).toBe(true);
expect(looksLikeLgtmUrl("g/github/myproj")).toBe(true);
expect(looksLikeLgtmUrl("git/github/myproj")).toBe(true);
});
});
describe("findDirWithFile", () => {
let dir: tmp.DirResult;
beforeEach(() => {