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
9 changes: 0 additions & 9 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -149,15 +149,6 @@ export async function activate(

registerBuildifierFormatter();

// if this is a multi-root project, create a listener to refresh the symlinked project root directory on file add/remove
if (ProjectViewManager.isMultiRoot()) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why remove this? As my understanding user will never use multi-root mode, case our workspace configuration is force configured to be single-root mode. right?
maybe I missed something, could you explain more?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not mandatory to use single-root mode. When a user opens the plugin through code-workspace, it will load in multi-root mode. Previously, it was always in single-root mode because an incorrect logic for retrieving the project root directory caused multi-root mode loading to fail, after which it started loading in single-root mode.

The logic for synchronizing files in the project root directory was removed here. The original design synchronized files under ~/development/urbancompass to ~/urbancompass, which was what the ProjectViewManager.syncWorkspaceRoot method did. However, this design conflicted with our usage guidelines. Therefore, I removed this logic and instead directly added ~/development/urbancompass to the workspace as the project root directory. Thus, the file monitoring logic can be removed.

const w = workspace.createFileSystemWatcher(
new RelativePattern(workspaceRoot, '*')
);
w.onDidCreate((_e) => ProjectViewManager.syncWorkspaceRoot());
w.onDidDelete((_e) => ProjectViewManager.syncWorkspaceRoot());
}

// trigger a refresh of the tree view when any task get executed
tasks.onDidStartTask((_) => BazelRunTargetProvider.instance.refresh());
tasks.onDidEndTask((_) => BazelRunTargetProvider.instance.refresh());
Expand Down
73 changes: 24 additions & 49 deletions src/projectViewManager.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,4 @@
import {
existsSync,
mkdirSync,
readdirSync,
rmSync,
statSync,
symlinkSync,
writeFileSync,
} from 'fs';
import { homedir } from 'os';
import { writeFileSync } from 'fs';
import { sep } from 'path';
import {
commands,
Expand All @@ -24,8 +15,17 @@ import { getVscodeConfig, getWorkspaceRoot } from './util';

export namespace ProjectViewManager {
const workspaceRoot = getWorkspaceRoot();
const workspaceRootName = workspaceRoot.split('/').reverse()[0];
const projectRootSymlinks = `${homedir}${sep}${workspaceRootName}`;
const workspaceRootName = getWorkspaceRootName();

function getWorkspaceRootName(): string {
const name = workspaceRoot.split('/').reverse()[0];
if (!name || name.trim() === '') {
throw new Error(
`Invalid workspace root path, cannot extract name: ${workspaceRoot}`
);
}
return name;
}

export function isMultiRoot(): boolean {
return !!workspace.workspaceFile;
Expand Down Expand Up @@ -93,10 +93,6 @@ export namespace ProjectViewManager {

async function getDisplayFolders(): Promise<string[]> {
let displayFolders = new Set<string>(['.eclipse']); // TODO bubble this out to a setting
if (isMultiRoot()) {
syncWorkspaceRoot();
displayFolders.add(projectRootSymlinks);
}
try {
const bazelProjectFile = await getBazelProjectFile();
if (bazelProjectFile.directories.includes('.')) {
Expand Down Expand Up @@ -149,22 +145,21 @@ export namespace ProjectViewManager {
function updateMultiRootProjectView(
displayFolders: string[]
): Thenable<string[]> {
// 1. workspaceRoot as the first workspace folder, so ${workspaceFolder} resolves to the real project path
// 2. Other subdirectories serve as quick access entries
const workspaceFoldersToAdd = [
{ uri: Uri.file(workspaceRoot), name: workspaceRootName },
...displayFolders
.filter((f) => f !== '.') // Exclude '.' since workspaceRoot already represents the root directory
.map((f) => ({
uri: Uri.file(`${workspaceRoot}/${f}`),
name: f.replaceAll(sep, ' ⇾ '),
})),
];
workspace.updateWorkspaceFolders(
0,
workspace.workspaceFolders?.length,
...displayFolders.map((f) => {
if (f === projectRootSymlinks) {
return {
uri: Uri.file(projectRootSymlinks),
name: workspaceRootName,
};
} else {
return {
uri: Uri.file(`${workspaceRoot}/${f}`),
name: f.replaceAll(sep, ' ⇾ '),
};
}
})
...workspaceFoldersToAdd
);
return Promise.resolve(displayFolders);
}
Expand Down Expand Up @@ -258,24 +253,4 @@ export namespace ProjectViewManager {
function rootDirOnly(dirs: string[]): string[] {
return dirs.map((d) => d.split('/')[0]);
}

export function syncWorkspaceRoot() {
if (existsSync(projectRootSymlinks)) {
rmSync(projectRootSymlinks, { recursive: true }); // delete
}

mkdirSync(projectRootSymlinks);

readdirSync(workspaceRoot).forEach((f) => {
const fpath = `${workspaceRoot}${sep}${f}`;
if (existsSync(fpath)) {
const stats = statSync(fpath);
if (stats.isFile()) {
symlinkSync(fpath, `${projectRootSymlinks}${sep}${f}`);
}
}
});

commands.executeCommand('workbench.files.action.refreshFilesExplorer');
}
}
6 changes: 5 additions & 1 deletion src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ derive_targets_from_directories: true

export function getWorkspaceRoot(): string {
if (workspace.workspaceFile) {
return dirname(workspace.workspaceFile.path);
const workspaceFilePath = dirname(workspace.workspaceFile.path);
if (workspaceFilePath.endsWith('.vscode')) {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What this means? could tell me an example? Thanks!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the loaded project is loaded through the code-workspace file, as shown in the image below, the workspaceFile.path is <repoRoot>/.vscode, which is not the desired <repoRoot> directory

Image

return dirname(workspaceFilePath);
}
return workspaceFilePath;
} else {
if (workspace.workspaceFolders && workspace.workspaceFolders.length > 0) {
return workspace.workspaceFolders[0].uri.path;
Expand Down