public async cmakePreConditionProblemHandler()

in src/cmake-tools.ts [572:701]


    public async cmakePreConditionProblemHandler(e: CMakePreconditionProblems, isConfiguring: boolean, config?: ConfigurationReader): Promise<void> {
        let telemetryEvent: string | undefined;
        const telemetryProperties: telemetry.Properties = {};

        switch (e) {
            case CMakePreconditionProblems.ConfigureIsAlreadyRunning:
                void vscode.window.showErrorMessage(localize('configuration.already.in.progress', 'Configuration is already in progress.'));
                break;
            case CMakePreconditionProblems.BuildIsAlreadyRunning:
                void vscode.window.showErrorMessage(localize('task.already.running', 'A CMake task is already running. Stop it before trying to run a new CMake task.'));
                break;
            case CMakePreconditionProblems.NoSourceDirectoryFound:
                void vscode.window.showErrorMessage(localize('no.source.directory.found', 'You do not have a source directory open'));
                break;
            case CMakePreconditionProblems.MissingCMakeListsFile:
                telemetryEvent = "partialActivation";
                telemetryProperties["ignoreCMakeListsMissing"] = this.workspaceContext.state.ignoreCMakeListsMissing.toString();

                if (!this.workspaceContext.state.ignoreCMakeListsMissing) {
                    const quickStart = localize('quickstart.cmake.project', "Create");
                    const changeSourceDirectory = localize('edit.setting', "Locate");
                    const ignoreCMakeListsMissing = localize('ignore.activation', "Don't show again");

                    let showCMakeLists: boolean = await expShowCMakeLists();
                    const existingCmakeListsFiles: string[] | undefined = await util.getAllCMakeListsPaths(this.folder.uri);
                    if (showCMakeLists) {
                        showCMakeLists = existingCmakeListsFiles !== undefined && existingCmakeListsFiles.length > 0;
                        telemetryProperties["ignoreExperiment"] = (!showCMakeLists).toString();
                    }

                    telemetryProperties["missingCMakeListsPopupType"] = showCMakeLists ? "selectFromAllCMakeLists" : "toastCreateLocateIgnore";

                    const result = showCMakeLists ? changeSourceDirectory : await vscode.window.showErrorMessage(
                        localize('missing.cmakelists', 'CMakeLists.txt was not found in the root of the folder {0}. How would you like to proceed?', `"${this.folderName}"`),
                        quickStart, changeSourceDirectory, ignoreCMakeListsMissing);

                    if (result === quickStart) {
                        // Return here, since the updateFolderFullFeature set below (after the "switch")
                        // will set unnecessarily a partial feature set view for this folder
                        // if quickStart doesn't finish early enough.
                        // quickStart will update correctly the full/partial view state at the end.
                        telemetryProperties["missingCMakeListsUserAction"] = "quickStart";
                        telemetry.logEvent(telemetryEvent, telemetryProperties);
                        return vscode.commands.executeCommand('cmake.quickStart');
                    } else if (result === changeSourceDirectory) {
                        // Open the search file dialog from the path set by cmake.sourceDirectory or from the current workspace folder
                        // if the setting is not defined.
                        interface FileItem extends vscode.QuickPickItem {
                            fullPath: string;
                        }
                        const items: FileItem[] = existingCmakeListsFiles ? existingCmakeListsFiles.map<FileItem>(file => ({
                            label: util.getRelativePath(file, this.folder.uri.fsPath) + "/CMakeLists.txt",
                            fullPath: file
                        })) : [];
                        const browse: string = localize("browse.for.cmakelists", "[Browse for CMakeLists.txt]");
                        items.push({ label: browse, fullPath: "", description: "Search for CMakeLists.txt on this computer" });
                        const selection: FileItem | undefined = await vscode.window.showQuickPick(items, {
                            placeHolder: (items.length === 1 ? localize("cmakelists.not.found", "No CMakeLists.txt was found.") : localize("select.cmakelists", "Select CMakeLists.txt"))
                        });

                        if (showCMakeLists) {
                            telemetryProperties["missingCMakeListsUserAction"] = (selection === undefined) ? "dismissed" : (selection.label === browse) ? "browse" : "pick";
                        } else {
                            telemetryProperties["missingCMakeListsUserAction"] = "changeSourceDirectory";
                        }

                        let selectedFile: string | undefined;
                        if (!selection) {
                            break; // User canceled it.
                        } else if (selection.label === browse) {
                            const openOpts: vscode.OpenDialogOptions = {
                                canSelectMany: false,
                                defaultUri: vscode.Uri.file(this.folder.uri.fsPath),
                                filters: { "CMake files": ["txt"], "All files": ["*"] },
                                openLabel: "Load"
                            };
                            const cmakeListsFile = await vscode.window.showOpenDialog(openOpts);
                            if (cmakeListsFile) {
                                selectedFile = cmakeListsFile[0].fsPath;
                            }
                        } else {
                            selectedFile = selection.fullPath;
                        }
                        if (selectedFile) {
                            const relPath = util.getRelativePath(selectedFile, this.folder.uri.fsPath);
                            void vscode.workspace.getConfiguration('cmake', this.folder.uri).update("sourceDirectory", relPath);
                            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
                                // another immediate configure, which will be blocked anyway).
                                config.updatePartial({ sourceDirectory: relPath }, false);

                                // Since the source directory is set via a file open dialog tuned to CMakeLists.txt,
                                // we know that it exists and we don't need any other additional checks on its value,
                                // so simply enable full feature set.
                                await enableFullFeatureSet(true);

                                if (!isConfiguring) {
                                    telemetry.logEvent(telemetryEvent, telemetryProperties);
                                    return vscode.commands.executeCommand('cmake.configure');
                                }
                            }
                        }
                    } else if (result === ignoreCMakeListsMissing) {
                        // The user ignores the missing CMakeLists.txt file --> limit the CMake Tools extension functionality
                        // (hide commands and status bar) and record this choice so that this popup doesn't trigger next time.
                        // The switch back to full functionality can be done later by changes to the cmake.sourceDirectory setting
                        // or to the CMakeLists.txt file, a successful configure or a configure failing with anything but CMakePreconditionProblems.MissingCMakeListsFile.
                        // After that switch (back to a full activation), another occurrence of missing CMakeLists.txt
                        // would trigger this popup again.
                        telemetryProperties["missingCMakeListsUserAction"] = "ignore";
                        await this.workspaceContext.state.setIgnoreCMakeListsMissing(true);
                    } else {
                        // "invalid" normally shouldn't happen since the popup can be closed by either dismissing it or clicking any of the three buttons.
                        telemetryProperties["missingCMakeListsUserAction"] = (result === undefined) ? "dismissed" : "invalid";
                    }
                }

                break;
        }

        if (telemetryEvent) {
            telemetry.logEvent(telemetryEvent, telemetryProperties);
        }

        // This CMT folder can go through various changes while executing this function
        // that could be relevant to the partial/full feature set view.
        // This is a good place for an update.
        return updateFullFeatureSetForFolder(this.folder);
    }