Add detection of root workspace directory using .git folder
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
import { Uri, window, workspace, WorkspaceFolder } from "vscode";
|
import { FileType, Uri, window, workspace, WorkspaceFolder } from "vscode";
|
||||||
import { getOnDiskWorkspaceFoldersObjects } from "../common/vscode/workspace-folders";
|
import { getOnDiskWorkspaceFoldersObjects } from "../common/vscode/workspace-folders";
|
||||||
import { extLogger } from "../common";
|
import { extLogger } from "../common";
|
||||||
import { tmpdir } from "../pure/files";
|
import { tmpdir } from "../pure/files";
|
||||||
@@ -20,7 +20,7 @@ function getAncestors(uri: Uri): Uri[] {
|
|||||||
return ancestors;
|
return ancestors;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getRootWorkspaceDirectory(): Uri | undefined {
|
async function getRootWorkspaceDirectory(): Promise<Uri | undefined> {
|
||||||
// If there is a valid workspace file, just use its directory as the directory for the extensions
|
// If there is a valid workspace file, just use its directory as the directory for the extensions
|
||||||
const workspaceFile = workspace.workspaceFile;
|
const workspaceFile = workspace.workspaceFile;
|
||||||
if (workspaceFile?.scheme === "file") {
|
if (workspaceFile?.scheme === "file") {
|
||||||
@@ -56,7 +56,7 @@ function getRootWorkspaceDirectory(): Uri | undefined {
|
|||||||
}, getAncestors(workspaceFolders[0].uri));
|
}, getAncestors(workspaceFolders[0].uri));
|
||||||
|
|
||||||
if (commonRoot.length === 0) {
|
if (commonRoot.length === 0) {
|
||||||
return undefined;
|
return await findGitFolder(workspaceFolders);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The path closest to the workspace folders is the last element of the common root
|
// The path closest to the workspace folders is the last element of the common root
|
||||||
@@ -65,12 +65,65 @@ function getRootWorkspaceDirectory(): Uri | undefined {
|
|||||||
// If we are at the root of the filesystem, we can't go up any further and there's something
|
// If we are at the root of the filesystem, we can't go up any further and there's something
|
||||||
// wrong, so just return undefined
|
// wrong, so just return undefined
|
||||||
if (commonRootUri.fsPath === Uri.joinPath(commonRootUri, "..").fsPath) {
|
if (commonRootUri.fsPath === Uri.joinPath(commonRootUri, "..").fsPath) {
|
||||||
return undefined;
|
return await findGitFolder(workspaceFolders);
|
||||||
}
|
}
|
||||||
|
|
||||||
return commonRootUri;
|
return commonRootUri;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function findGitFolder(
|
||||||
|
workspaceFolders: WorkspaceFolder[],
|
||||||
|
): Promise<Uri | undefined> {
|
||||||
|
// Go through all workspace folders one-by-one and try to find the closest .git folder for each one
|
||||||
|
const folders = await Promise.all(
|
||||||
|
workspaceFolders.map(async (folder) => {
|
||||||
|
const ancestors = getAncestors(folder.uri);
|
||||||
|
|
||||||
|
// Reverse the ancestors so we're going from closest to furthest
|
||||||
|
ancestors.reverse();
|
||||||
|
|
||||||
|
const gitFoldersExists = await Promise.all(
|
||||||
|
ancestors.map(async (uri) => {
|
||||||
|
const gitFolder = Uri.joinPath(uri, ".git");
|
||||||
|
try {
|
||||||
|
const stat = await workspace.fs.stat(gitFolder);
|
||||||
|
// Check whether it's a directory
|
||||||
|
return (stat.type & FileType.Directory) !== 0;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// Find the first ancestor that has a .git folder
|
||||||
|
const ancestorIndex = gitFoldersExists.findIndex((exists) => exists);
|
||||||
|
|
||||||
|
if (ancestorIndex === -1) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return [ancestorIndex, ancestors[ancestorIndex]];
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
const validFolders = folders.filter(
|
||||||
|
(folder): folder is [number, Uri] => folder !== undefined,
|
||||||
|
);
|
||||||
|
if (validFolders.length === 0) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the .git folder which is closest to a workspace folder
|
||||||
|
const closestFolder = validFolders.reduce((closestFolder, folder) => {
|
||||||
|
if (folder[0] < closestFolder[0]) {
|
||||||
|
return folder;
|
||||||
|
}
|
||||||
|
return closestFolder;
|
||||||
|
}, validFolders[0]);
|
||||||
|
|
||||||
|
return closestFolder?.[1];
|
||||||
|
}
|
||||||
|
|
||||||
export async function autoPickExtensionsDirectory(): Promise<Uri | undefined> {
|
export async function autoPickExtensionsDirectory(): Promise<Uri | undefined> {
|
||||||
const workspaceFolders = getOnDiskWorkspaceFoldersObjects();
|
const workspaceFolders = getOnDiskWorkspaceFoldersObjects();
|
||||||
|
|
||||||
@@ -94,7 +147,7 @@ export async function autoPickExtensionsDirectory(): Promise<Uri | undefined> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get the root workspace directory, i.e. the common root directory of all workspace folders
|
// Get the root workspace directory, i.e. the common root directory of all workspace folders
|
||||||
const rootDirectory = getRootWorkspaceDirectory();
|
const rootDirectory = await getRootWorkspaceDirectory();
|
||||||
if (!rootDirectory) {
|
if (!rootDirectory) {
|
||||||
void extLogger.log("Unable to determine root workspace directory");
|
void extLogger.log("Unable to determine root workspace directory");
|
||||||
|
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { dir, DirectoryResult } from "tmp-promise";
|
|||||||
import { join } from "path";
|
import { join } from "path";
|
||||||
import { autoPickExtensionsDirectory } from "../../../../src/data-extensions-editor/extensions-workspace-folder";
|
import { autoPickExtensionsDirectory } from "../../../../src/data-extensions-editor/extensions-workspace-folder";
|
||||||
import * as files from "../../../../src/pure/files";
|
import * as files from "../../../../src/pure/files";
|
||||||
|
import { mkdirp } from "fs-extra";
|
||||||
|
|
||||||
describe("autoPickExtensionsDirectory", () => {
|
describe("autoPickExtensionsDirectory", () => {
|
||||||
let tmpDir: DirectoryResult;
|
let tmpDir: DirectoryResult;
|
||||||
@@ -187,4 +188,27 @@ describe("autoPickExtensionsDirectory", () => {
|
|||||||
expect(await autoPickExtensionsDirectory()).toEqual(undefined);
|
expect(await autoPickExtensionsDirectory()).toEqual(undefined);
|
||||||
expect(updateWorkspaceFoldersSpy).not.toHaveBeenCalled();
|
expect(updateWorkspaceFoldersSpy).not.toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("when a workspace file does not exist and there is a .git folder", async () => {
|
||||||
|
await mkdirp(join(rootDirectory.fsPath, ".git"));
|
||||||
|
|
||||||
|
workspaceFoldersSpy.mockReturnValue([
|
||||||
|
{
|
||||||
|
uri: Uri.joinPath(rootDirectory, "codeql-custom-queries-java"),
|
||||||
|
name: "codeql-custom-queries-java",
|
||||||
|
index: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
uri: Uri.file("/a/b/c"),
|
||||||
|
name: "codeql-custom-queries-python",
|
||||||
|
index: 1,
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(await autoPickExtensionsDirectory()).toEqual(extensionsDirectory);
|
||||||
|
expect(updateWorkspaceFoldersSpy).toHaveBeenCalledWith(2, 0, {
|
||||||
|
name: "CodeQL Extension Packs",
|
||||||
|
uri: extensionsDirectory,
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user