Skip to content

Commit

Permalink
Check if "CMakeLists.txt" exists, currently or after renaming (#2946)
Browse files Browse the repository at this point in the history
  • Loading branch information
elahehrashedi authored Jan 30, 2023
1 parent defb0ad commit 013a2ee
Show file tree
Hide file tree
Showing 5 changed files with 51 additions and 62 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,11 @@ Improvements:
- Add an optional description field to kits. [PR #2944](https://github.com/microsoft/vscode-cmake-tools/pull/2944) [@TisziV](https://github.com/TisziV)

Bug Fixes:
- Compatibility between test and build presets was not enforced. [#2904](https://github.com/microsoft/vscode-cmake-tools/issues/2904)
- Check if "CMakeLists.txt" exists after renaming. [#2986](https://github.com/microsoft/vscode-cmake-tools/issues/2986)

## 1.13.44
Bug Fixes:
- Compatibility between test and build presets was not enforced. [#2904](https://github.com/microsoft/vscode-cmake-tools/issues/2904)
- Fix problems with updating the code model. [#2980](https://github.com/microsoft/vscode-cmake-tools/issues/2980)
- Validate presets in initialization. [#2976](https://github.com/microsoft/vscode-cmake-tools/issues/2976)

Expand Down
59 changes: 19 additions & 40 deletions src/cmakeProject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { CTestDriver, BasicTestResults } from './ctest';
import { CMakeBuildConsumer } from './diagnostics/build';
import { CMakeOutputConsumer } from './diagnostics/cmake';
import { populateCollection } from './diagnostics/util';
import { expandStrings, expandString, ExpansionOptions, KitContextVars } from './expand';
import { expandStrings, expandString, ExpansionOptions } from './expand';
import { CMakeGenerator, Kit } from './kit';
import * as logging from './logging';
import { fs } from './pr';
Expand Down Expand Up @@ -685,8 +685,8 @@ export class CMakeProject {
}
if (selectedFile) {
const newSourceDirectory = path.dirname(selectedFile);
void vscode.workspace.getConfiguration('cmake', this.workspaceFolder.uri).update("sourceDirectory", newSourceDirectory);
this._sourceDir = newSourceDirectory;
await this.setSourceDir(await util.normalizeAndVerifySourceDir(newSourceDirectory, CMakeDriver.sourceDirExpansionOptions(this.workspaceContext.folder.uri.fsPath)));
void vscode.workspace.getConfiguration('cmake', this.workspaceFolder.uri).update("sourceDirectory", this._sourceDir);
if (config) {
// Updating sourceDirectory here, at the beginning of the configure process,
// doesn't need to fire the settings change event (which would trigger unnecessarily
Expand Down Expand Up @@ -888,7 +888,7 @@ export class CMakeProject {
*/
private async init(sourceDirectory: string) {
log.debug(localize('second.phase.init', 'Starting CMake Tools second-phase init'));
this._sourceDir = await util.normalizeAndVerifySourceDir(sourceDirectory, CMakeDriver.sourceDirExpansionOptions(this.workspaceContext.folder.uri.fsPath));
await this.setSourceDir(await util.normalizeAndVerifySourceDir(sourceDirectory, CMakeDriver.sourceDirExpansionOptions(this.workspaceContext.folder.uri.fsPath)));

// Start up the variant manager
await this.variantManager.initialize();
Expand Down Expand Up @@ -946,7 +946,7 @@ export class CMakeProject {
if (usingCMakePresets) {
const setPresetsFileLanguageMode = (document: vscode.TextDocument) => {
const fileName = path.basename(document.uri.fsPath);
if (util.isFileInsideFolder(document, this.folderPath) && fileName === 'CMakePresets.json' || fileName === 'CMakeUserPresets.json') {
if (util.isFileInsideFolder(document.uri, this.folderPath) && fileName === 'CMakePresets.json' || fileName === 'CMakeUserPresets.json') {
if (config.allowCommentsInPresetsFile && document.languageId !== 'jsonc') {
// setTextDocumentLanguage will trigger onDidOpenTextDocument
void vscode.languages.setTextDocumentLanguage(document, 'jsonc');
Expand Down Expand Up @@ -1498,8 +1498,8 @@ export class CMakeProject {
}

// Reconfigure if the saved file is a cmake file.
async doCMakeFileSaveReconfigure(textDocument: vscode.TextDocument) {
const filePath = util.platformNormalizePath(textDocument.uri.fsPath);
async doCMakeFileChangeReconfigure(uri: vscode.Uri) {
const filePath = util.platformNormalizePath(uri.fsPath);
const driver: CMakeDriver | null = await this.getCMakeDriverInstance();

// If we detect a change in the CMake cache file, refresh the webview
Expand Down Expand Up @@ -2488,6 +2488,16 @@ export class CMakeProject {
return this._sourceDir;
}

async setSourceDir(sourceDir: string) {
this._sourceDir = sourceDir;
this.cmakeListsExists = await fs.exists(path.join(this._sourceDir, "CMakeLists.txt"));
}

private cmakeListsExists: boolean = false;
hasCMakeLists(): boolean {
return this.cmakeListsExists;
}

get mainListFile() {
const drv = this.getCMakeDriverInstance();

Expand Down Expand Up @@ -2588,8 +2598,8 @@ export class CMakeProject {
return expandStrings(this.workspaceContext.config.additionalKits, opts);
}

async sendFileTypeTelemetry(textDocument: vscode.TextDocument): Promise<void> {
const filePath = util.platformNormalizePath(textDocument.uri.fsPath);
async sendFileTypeTelemetry(uri: vscode.Uri): Promise<void> {
const filePath = util.platformNormalizePath(uri.fsPath);
const sourceDirectory = util.platformNormalizePath(this.sourceDir);
// "outside" evaluates whether the modified cmake file belongs to the project.
let outside: boolean = true;
Expand Down Expand Up @@ -2669,37 +2679,6 @@ export class CMakeProject {
return this.onUseCMakePresetsChangedEmitter.event;
}

async hasCMakeLists(): Promise<boolean> {
const optsVars: KitContextVars = {
// sourceDirectory cannot be defined based on any of the below variables.
buildKit: '${buildKit}',
buildType: '${buildType}',
buildKitVendor: '${buildKitVendor}',
buildKitTriple: '${buildKitTriple}',
buildKitVersion: '${buildKitVersion}',
buildKitHostOs: '${buildKitVendor}',
buildKitTargetOs: '${buildKitTargetOs}',
buildKitTargetArch: '${buildKitTargetArch}',
buildKitVersionMajor: '${buildKitVersionMajor}',
buildKitVersionMinor: '${buildKitVersionMinor}',
generator: '${generator}',
userHome: paths.userHome,
workspaceFolder: this.workspaceContext.folder.uri.fsPath,
workspaceFolderBasename: this.workspaceContext.folder.name,
workspaceHash: '${workspaceHash}',
workspaceRoot: this.workspaceContext.folder.uri.fsPath,
workspaceRootFolderName: this.workspaceContext.folder.name,
sourceDir: this.sourceDir
};

const sourceDirectory: string = this.sourceDir;
let expandedSourceDirectory: string = util.lightNormalizePath(await expandString(sourceDirectory, { vars: optsVars }));
if (path.basename(expandedSourceDirectory).toLocaleLowerCase() !== "cmakelists.txt") {
expandedSourceDirectory = path.join(expandedSourceDirectory, "CMakeLists.txt");
}
return fs.exists(expandedSourceDirectory);
}

}

export default CMakeProject;
17 changes: 6 additions & 11 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,7 +127,7 @@ export class ExtensionManager implements vscode.Disposable {
await util.setContextValue(multiProjectModeKey, this.projectController.hasMultipleProjects);
// Update the full/partial view of the workspace by verifying if after the folder removal
// it still has at least one CMake project.
await enableFullFeatureSet(await this.workspaceHasAtLeastOneProject());
await enableFullFeatureSet(this.workspaceHasAtLeastOneProject());
}

this.projectOutlineProvider.removeFolder(folder);
Expand Down Expand Up @@ -177,7 +177,7 @@ export class ExtensionManager implements vscode.Disposable {
}
await this.initActiveProject();
}
const isFullyActivated: boolean = await this.workspaceHasAtLeastOneProject();
const isFullyActivated: boolean = this.workspaceHasAtLeastOneProject();
await enableFullFeatureSet(isFullyActivated);

const telemetryProperties: telemetry.Properties = {
Expand Down Expand Up @@ -464,7 +464,7 @@ export class ExtensionManager implements vscode.Disposable {
}
}
if (project) {
if (!await project.hasCMakeLists()) {
if (!project.hasCMakeLists()) {
await project.cmakePreConditionProblemHandler(CMakePreconditionProblems.MissingCMakeListsFile, false, this.workspaceConfig);
} else {
if (shouldConfigure === true) {
Expand Down Expand Up @@ -1419,17 +1419,12 @@ export class ExtensionManager implements vscode.Disposable {

// Answers whether the workspace contains at least one project folder that is CMake based,
// without recalculating the valid states of CMakeLists.txt.
async workspaceHasAtLeastOneProject(): Promise<boolean> {
workspaceHasAtLeastOneProject(): boolean {
const projects: CMakeProject[] | undefined = this.projectController.getAllCMakeProjects();
if (!projects || projects.length === 0) {
return false;
}
for (const project of projects) {
if (await project.hasCMakeLists()) {
return true;
}
}
return false;
return projects.some(project => project.hasCMakeLists());
}

activeConfigurePresetName(): string {
Expand Down Expand Up @@ -1812,7 +1807,7 @@ export function getActiveProject(): CMakeProject | undefined {
// sourceDirectory change, CMakeLists.txt creation/move/deletion.
export async function updateFullFeatureSet() {
if (extensionManager) {
await enableFullFeatureSet(await extensionManager.workspaceHasAtLeastOneProject());
await enableFullFeatureSet(extensionManager.workspaceHasAtLeastOneProject());
} else {
// This shouldn't normally happen (not finding a cmake project or not having a valid extension manager)
// but just in case, disable full feature set.
Expand Down
30 changes: 22 additions & 8 deletions src/projectController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ export class ProjectController implements vscode.Disposable {
if (projects && projects.length > 0) {
if (openEditor) {
for (const project of projects) {
if (util.isFileInsideFolder(openEditor.document, project.folderPath)) {
if (util.isFileInsideFolder(openEditor.document.uri, project.folderPath)) {
this.setActiveProject(project);
break;
}
}
if (!this.activeProject) {
if (util.isFileInsideFolder(openEditor.document, projects[0].workspaceFolder.uri.fsPath)) {
if (util.isFileInsideFolder(openEditor.document.uri, projects[0].workspaceFolder.uri.fsPath)) {
this.setActiveProject(projects[0]);
}
}
Expand Down Expand Up @@ -114,10 +114,10 @@ export class ProjectController implements vscode.Disposable {
return this.getAllCMakeProjects().length;
}

async getNumOfValidProjects(): Promise<number> {
getNumOfValidProjects(): number {
let count: number = 0;
for (const project of this.getAllCMakeProjects()) {
count += (await project.hasCMakeLists() ? 1 : 0);
count += project.hasCMakeLists() ? 1 : 0;
}
return count;
}
Expand All @@ -144,7 +144,8 @@ export class ProjectController implements vscode.Disposable {
vscode.workspace.onDidChangeWorkspaceFolders(
e => rollbar.invokeAsync(localize('update.workspace.folders', 'Update workspace folders'), () => this.doWorkspaceFolderChange(e))),
vscode.workspace.onDidOpenTextDocument((textDocument: vscode.TextDocument) => this.doOpenTextDocument(textDocument)),
vscode.workspace.onDidSaveTextDocument((textDocument: vscode.TextDocument) => this.doSaveTextDocument(textDocument))
vscode.workspace.onDidSaveTextDocument((textDocument: vscode.TextDocument) => this.doSaveTextDocument(textDocument)),
vscode.workspace.onDidRenameFiles(this.onDidRenameFiles, this)
];
}

Expand Down Expand Up @@ -441,13 +442,26 @@ export class ProjectController implements vscode.Disposable {
}

private async doSaveTextDocument(textDocument: vscode.TextDocument): Promise<void> {
await this.doCMakeFileChangeReconfigure(textDocument.uri);
}

private async onDidRenameFiles(renamedFileEvt: vscode.FileRenameEvent): Promise<void> {
for (const file of renamedFileEvt.files) {
const filePath = file.newUri.fsPath.toLowerCase();
if (filePath.endsWith("cmakelists.txt")) {
await this.doCMakeFileChangeReconfigure(file.newUri);
}
}
}

private async doCMakeFileChangeReconfigure(uri: vscode.Uri): Promise<void> {
const activeProject: CMakeProject | undefined = this.getActiveCMakeProject();
if (activeProject) {
const isFileInsideActiveProject: boolean = util.isFileInsideFolder(textDocument, activeProject.isMultiProjectFolder ? activeProject.folderPath : activeProject.workspaceFolder.uri.fsPath);
const isFileInsideActiveProject: boolean = util.isFileInsideFolder(uri, activeProject.isMultiProjectFolder ? activeProject.folderPath : activeProject.workspaceFolder.uri.fsPath);
if (isFileInsideActiveProject) {
await activeProject.doCMakeFileSaveReconfigure(textDocument);
await activeProject.doCMakeFileChangeReconfigure(uri);
}
await activeProject.sendFileTypeTelemetry(textDocument);
await activeProject.sendFileTypeTelemetry(uri);
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -864,9 +864,9 @@ export async function scheduleAsyncTask<T>(task: () => Promise<T>): Promise<T> {
});
}

export function isFileInsideFolder(openEditor: vscode.TextDocument, folderPath: string): boolean {
export function isFileInsideFolder(uri: vscode.Uri, folderPath: string): boolean {
const parent = platformNormalizePath(folderPath);
const file = platformNormalizePath(openEditor.uri.fsPath);
const file = platformNormalizePath(uri.fsPath);
return file.startsWith(parent);
}

Expand Down

0 comments on commit 013a2ee

Please sign in to comment.