Add public API (#2794)
This commit is contained in:
Родитель
cd555861b4
Коммит
e7ed1b7dcd
|
@ -2114,6 +2114,7 @@
|
|||
"tslint": "^6.1.3",
|
||||
"typescript": "^4.1.5",
|
||||
"vsce": "^2.7.0",
|
||||
"vscode-cmake-tools": "^1.0.0",
|
||||
"vscode-nls-dev": "^3.3.2",
|
||||
"webpack": "^5.38.1",
|
||||
"webpack-cli": "^4.5.0"
|
||||
|
|
404
src/api.ts
404
src/api.ts
|
@ -1,317 +1,101 @@
|
|||
/**
|
||||
* This module defines the external API for the extension. Other
|
||||
* extensions can access this API via the exports instance for the extension.
|
||||
*
|
||||
* Look at the `CMakeToolsAPI` interface for the actual exported API.
|
||||
*
|
||||
* Copy the `api.ts` source file into your project to use it.
|
||||
*/ /** */
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { DebugSession, Disposable, Event, Terminal } from 'vscode';
|
||||
import * as vscode from 'vscode';
|
||||
import * as api from 'vscode-cmake-tools';
|
||||
import CMakeProject from '@cmt/cmakeProject';
|
||||
import { ExtensionManager } from '@cmt/extension';
|
||||
import { assertNever } from '@cmt/util';
|
||||
|
||||
/**
|
||||
* The result of executing a program.
|
||||
*/
|
||||
export interface ExecutionResult {
|
||||
/**
|
||||
* The return code of the program.
|
||||
*/
|
||||
retc: number | null;
|
||||
/**
|
||||
* The full standard output of the program. May be `` if standard out
|
||||
* was not captured.
|
||||
*/
|
||||
stdout: string;
|
||||
/**
|
||||
* Standard error output of the program. May be `` if standard error was
|
||||
* not captured
|
||||
*/
|
||||
stderr: string;
|
||||
export class CMakeToolsApiImpl implements api.CMakeToolsApi {
|
||||
constructor(private readonly manager: ExtensionManager) {}
|
||||
|
||||
version: api.Version = api.Version.v1;
|
||||
|
||||
showUIElement(element: api.UIElement): Promise<void> {
|
||||
return this.setUIElementVisibility(element, true);
|
||||
}
|
||||
|
||||
hideUIElement(element: api.UIElement): Promise<void> {
|
||||
return this.setUIElementVisibility(element, false);
|
||||
}
|
||||
|
||||
get onBuildTargetChanged() {
|
||||
return this.manager.onBuildTargetChanged;
|
||||
}
|
||||
|
||||
get onLaunchTargetChanged() {
|
||||
return this.manager.onLaunchTargetChanged;
|
||||
}
|
||||
|
||||
get onActiveProjectChanged() {
|
||||
return this.manager.onActiveProjectChanged;
|
||||
}
|
||||
|
||||
async getProject(uri: vscode.Uri) {
|
||||
const project = this.manager.cmakeWorkspaceFolders.get([uri.fsPath])?.cmakeProject;
|
||||
return project && new CMakeProjectWrapper(project);
|
||||
}
|
||||
|
||||
private async setUIElementVisibility(element: api.UIElement, visible: boolean): Promise<void> {
|
||||
switch (element) {
|
||||
case api.UIElement.StatusBarDebugButton:
|
||||
await this.manager.hideDebugCommand(!visible);
|
||||
break;
|
||||
case api.UIElement.StatusBarLaunchButton:
|
||||
await this.manager.hideLaunchCommand(!visible);
|
||||
break;
|
||||
default:
|
||||
assertNever(element);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Options for executing a command.
|
||||
*/
|
||||
export interface ExecutionOptions {
|
||||
/**
|
||||
* Whether output from the command should be suppressed from CMake Tools'
|
||||
* output channel.
|
||||
*/
|
||||
silent: boolean;
|
||||
/**
|
||||
* Additional environment variables to define when executing the command.
|
||||
*/
|
||||
environment: { [key: string]: string };
|
||||
/**
|
||||
* Whether we should collect output from the command.
|
||||
*
|
||||
* @note All output from the command is collected into a single string, so
|
||||
* commands which emit a lot of output may consume a lot of memory if
|
||||
* `collectOutput` is set to `true`.
|
||||
*/
|
||||
collectOutput?: boolean;
|
||||
/**
|
||||
* The working directory for the command. The default directory is
|
||||
* unspecified.
|
||||
*/
|
||||
workingDirectory?: string;
|
||||
async function withErrorCheck(name: string, action: () => Thenable<number>): Promise<void> {
|
||||
const code = await action();
|
||||
if (code !== 0) {
|
||||
throw new Error(`${name} failed with code ${code}`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The type of a CMake cache entry
|
||||
*/
|
||||
export enum CacheEntryType {
|
||||
Bool = 0,
|
||||
String = 1,
|
||||
Path = 2,
|
||||
FilePath = 3,
|
||||
Internal = 4,
|
||||
Uninitialized = 5,
|
||||
Static = 6,
|
||||
}
|
||||
|
||||
/**
|
||||
* Information about a CTest test
|
||||
*/
|
||||
export interface Test {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* The properties of a CMake cache entry.
|
||||
*/
|
||||
export interface CacheEntryProperties {
|
||||
type: CacheEntryType;
|
||||
helpString: string;
|
||||
/** The name of the cache entry */
|
||||
key: string;
|
||||
/** The entry's value. Type depends on `type`. */
|
||||
value: any;
|
||||
/** Whether this entry is ADVANCED, meaning it hidden from the user. */
|
||||
advanced: boolean;
|
||||
/** List of allowed values, as specified by STRINGS property */
|
||||
choices: string[];
|
||||
}
|
||||
|
||||
/**
|
||||
* A cache entry from a CMake cache.
|
||||
*/
|
||||
export interface CacheEntry extends CacheEntryProperties {
|
||||
/**
|
||||
* Return the value as a `T` instance. Does no actual conversion. It's up to
|
||||
* you to check the value of `CacheEntryProperties.type`.
|
||||
*/
|
||||
as<T>(): T;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of an executable CMake target, defined via `add_executable()`.
|
||||
*/
|
||||
export interface ExecutableTarget {
|
||||
/**
|
||||
* The name of the target.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* The absolute path to the build output.
|
||||
*/
|
||||
path: string;
|
||||
}
|
||||
|
||||
export interface VariantKeywordSettings {
|
||||
[key: string]: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A target with a name, but no output. This may be created via `add_custom_command()`.
|
||||
*/
|
||||
export interface NamedTarget {
|
||||
type: 'named';
|
||||
name: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A target with a name, path, and type.
|
||||
*/
|
||||
export interface RichTarget {
|
||||
type: 'rich';
|
||||
name: string;
|
||||
filepath: string;
|
||||
targetType: string;
|
||||
}
|
||||
|
||||
export type Target = NamedTarget | RichTarget;
|
||||
|
||||
/**
|
||||
* The CMake Tools extension API obtained via `getExtension().exports`
|
||||
*/
|
||||
export interface CMakeToolsAPI extends Disposable {
|
||||
|
||||
/**
|
||||
* The source directory, containing the root of the project
|
||||
*/
|
||||
readonly sourceDir: string;
|
||||
/**
|
||||
* The `CMakeLists.txt` at to the root of the project
|
||||
*/
|
||||
readonly mainListFile: Thenable<string>;
|
||||
/**
|
||||
* The root build directory for the project. May change based on build
|
||||
* configuration.
|
||||
*/
|
||||
readonly binaryDir: Thenable<string>;
|
||||
/**
|
||||
* The path to the `CMakeCache.txt for the project.
|
||||
*/
|
||||
readonly cachePath: Thenable<string>;
|
||||
/**
|
||||
* List of CMake targets created via `add_executable()`.
|
||||
*/
|
||||
readonly executableTargets: Thenable<ExecutableTarget[]>;
|
||||
/**
|
||||
* All targets available to be built
|
||||
*/
|
||||
readonly targets: Thenable<Target[]>;
|
||||
/**
|
||||
* Event fired when the configure/generate stage completes
|
||||
*/
|
||||
readonly onReconfigured: Event<void>;
|
||||
/**
|
||||
* Event fired when the active target changes.
|
||||
*/
|
||||
readonly onTargetChanged: Event<void>;
|
||||
|
||||
/**
|
||||
* Execute a command using the CMake executable.
|
||||
*
|
||||
* @param args Arguments to CMake
|
||||
* @param options Additional execution options
|
||||
* @returns The result of execution.
|
||||
*/
|
||||
executeCMakeCommand(args: string[], options?: ExecutionOptions): Thenable<ExecutionResult>;
|
||||
// Execute an arbitrary program in the active environments
|
||||
/**
|
||||
* Execute an arbitrary program.
|
||||
*
|
||||
* @param program Path to an executable binary
|
||||
* @param args List of command-line arguments to the program
|
||||
* @param options Additional execution options
|
||||
* @returns The result of execution
|
||||
*
|
||||
* ## Why you should use this API:
|
||||
*
|
||||
* You can execute a program on your own, but if it requires access to
|
||||
* environment variables that CMake Tools knows about, such as Visual C++
|
||||
* environment variables, this is the most reliable way to ensure that you
|
||||
* execute in the context that the user is expecting.
|
||||
*/
|
||||
execute(program: string, args: string[], options?: ExecutionOptions): Thenable<ExecutionResult>;
|
||||
|
||||
/**
|
||||
* Configure the project.
|
||||
*
|
||||
* @param extraArgs Extra arguments to pass on the CMake command line
|
||||
* @returns The exit code of CMake
|
||||
*/
|
||||
configure(extraArgs?: string[]): Thenable<number>;
|
||||
|
||||
/**
|
||||
* Build the project
|
||||
*
|
||||
* @param target The target to build. If not provided, will build the user's
|
||||
* active build target.
|
||||
* @returns the exit code of the build command
|
||||
*/
|
||||
build(targets?: string[]): Thenable<number>;
|
||||
|
||||
/**
|
||||
* Installs the project
|
||||
* @returns The exit code from CMake
|
||||
*/
|
||||
install(): Thenable<number>;
|
||||
|
||||
/**
|
||||
* Clean the build output. Runs the `clean` target.
|
||||
*
|
||||
* @returns The exit code from the build command
|
||||
*/
|
||||
clean(): Thenable<number>;
|
||||
|
||||
/**
|
||||
* Clean up old configuration and reconfigure.
|
||||
*
|
||||
* @returns The exit code from CMake
|
||||
*
|
||||
* @note This is *not* the same as running `clean`, then `configure`.
|
||||
* Cleaning up configure includes removing the CMake cache file and any
|
||||
* intermediate configuration files.
|
||||
*/
|
||||
cleanConfigure(): Thenable<number>;
|
||||
|
||||
/**
|
||||
* Clean the build output and rebuild
|
||||
*
|
||||
* @returns The exit code from the build command.
|
||||
*/
|
||||
cleanRebuild(): Thenable<number>;
|
||||
|
||||
/**
|
||||
* Execute CTest
|
||||
*
|
||||
* @returns The exit code from CTest
|
||||
*/
|
||||
ctest(): Thenable<number>;
|
||||
|
||||
/**
|
||||
* Stop the currently running command.
|
||||
*
|
||||
* @returns `true` on success. `false` otherwise.
|
||||
*/
|
||||
stop(): Thenable<boolean>;
|
||||
|
||||
/**
|
||||
* Start the active target without a debugger.
|
||||
*/
|
||||
launchTarget(): Thenable<Terminal | null>;
|
||||
|
||||
/**
|
||||
* Start the active target with a debugger.
|
||||
*/
|
||||
debugTarget(): Thenable<DebugSession | null>;
|
||||
|
||||
/**
|
||||
* Get the path to the active launch target
|
||||
*/
|
||||
launchTargetPath(): Thenable<string | null>;
|
||||
|
||||
/**
|
||||
* Get the directory to the active launch target
|
||||
*/
|
||||
launchTargetDirectory(): Thenable<string | null>;
|
||||
|
||||
/**
|
||||
* Get the filename of the active launch target
|
||||
*/
|
||||
launchTargetFilename(): Thenable<string | null>;
|
||||
|
||||
/**
|
||||
* Get the selected build type
|
||||
*/
|
||||
currentBuildType(): Thenable<string | null>;
|
||||
|
||||
/**
|
||||
* Get the build directory.
|
||||
*/
|
||||
buildDirectory(): Thenable<string | null>;
|
||||
|
||||
/**
|
||||
* Get the build command string for the active target
|
||||
*/
|
||||
tasksBuildCommand(): Thenable<string | null>;
|
||||
|
||||
/**
|
||||
* Get the build kit
|
||||
*/
|
||||
buildKit(): Thenable<string | null>;
|
||||
class CMakeProjectWrapper implements api.Project {
|
||||
constructor(private readonly project: CMakeProject) {}
|
||||
|
||||
get codeModel() {
|
||||
return this.project.codeModelContent ?? undefined;
|
||||
}
|
||||
|
||||
get onCodeModelChanged() {
|
||||
return this.project.onCodeModelChangedApiEvent;
|
||||
}
|
||||
|
||||
configure(): Promise<void> {
|
||||
return withErrorCheck('configure', () => this.project.configure());
|
||||
}
|
||||
|
||||
build(targets?: string[]): Promise<void> {
|
||||
return withErrorCheck('build', () => this.project.build(targets));
|
||||
}
|
||||
|
||||
install(): Promise<void> {
|
||||
return withErrorCheck('install', () => this.project.install());
|
||||
}
|
||||
|
||||
clean(): Promise<void> {
|
||||
return withErrorCheck('clean', () => this.project.clean());
|
||||
}
|
||||
|
||||
reconfigure(): Promise<void> {
|
||||
return withErrorCheck('reconfigure', () => this.project.cleanConfigure());
|
||||
}
|
||||
|
||||
async getBuildDirectory(): Promise<string | undefined> {
|
||||
return (await this.project.buildDirectory()) ?? undefined;
|
||||
}
|
||||
|
||||
async getActiveBuildType(): Promise<string | undefined> {
|
||||
return (await this.project.currentBuildType()) ?? undefined;
|
||||
}
|
||||
}
|
||||
|
|
61
src/cache.ts
61
src/cache.ts
|
@ -2,7 +2,6 @@
|
|||
* Module for reading from the CMake cache
|
||||
*/ /** */
|
||||
|
||||
import * as api from './api';
|
||||
import * as logging from './logging';
|
||||
import { fs } from './pr';
|
||||
import rollbar from './rollbar';
|
||||
|
@ -15,19 +14,39 @@ const localize: nls.LocalizeFunc = nls.loadMessageBundle();
|
|||
const log = logging.createLogger('cache');
|
||||
|
||||
/**
|
||||
* Implements access to CMake cache entries. See `api.CacheEntry` for more
|
||||
* information.
|
||||
* The type of a CMake cache entry
|
||||
*/
|
||||
export class Entry implements api.CacheEntry {
|
||||
public readonly type: api.CacheEntryType = api.CacheEntryType.Uninitialized;
|
||||
export enum CacheEntryType {
|
||||
Bool = 0,
|
||||
String = 1,
|
||||
Path = 2,
|
||||
FilePath = 3,
|
||||
Internal = 4,
|
||||
Uninitialized = 5,
|
||||
Static = 6,
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements access to CMake cache entries.
|
||||
*/
|
||||
export class CacheEntry {
|
||||
public readonly type: CacheEntryType = CacheEntryType.Uninitialized;
|
||||
public readonly helpString: string = '';
|
||||
/** The name of the cache entry */
|
||||
public readonly key: string = '';
|
||||
/** The entry's value. Type depends on `type`. */
|
||||
public readonly value: any = null;
|
||||
/** Whether this entry is ADVANCED, meaning it hidden from the user. */
|
||||
advanced: boolean = false;
|
||||
/** List of allowed values, as specified by STRINGS property */
|
||||
choices: string[] = [];
|
||||
|
||||
serializedKey: string = '';
|
||||
|
||||
/**
|
||||
* Return the value as a `T` instance. Does no actual conversion. It's up to
|
||||
* you to check the value of `CacheEntryProperties.type`.
|
||||
*/
|
||||
as<T>(): T {
|
||||
return this.value as T;
|
||||
}
|
||||
|
@ -41,11 +60,11 @@ export class Entry implements api.CacheEntry {
|
|||
* @param docString The `DOC` string in the cache
|
||||
* @param advanced Whether the entry is `ADVANCED`
|
||||
*/
|
||||
constructor(key: string, value: string, type: api.CacheEntryType, docString: string, advanced: boolean) {
|
||||
constructor(key: string, value: string, type: CacheEntryType, docString: string, advanced: boolean) {
|
||||
this.key = key;
|
||||
this.serializedKey = key; // may be overwritten later with quoted version of `key`
|
||||
this.type = type;
|
||||
if (type === api.CacheEntryType.Bool) {
|
||||
if (type === CacheEntryType.Bool) {
|
||||
this.value = util.isTruthy(value);
|
||||
} else {
|
||||
this.value = value;
|
||||
|
@ -85,7 +104,7 @@ export class CMakeCache {
|
|||
}
|
||||
|
||||
/** Get a list of all cache entries */
|
||||
get allEntries(): Entry[] {
|
||||
get allEntries(): CacheEntry[] {
|
||||
return Array.from(this.cacheEntries.values());
|
||||
}
|
||||
|
||||
|
@ -95,7 +114,7 @@ export class CMakeCache {
|
|||
* @param path Path to the cache file
|
||||
* @param cacheEntries Entries in the cache
|
||||
*/
|
||||
private constructor(public readonly path: string, private readonly cacheEntries: Map<string, Entry>) {}
|
||||
private constructor(public readonly path: string, private readonly cacheEntries: Map<string, CacheEntry>) {}
|
||||
|
||||
/**
|
||||
* Reload the cache file and return a new instance. This will not modify this
|
||||
|
@ -112,11 +131,11 @@ export class CMakeCache {
|
|||
* @param content The contents of a CMake cache file.
|
||||
* @returns A map from the cache keys to the entries in the cache.
|
||||
*/
|
||||
static parseCache(content: string): Map<string, Entry> {
|
||||
static parseCache(content: string): Map<string, CacheEntry> {
|
||||
log.debug(localize('parsing.cmake.cache.string', 'Parsing CMake cache string'));
|
||||
const lines = content.split(/\r\n|\n|\r/).filter(line => !!line.length).filter(line => !/^\s*#/.test(line));
|
||||
|
||||
const entries = new Map<string, Entry>();
|
||||
const entries = new Map<string, CacheEntry>();
|
||||
let docStringAccumulator = '';
|
||||
const advancedNames: string[] = [];
|
||||
const choices: Map<string, string[]> = new Map();
|
||||
|
@ -147,14 +166,14 @@ export class CMakeCache {
|
|||
} else {
|
||||
const key = name;
|
||||
const typemap = {
|
||||
BOOL: api.CacheEntryType.Bool,
|
||||
STRING: api.CacheEntryType.String,
|
||||
PATH: api.CacheEntryType.Path,
|
||||
FILEPATH: api.CacheEntryType.FilePath,
|
||||
INTERNAL: api.CacheEntryType.Internal,
|
||||
UNINITIALIZED: api.CacheEntryType.Uninitialized,
|
||||
STATIC: api.CacheEntryType.Static
|
||||
} as { [type: string]: api.CacheEntryType | undefined };
|
||||
BOOL: CacheEntryType.Bool,
|
||||
STRING: CacheEntryType.String,
|
||||
PATH: CacheEntryType.Path,
|
||||
FILEPATH: CacheEntryType.FilePath,
|
||||
INTERNAL: CacheEntryType.Internal,
|
||||
UNINITIALIZED: CacheEntryType.Uninitialized,
|
||||
STATIC: CacheEntryType.Static
|
||||
} as { [type: string]: CacheEntryType | undefined };
|
||||
const type = typemap[typeName];
|
||||
const docString = docStringAccumulator.trim();
|
||||
docStringAccumulator = '';
|
||||
|
@ -162,7 +181,7 @@ export class CMakeCache {
|
|||
rollbar.error(localize('cache.entry.unknown', 'Cache entry {0} has unknown type: {1}', `"${name}"`, `"${typeName}"`));
|
||||
} else {
|
||||
log.trace(localize('constructing.new.cache.entry', 'Constructing a new cache entry from the given line'));
|
||||
const entry = new Entry(key, value, type, docString, false);
|
||||
const entry = new CacheEntry(key, value, type, docString, false);
|
||||
entry.serializedKey = serializedName;
|
||||
entries.set(name, entry);
|
||||
}
|
||||
|
@ -278,7 +297,7 @@ export class CMakeCache {
|
|||
* @param key The name of a cache entry
|
||||
* @returns The cache entry, or `null` if the cache entry is not present.
|
||||
*/
|
||||
get(key: string): Entry | null {
|
||||
get(key: string): CacheEntry | null {
|
||||
const ret = this.cacheEntries.get(key) || null;
|
||||
if (ret) {
|
||||
log.trace(localize('get.cache.key', 'Get cache key {0}={1}', key, ret.value));
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import * as telemetry from '@cmt/telemetry';
|
||||
import * as api from './api';
|
||||
import * as util from './util';
|
||||
|
||||
import { CMakeCache } from './cache';
|
||||
import { CacheEntryType, CMakeCache } from './cache';
|
||||
|
||||
import * as logging from './logging';
|
||||
const log = logging.createLogger('cache');
|
||||
|
@ -222,8 +221,8 @@ export class ConfigurationWebview {
|
|||
for (const entry of cmakeCache.allEntries) {
|
||||
// Static cache entries are set automatically by CMake, overriding any value set by the user in this view.
|
||||
// Not useful to show these entries in the list.
|
||||
if (entry.type !== api.CacheEntryType.Static) {
|
||||
options.push({ key: entry.key, helpString: entry.helpString, choices: entry.choices, type: (entry.type === api.CacheEntryType.Bool) ? "Bool" : "String", value: entry.value, dirty: false });
|
||||
if (entry.type !== CacheEntryType.Static) {
|
||||
options.push({ key: entry.key, helpString: entry.helpString, choices: entry.choices, type: (entry.type === CacheEntryType.Bool) ? "Bool" : "String", value: entry.value, dirty: false });
|
||||
}
|
||||
}
|
||||
return options;
|
||||
|
|
|
@ -14,8 +14,6 @@ import { DirectoryContext } from '@cmt/workspace';
|
|||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
import * as proc from '@cmt/proc';
|
||||
import * as api from './api';
|
||||
import { ExecutionOptions, ExecutionResult } from './api';
|
||||
import { CodeModelContent } from '@cmt/drivers/codeModel';
|
||||
import { BadHomeDirectoryError } from '@cmt/drivers/cmakeServerClient';
|
||||
import { CMakeServerDriver, NoGeneratorError } from '@cmt/drivers/cmakeServerDriver';
|
||||
|
@ -23,14 +21,14 @@ import { CTestDriver, BasicTestResults } from './ctest';
|
|||
import { CMakeBuildConsumer } from './diagnostics/build';
|
||||
import { CMakeOutputConsumer } from './diagnostics/cmake';
|
||||
import { populateCollection } from './diagnostics/util';
|
||||
import { CMakeDriver, CMakePreconditionProblems } from '@cmt/drivers/cmakeDriver';
|
||||
import { CMakeDriver, CMakePreconditionProblems, ExecutableTarget } from '@cmt/drivers/cmakeDriver';
|
||||
import { expandStrings, expandString, ExpansionOptions } from './expand';
|
||||
import { CMakeGenerator, Kit } from './kit';
|
||||
import { CMakeLegacyDriver } from '@cmt/drivers/cmakeLegacyDriver';
|
||||
import * as logging from './logging';
|
||||
import { fs } from './pr';
|
||||
import { buildCmdStr, DebuggerEnvironmentVariable } from './proc';
|
||||
import { Property } from './prop';
|
||||
import { buildCmdStr, DebuggerEnvironmentVariable, ExecutionResult, ExecutionOptions } from './proc';
|
||||
import { FireLate, Property } from './prop';
|
||||
import rollbar from './rollbar';
|
||||
import * as telemetry from './telemetry';
|
||||
import { setContextValue } from './util';
|
||||
|
@ -98,7 +96,7 @@ export enum ConfigureTrigger {
|
|||
* The second phases of fields will be called by the second phase of the parent
|
||||
* class. See the `init` private method for this initialization.
|
||||
*/
|
||||
export class CMakeProject implements api.CMakeToolsAPI {
|
||||
export class CMakeProject {
|
||||
/**
|
||||
* Construct a new instance. The instance isn't ready, and must be initalized.
|
||||
* @param extensionContext The extension context
|
||||
|
@ -108,6 +106,7 @@ export class CMakeProject implements api.CMakeToolsAPI {
|
|||
private constructor(readonly extensionContext: vscode.ExtensionContext, readonly workspaceContext: DirectoryContext) {
|
||||
// Handle the active kit changing. We want to do some updates and teardown
|
||||
log.debug(localize('constructing.cmakeproject', 'Constructing new CMakeProject instance'));
|
||||
this.onCodeModelChanged(FireLate, (_) => this._codeModelChangedApiEventEmitter.fire());
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -478,6 +477,11 @@ export class CMakeProject implements api.CMakeToolsAPI {
|
|||
private readonly _codeModelContent = new Property<CodeModelContent | null>(null);
|
||||
private codeModelDriverSub: vscode.Disposable | null = null;
|
||||
|
||||
get onCodeModelChangedApiEvent() {
|
||||
return this._codeModelChangedApiEventEmitter.event;
|
||||
}
|
||||
private readonly _codeModelChangedApiEventEmitter = new vscode.EventEmitter<void>();
|
||||
|
||||
private readonly communicationModeSub = this.workspaceContext.config.onChange('cmakeCommunicationMode', () => {
|
||||
log.info(localize('communication.changed.restart.driver', "Restarting the CMake driver after a communication mode change."));
|
||||
return this.shutDownCMakeDriver();
|
||||
|
@ -1931,7 +1935,7 @@ export class CMakeProject implements api.CMakeToolsAPI {
|
|||
return chosen.detail;
|
||||
}
|
||||
|
||||
async getCurrentLaunchTarget(): Promise<api.ExecutableTarget | null> {
|
||||
async getCurrentLaunchTarget(): Promise<ExecutableTarget | null> {
|
||||
const targetName = this.workspaceContext.state.launchTargetName;
|
||||
const target = (await this.executableTargets).find(e => e.name === targetName);
|
||||
|
||||
|
@ -2056,8 +2060,8 @@ export class CMakeProject implements api.CMakeToolsAPI {
|
|||
}
|
||||
}
|
||||
|
||||
async prepareLaunchTargetExecutable(name?: string): Promise<api.ExecutableTarget | null> {
|
||||
let chosen: api.ExecutableTarget;
|
||||
async prepareLaunchTargetExecutable(name?: string): Promise<ExecutableTarget | null> {
|
||||
let chosen: ExecutableTarget;
|
||||
|
||||
// Ensure that we've configured the project already. If we haven't, `getOrSelectLaunchTarget` won't see any
|
||||
// executable targets and may show an uneccessary prompt to the user
|
||||
|
@ -2096,7 +2100,7 @@ export class CMakeProject implements api.CMakeToolsAPI {
|
|||
return chosen;
|
||||
}
|
||||
|
||||
async getOrSelectLaunchTarget(): Promise<api.ExecutableTarget | null> {
|
||||
async getOrSelectLaunchTarget(): Promise<ExecutableTarget | null> {
|
||||
const current = await this.getCurrentLaunchTarget();
|
||||
if (current) {
|
||||
return current;
|
||||
|
@ -2217,7 +2221,7 @@ export class CMakeProject implements api.CMakeToolsAPI {
|
|||
}
|
||||
});
|
||||
|
||||
private async createTerminal(executable: api.ExecutableTarget): Promise<vscode.Terminal> {
|
||||
private async createTerminal(executable: ExecutableTarget): Promise<vscode.Terminal> {
|
||||
const launchBehavior = this.workspaceContext.config.launchBehavior.toLowerCase();
|
||||
if (launchBehavior !== "newterminal") {
|
||||
for (const [, terminal] of this.launchTerminals) {
|
||||
|
|
19
src/ctest.ts
19
src/ctest.ts
|
@ -4,7 +4,6 @@ import * as vscode from 'vscode';
|
|||
import * as xml2js from 'xml2js';
|
||||
import * as zlib from 'zlib';
|
||||
|
||||
import * as api from './api';
|
||||
import { CMakeDriver } from '@cmt/drivers/cmakeDriver';
|
||||
import * as logging from './logging';
|
||||
import { fs } from './pr';
|
||||
|
@ -20,6 +19,14 @@ const localize: nls.LocalizeFunc = nls.loadMessageBundle();
|
|||
|
||||
const log = logging.createLogger('ctest');
|
||||
|
||||
/**
|
||||
* Information about a CTest test
|
||||
*/
|
||||
export interface CTest {
|
||||
id: number;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface BasicTestResults {
|
||||
passing: number;
|
||||
total: number;
|
||||
|
@ -331,16 +338,16 @@ export class CTestDriver implements vscode.Disposable {
|
|||
/**
|
||||
* Holds the most recent test informations
|
||||
*/
|
||||
private _tests: api.Test[] = [];
|
||||
get tests(): api.Test[] {
|
||||
private _tests: CTest[] = [];
|
||||
get tests(): CTest[] {
|
||||
return this._tests;
|
||||
}
|
||||
set tests(v: api.Test[]) {
|
||||
set tests(v: CTest[]) {
|
||||
this._tests = v;
|
||||
this.testsChangedEmitter.fire(v);
|
||||
}
|
||||
|
||||
private readonly testsChangedEmitter = new vscode.EventEmitter<api.Test[]>();
|
||||
private readonly testsChangedEmitter = new vscode.EventEmitter<CTest[]>();
|
||||
readonly onTestsChanged = this.testsChangedEmitter.event;
|
||||
|
||||
private _testResults?: CTestResults;
|
||||
|
@ -418,7 +425,7 @@ export class CTestDriver implements vscode.Disposable {
|
|||
/**
|
||||
* @brief Reload the list of CTest tests
|
||||
*/
|
||||
async reloadTests(driver: CMakeDriver): Promise<api.Test[]> {
|
||||
async reloadTests(driver: CMakeDriver): Promise<CTest[]> {
|
||||
const ctestFile = path.join(driver.binaryDir, 'CTestTestfile.cmake');
|
||||
if (!(await fs.exists(ctestFile))) {
|
||||
this.testingEnabled = false;
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { ExecutableTarget } from '@cmt/api';
|
||||
import { CMakeCache } from '@cmt/cache';
|
||||
import * as proc from '@cmt/proc';
|
||||
import { createLogger } from './logging';
|
||||
|
@ -6,6 +5,7 @@ import * as nls from 'vscode-nls';
|
|||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
import { fs } from './pr';
|
||||
import { ExecutableTarget } from '@cmt/drivers/cmakeDriver';
|
||||
|
||||
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
|
||||
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import * as api from '@cmt/api';
|
||||
import { CMakeExecutable } from '@cmt/cmake/cmakeExecutable';
|
||||
import * as codepages from '@cmt/codePageTable';
|
||||
import { ConfigureTrigger } from "@cmt/cmakeProject";
|
||||
|
@ -33,6 +32,7 @@ import { DiagnosticsConfiguration } from '@cmt/cmakeWorkspaceFolder';
|
|||
import { Environment, EnvironmentUtils } from '@cmt/environmentVariables';
|
||||
import { CustomBuildTaskTerminal } from '@cmt/cmakeTaskProvider';
|
||||
import { getValue } from '@cmt/preset';
|
||||
import { CacheEntry } from '@cmt/cache';
|
||||
|
||||
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
|
||||
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
|
||||
|
@ -57,6 +57,40 @@ function nullableValueToString(arg: any | null | undefined): string {
|
|||
return arg === null ? 'empty' : arg;
|
||||
}
|
||||
|
||||
/**
|
||||
* Description of an executable CMake target, defined via `add_executable()`.
|
||||
*/
|
||||
export interface ExecutableTarget {
|
||||
/**
|
||||
* The name of the target.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* The absolute path to the build output.
|
||||
*/
|
||||
path: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A target with a name, but no output. This may be created via `add_custom_command()`.
|
||||
*/
|
||||
export interface NamedTarget {
|
||||
type: 'named';
|
||||
name: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A target with a name, path, and type.
|
||||
*/
|
||||
export interface RichTarget {
|
||||
type: 'rich';
|
||||
name: string;
|
||||
filepath: string;
|
||||
targetType: string;
|
||||
}
|
||||
|
||||
export type Target = NamedTarget | RichTarget;
|
||||
|
||||
/**
|
||||
* Base class for CMake drivers.
|
||||
*
|
||||
|
@ -112,19 +146,19 @@ export abstract class CMakeDriver implements vscode.Disposable {
|
|||
/**
|
||||
* List of targets known to CMake
|
||||
*/
|
||||
abstract get targets(): api.Target[];
|
||||
abstract get targets(): Target[];
|
||||
|
||||
abstract get codeModelContent(): codeModel.CodeModelContent | null;
|
||||
|
||||
/**
|
||||
* List of executable targets known to CMake
|
||||
*/
|
||||
abstract get executableTargets(): api.ExecutableTarget[];
|
||||
abstract get executableTargets(): ExecutableTarget[];
|
||||
|
||||
/**
|
||||
* List of unique targets known to CMake
|
||||
*/
|
||||
abstract get uniqueTargets(): api.Target[];
|
||||
abstract get uniqueTargets(): Target[];
|
||||
|
||||
/**
|
||||
* List of all files (CMakeLists.txt and included .cmake files) used by CMake
|
||||
|
@ -1747,7 +1781,7 @@ export abstract class CMakeDriver implements vscode.Disposable {
|
|||
*
|
||||
* Will be automatically reloaded when the file on disk changes.
|
||||
*/
|
||||
abstract get cmakeCacheEntries(): Map<string, api.CacheEntryProperties>;
|
||||
abstract get cmakeCacheEntries(): Map<string, CacheEntry>;
|
||||
|
||||
private async _baseInit(useCMakePresets: boolean,
|
||||
kit: Kit | null,
|
||||
|
|
|
@ -6,7 +6,6 @@
|
|||
* This file implements only the new required structures.
|
||||
*/
|
||||
|
||||
import * as api from '@cmt/api';
|
||||
import * as cache from '@cmt/cache';
|
||||
import {
|
||||
CodeModelConfiguration,
|
||||
|
@ -22,6 +21,7 @@ import * as path from 'path';
|
|||
import * as nls from 'vscode-nls';
|
||||
import rollbar from '@cmt/rollbar';
|
||||
import { removeEmpty } from '@cmt/util';
|
||||
import { RichTarget, Target } from '@cmt/drivers/cmakeDriver';
|
||||
|
||||
export interface ApiVersion {
|
||||
major: number;
|
||||
|
@ -260,7 +260,7 @@ export async function loadIndexFile(replyPath: string): Promise<Index.IndexFile
|
|||
return JSON.parse(fileContent.toString()) as Index.IndexFile;
|
||||
}
|
||||
|
||||
export async function loadCacheContent(filename: string): Promise<Map<string, api.CacheEntry>> {
|
||||
export async function loadCacheContent(filename: string): Promise<Map<string, cache.CacheEntry>> {
|
||||
const fileContent = await tryReadFile(filename);
|
||||
if (!fileContent) {
|
||||
return new Map();
|
||||
|
@ -310,16 +310,16 @@ function findPropertyValue(cacheElement: Cache.CMakeCacheEntry, name: string): s
|
|||
return propertyElement ? propertyElement.value : '';
|
||||
}
|
||||
|
||||
function convertFileApiCacheToExtensionCache(cmakeCacheContent: Cache.CacheContent): Map<string, api.CacheEntry> {
|
||||
function convertFileApiCacheToExtensionCache(cmakeCacheContent: Cache.CacheContent): Map<string, cache.CacheEntry> {
|
||||
return cmakeCacheContent.entries.reduce((acc, el) => {
|
||||
const fileApiToExtensionCacheMap: { [key: string]: api.CacheEntryType | undefined } = {
|
||||
BOOL: api.CacheEntryType.Bool,
|
||||
STRING: api.CacheEntryType.String,
|
||||
PATH: api.CacheEntryType.Path,
|
||||
FILEPATH: api.CacheEntryType.FilePath,
|
||||
INTERNAL: api.CacheEntryType.Internal,
|
||||
UNINITIALIZED: api.CacheEntryType.Uninitialized,
|
||||
STATIC: api.CacheEntryType.Static
|
||||
const fileApiToExtensionCacheMap: { [key: string]: cache.CacheEntryType | undefined } = {
|
||||
BOOL: cache.CacheEntryType.Bool,
|
||||
STRING: cache.CacheEntryType.String,
|
||||
PATH: cache.CacheEntryType.Path,
|
||||
FILEPATH: cache.CacheEntryType.FilePath,
|
||||
INTERNAL: cache.CacheEntryType.Internal,
|
||||
UNINITIALIZED: cache.CacheEntryType.Uninitialized,
|
||||
STATIC: cache.CacheEntryType.Static
|
||||
};
|
||||
const type = fileApiToExtensionCacheMap[el.type];
|
||||
if (type === undefined) {
|
||||
|
@ -328,9 +328,9 @@ function convertFileApiCacheToExtensionCache(cmakeCacheContent: Cache.CacheConte
|
|||
}
|
||||
const helpString = findPropertyValue(el, 'HELPSTRING');
|
||||
const advanced = findPropertyValue(el, 'ADVANCED');
|
||||
acc.set(el.name, new cache.Entry(el.name, el.value, type, helpString, advanced === '1'));
|
||||
acc.set(el.name, new cache.CacheEntry(el.name, el.value, type, helpString, advanced === '1'));
|
||||
return acc;
|
||||
}, new Map<string, api.CacheEntry>());
|
||||
}, new Map<string, cache.CacheEntry>());
|
||||
}
|
||||
|
||||
export async function loadCodeModelContent(filename: string): Promise<CodeModelKind.Content | null> {
|
||||
|
@ -363,7 +363,7 @@ export async function loadTargetObject(filename: string): Promise<CodeModelKind.
|
|||
return JSON.parse(fileContent.toString()) as CodeModelKind.TargetObject;
|
||||
}
|
||||
|
||||
async function convertTargetObjectFileToExtensionTarget(buildDirectory: string, filePath: string): Promise<api.Target | null> {
|
||||
async function convertTargetObjectFileToExtensionTarget(buildDirectory: string, filePath: string): Promise<Target | null> {
|
||||
const targetObject = await loadTargetObject(filePath);
|
||||
if (!targetObject) {
|
||||
return null;
|
||||
|
@ -382,10 +382,10 @@ async function convertTargetObjectFileToExtensionTarget(buildDirectory: string,
|
|||
filepath: executablePath,
|
||||
targetType: targetObject.type,
|
||||
type: 'rich' as 'rich'
|
||||
} as api.RichTarget;
|
||||
} as RichTarget;
|
||||
}
|
||||
|
||||
export async function loadAllTargetsForBuildTypeConfiguration(replyPath: string, buildDirectory: string, configuration: CodeModelKind.Configuration): Promise<{ name: string; targets: api.Target[] }> {
|
||||
export async function loadAllTargetsForBuildTypeConfiguration(replyPath: string, buildDirectory: string, configuration: CodeModelKind.Configuration): Promise<{ name: string; targets: Target[] }> {
|
||||
const metaTargets = [];
|
||||
if (configuration.directories[0].hasInstallRule) {
|
||||
metaTargets.push({
|
||||
|
@ -403,7 +403,7 @@ export async function loadAllTargetsForBuildTypeConfiguration(replyPath: string,
|
|||
};
|
||||
}
|
||||
|
||||
export async function loadConfigurationTargetMap(replyPath: string, codeModelFileName: string): Promise<Map<string, api.Target[]>> {
|
||||
export async function loadConfigurationTargetMap(replyPath: string, codeModelFileName: string): Promise<Map<string, Target[]>> {
|
||||
const codeModelContent = await loadCodeModelContent(path.join(replyPath, codeModelFileName));
|
||||
if (!codeModelContent) {
|
||||
return new Map();
|
||||
|
@ -414,7 +414,7 @@ export async function loadConfigurationTargetMap(replyPath: string, codeModelFil
|
|||
return targets.reduce((acc, el) => {
|
||||
acc.set(el.name, el.targets);
|
||||
return acc;
|
||||
}, new Map<string, api.Target[]>());
|
||||
}, new Map<string, Target[]>());
|
||||
}
|
||||
|
||||
function convertToAbsolutePath(inputPath: string, basePath: string) {
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import * as api from '@cmt/api';
|
||||
import { ConfigureTrigger } from '@cmt/cmakeProject';
|
||||
import { ExecutableTarget } from '@cmt/api';
|
||||
import { CMakeCache } from '@cmt/cache';
|
||||
import { CMakeCache, CacheEntry } from '@cmt/cache';
|
||||
import { CMakeExecutable } from '@cmt/cmake/cmakeExecutable';
|
||||
import { ConfigurationReader } from '@cmt/config';
|
||||
import {
|
||||
|
@ -15,7 +13,13 @@ import {
|
|||
Index
|
||||
} from '@cmt/drivers/cmakeFileApi';
|
||||
import * as codeModel from '@cmt/drivers/codeModel';
|
||||
import { CMakeDriver, CMakePreconditionProblemSolver } from '@cmt/drivers/cmakeDriver';
|
||||
import {
|
||||
CMakeDriver,
|
||||
CMakePreconditionProblemSolver,
|
||||
ExecutableTarget,
|
||||
RichTarget,
|
||||
Target
|
||||
} from '@cmt/drivers/cmakeDriver';
|
||||
import { CMakeGenerator, Kit } from '@cmt/kit';
|
||||
import * as logging from '@cmt/logging';
|
||||
import { fs } from '@cmt/pr';
|
||||
|
@ -79,10 +83,10 @@ export class CMakeFileApiDriver extends CMakeDriver {
|
|||
private readonly _cacheWatcher = vscode.workspace.createFileSystemWatcher(this.cachePath);
|
||||
|
||||
// Information from cmake file api
|
||||
private _cache: Map<string, api.CacheEntry> = new Map<string, api.CacheEntry>();
|
||||
private _cache: Map<string, CacheEntry> = new Map<string, CacheEntry>();
|
||||
private _cmakeFiles: string[] | null = null;
|
||||
private _generatorInformation: Index.GeneratorInformation | null = null;
|
||||
private _target_map: Map<string, api.Target[]> = new Map();
|
||||
private _target_map: Map<string, Target[]> = new Map();
|
||||
|
||||
async getGeneratorFromCache(cache_file_path: string): Promise<string | undefined> {
|
||||
const cache = await CMakeCache.fromPath(cache_file_path);
|
||||
|
@ -355,13 +359,13 @@ export class CMakeFileApiDriver extends CMakeDriver {
|
|||
return this._codeModelContent;
|
||||
}
|
||||
|
||||
get cmakeCacheEntries(): Map<string, api.CacheEntryProperties> {
|
||||
get cmakeCacheEntries(): Map<string, CacheEntry> {
|
||||
return this._cache;
|
||||
}
|
||||
get generatorName(): string | null {
|
||||
return this._generatorInformation ? this._generatorInformation.name : null;
|
||||
}
|
||||
get targets(): api.Target[] {
|
||||
get targets(): Target[] {
|
||||
const targets = this._target_map.get(this.currentBuildType);
|
||||
if (targets) {
|
||||
const metaTargets = [{
|
||||
|
@ -379,15 +383,15 @@ export class CMakeFileApiDriver extends CMakeDriver {
|
|||
/**
|
||||
* List of unique targets known to CMake
|
||||
*/
|
||||
get uniqueTargets(): api.Target[] {
|
||||
get uniqueTargets(): Target[] {
|
||||
return this.targets.reduce(targetReducer, []);
|
||||
}
|
||||
|
||||
get executableTargets(): ExecutableTarget[] {
|
||||
return this.uniqueTargets.filter(t => t.type === 'rich' && (t as api.RichTarget).targetType === 'EXECUTABLE')
|
||||
return this.uniqueTargets.filter(t => t.type === 'rich' && (t as RichTarget).targetType === 'EXECUTABLE')
|
||||
.map(t => ({
|
||||
name: t.name,
|
||||
path: (t as api.RichTarget).filepath
|
||||
path: (t as RichTarget).filepath
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -407,14 +411,14 @@ export class CMakeFileApiDriver extends CMakeDriver {
|
|||
* @param set the accumulator
|
||||
* @t the RichTarget currently being examined.
|
||||
*/
|
||||
function targetReducer(set: api.Target[], t: api.Target): api.Target[] {
|
||||
function targetReducer(set: Target[], t: Target): Target[] {
|
||||
if (!set.find(t2 => compareTargets(t, t2))) {
|
||||
set.push(t);
|
||||
}
|
||||
return set;
|
||||
}
|
||||
|
||||
function compareTargets(a: api.Target, b: api.Target): boolean {
|
||||
function compareTargets(a: Target, b: Target): boolean {
|
||||
let same = false;
|
||||
if (a.type === b.type) {
|
||||
same = a.name === b.name;
|
||||
|
|
|
@ -6,8 +6,7 @@
|
|||
import { CMakeExecutable } from '@cmt/cmake/cmakeExecutable';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
import * as api from '@cmt/api';
|
||||
import { CMakeCache } from '@cmt/cache';
|
||||
import { CMakeCache, CacheEntry } from '@cmt/cache';
|
||||
import { CMakeDriver, CMakePreconditionProblemSolver } from '@cmt/drivers/cmakeDriver';
|
||||
import { Kit, CMakeGenerator } from '@cmt/kit';
|
||||
import * as logging from '@cmt/logging';
|
||||
|
@ -198,7 +197,7 @@ export class CMakeLegacyDriver extends CMakeDriver {
|
|||
}
|
||||
|
||||
get cmakeCacheEntries() {
|
||||
let ret = new Map<string, api.CacheEntryProperties>();
|
||||
let ret = new Map<string, CacheEntry>();
|
||||
if (this.cmakeCache) {
|
||||
ret = util.reduce(this.cmakeCache.allEntries, ret, (acc, entry) => acc.set(entry.key, entry));
|
||||
}
|
||||
|
|
|
@ -3,11 +3,15 @@ import { InputFileSet } from '@cmt/dirty';
|
|||
import { ConfigureTrigger } from '@cmt/cmakeProject';
|
||||
import * as path from 'path';
|
||||
import * as vscode from 'vscode';
|
||||
import * as api from '@cmt/api';
|
||||
import { CacheEntryProperties, ExecutableTarget, RichTarget } from '@cmt/api';
|
||||
import * as cache from '@cmt/cache';
|
||||
import * as cms from '@cmt/drivers/cmakeServerClient';
|
||||
import { CMakeDriver, CMakePreconditionProblemSolver } from '@cmt/drivers/cmakeDriver';
|
||||
import {
|
||||
CMakeDriver,
|
||||
CMakePreconditionProblemSolver,
|
||||
ExecutableTarget,
|
||||
RichTarget,
|
||||
Target
|
||||
} from '@cmt/drivers/cmakeDriver';
|
||||
import { Kit, CMakeGenerator } from '@cmt/kit';
|
||||
import { createLogger } from '@cmt/logging';
|
||||
import * as proc from '@cmt/proc';
|
||||
|
@ -47,7 +51,7 @@ export class CMakeServerDriver extends CMakeDriver {
|
|||
private _cmsClient: Promise<cms.CMakeServerClient | null> = Promise.resolve(null);
|
||||
private _clientChangeInProgress: Promise<void> = Promise.resolve();
|
||||
private _globalSettings!: cms.GlobalSettingsContent;
|
||||
private _cacheEntries = new Map<string, cache.Entry>();
|
||||
private _cacheEntries = new Map<string, cache.CacheEntry>();
|
||||
private _cmakeInputFileSet = InputFileSet.createEmpty();
|
||||
|
||||
private readonly _progressEmitter = new vscode.EventEmitter<cms.ProgressMessage>();
|
||||
|
@ -207,14 +211,14 @@ export class CMakeServerDriver extends CMakeDriver {
|
|||
this._cmakeInputFileSet = await InputFileSet.create(cmake_inputs);
|
||||
const clcache = await client.getCMakeCacheContent();
|
||||
this._cacheEntries = clcache.cache.reduce((acc, el) => {
|
||||
const entry_map: { [key: string]: api.CacheEntryType | undefined } = {
|
||||
BOOL: api.CacheEntryType.Bool,
|
||||
STRING: api.CacheEntryType.String,
|
||||
PATH: api.CacheEntryType.Path,
|
||||
FILEPATH: api.CacheEntryType.FilePath,
|
||||
INTERNAL: api.CacheEntryType.Internal,
|
||||
UNINITIALIZED: api.CacheEntryType.Uninitialized,
|
||||
STATIC: api.CacheEntryType.Static
|
||||
const entry_map: { [key: string]: cache.CacheEntryType | undefined } = {
|
||||
BOOL: cache.CacheEntryType.Bool,
|
||||
STRING: cache.CacheEntryType.String,
|
||||
PATH: cache.CacheEntryType.Path,
|
||||
FILEPATH: cache.CacheEntryType.FilePath,
|
||||
INTERNAL: cache.CacheEntryType.Internal,
|
||||
UNINITIALIZED: cache.CacheEntryType.Uninitialized,
|
||||
STATIC: cache.CacheEntryType.Static
|
||||
};
|
||||
const type = entry_map[el.type];
|
||||
if (type === undefined) {
|
||||
|
@ -222,9 +226,9 @@ export class CMakeServerDriver extends CMakeDriver {
|
|||
return acc;
|
||||
}
|
||||
acc.set(el.key,
|
||||
new cache.Entry(el.key, el.value, type, el.properties.HELPSTRING, el.properties.ADVANCED === '1'));
|
||||
new cache.CacheEntry(el.key, el.value, type, el.properties.HELPSTRING, el.properties.ADVANCED === '1'));
|
||||
return acc;
|
||||
}, new Map<string, cache.Entry>());
|
||||
}, new Map<string, cache.CacheEntry>());
|
||||
// Convert ServerCodeModel to general CodeModel.
|
||||
this.codeModel = this.convertServerCodeModel(await client.codemodel());
|
||||
this._codeModelChanged.fire(this.codeModel);
|
||||
|
@ -287,7 +291,7 @@ export class CMakeServerDriver extends CMakeDriver {
|
|||
.map(t => ({ name: t.name, path: t.filepath }));
|
||||
}
|
||||
|
||||
get uniqueTargets(): api.Target[] {
|
||||
get uniqueTargets(): Target[] {
|
||||
return this.targets.reduce(targetReducer, []);
|
||||
}
|
||||
|
||||
|
@ -318,7 +322,7 @@ export class CMakeServerDriver extends CMakeDriver {
|
|||
return this._cmakeInputFileSet.checkOutOfDate();
|
||||
}
|
||||
|
||||
get cmakeCacheEntries(): Map<string, CacheEntryProperties> {
|
||||
get cmakeCacheEntries(): Map<string, cache.CacheEntry> {
|
||||
return this._cacheEntries;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,114 +1,17 @@
|
|||
import { CMakeCache } from "@cmt/cache";
|
||||
|
||||
export type TargetTypeString = 'STATIC_LIBRARY' | 'MODULE_LIBRARY' | 'SHARED_LIBRARY' | 'OBJECT_LIBRARY' | 'EXECUTABLE' | 'UTILITY' | 'INTERFACE_LIBRARY';
|
||||
import * as api from "vscode-cmake-tools";
|
||||
|
||||
/** Describes a cmake target */
|
||||
export interface CodeModelTarget {
|
||||
/**
|
||||
* A string specifying the logical name of the target.
|
||||
*
|
||||
* (Source CMake Documentation cmake-file-api(7))
|
||||
*/
|
||||
readonly name: string;
|
||||
|
||||
/**
|
||||
* A string specifying the type of the target.
|
||||
* The value is one of EXECUTABLE, STATIC_LIBRARY, SHARED_LIBRARY, MODULE_LIBRARY, OBJECT_LIBRARY, or UTILITY.
|
||||
*
|
||||
* (Source CMake Documentation cmake-file-api(7))
|
||||
*
|
||||
* \todo clarify need of INTERFACE_LIBRARY type
|
||||
*/
|
||||
type: TargetTypeString;
|
||||
|
||||
/** A string specifying the absolute path to the target’s source directory. */
|
||||
sourceDirectory?: string;
|
||||
|
||||
/** Name of the target artifact on disk (library or executable file name). */
|
||||
fullName?: string;
|
||||
|
||||
/** List of absolute paths to a target´s build artifacts. */
|
||||
artifacts?: string[];
|
||||
|
||||
/**
|
||||
* The file groups describe a list of compilation information for artifacts of this target.
|
||||
* The file groups contains source code files that use the same compilation information
|
||||
* and are known by CMake.
|
||||
*/
|
||||
fileGroups?: CodeModelFileGroup[];
|
||||
|
||||
/**
|
||||
* Represents the CMAKE_SYSROOT variable
|
||||
*/
|
||||
sysroot?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes a file group to describe the build settings.
|
||||
*/
|
||||
export interface CodeModelFileGroup {
|
||||
/** List of source files with the same compilation information */
|
||||
sources: string[];
|
||||
|
||||
/** Specifies the language (C, C++, ...) for the toolchain */
|
||||
language?: string;
|
||||
|
||||
/** Include paths for compilation of a source file */
|
||||
includePath?: {
|
||||
/** include path */
|
||||
path: string;
|
||||
}[];
|
||||
|
||||
/** Compiler flags */
|
||||
compileCommandFragments?: string[];
|
||||
|
||||
/** Defines */
|
||||
defines?: string[];
|
||||
|
||||
/** CMake generated file group */
|
||||
isGenerated: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes cmake project and all its related targets
|
||||
*/
|
||||
export interface CodeModelProject {
|
||||
/** Name of the project */
|
||||
name: string;
|
||||
|
||||
/** List of targets */
|
||||
targets: CodeModelTarget[];
|
||||
|
||||
/** Location of the Project */
|
||||
sourceDirectory: string;
|
||||
|
||||
hasInstallRule?: boolean; // Exists in ServerCodeModelProject.
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Describes cmake configuration
|
||||
*/
|
||||
export interface CodeModelConfiguration {
|
||||
/** List of project() from CMakeLists.txt */
|
||||
projects: CodeModelProject[];
|
||||
|
||||
/** Name of the active configuration in a multi-configuration generator.*/
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface CodeModelToolchain {
|
||||
path: string;
|
||||
target?: string;
|
||||
}
|
||||
|
||||
/** Describes the cmake model */
|
||||
export interface CodeModelContent {
|
||||
/** List of configurations provided by the selected generator */
|
||||
configurations: CodeModelConfiguration[];
|
||||
|
||||
toolchains?: Map<string, CodeModelToolchain>;
|
||||
}
|
||||
// Re-export API types. This gives us flexibility add fields to the internal
|
||||
// representation of these data structures in the future without modifying the
|
||||
// public API.
|
||||
export type CodeModelConfiguration = api.CodeModel.Configuration;
|
||||
export type CodeModelContent = api.CodeModel.Content;
|
||||
export type CodeModelFileGroup = api.CodeModel.FileGroup;
|
||||
export type CodeModelProject = api.CodeModel.Project;
|
||||
export type CodeModelTarget = api.CodeModel.Target;
|
||||
export type CodeModelToolchain = api.CodeModel.Toolchain;
|
||||
export type TargetTypeString = api.CodeModel.TargetType;
|
||||
|
||||
/**
|
||||
* Type given when updating the configuration data stored in the file index.
|
||||
|
|
|
@ -10,6 +10,7 @@ import * as path from 'path';
|
|||
import * as vscode from 'vscode';
|
||||
import * as cpt from 'vscode-cpptools';
|
||||
import * as nls from 'vscode-nls';
|
||||
import * as api from 'vscode-cmake-tools';
|
||||
|
||||
import { CMakeCache } from '@cmt/cache';
|
||||
import { CMakeProject, ConfigureType, ConfigureTrigger } from '@cmt/cmakeProject';
|
||||
|
@ -41,6 +42,7 @@ import paths from '@cmt/paths';
|
|||
import { CMakeDriver, CMakePreconditionProblems } from './drivers/cmakeDriver';
|
||||
import { platform } from 'os';
|
||||
import { defaultBuildPreset } from './preset';
|
||||
import { CMakeToolsApiImpl } from './api';
|
||||
|
||||
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
|
||||
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
|
||||
|
@ -78,7 +80,7 @@ interface Diagnostics {
|
|||
* necessitate user input, this class acts as intermediary and will send
|
||||
* important information down to the lower layers.
|
||||
*/
|
||||
class ExtensionManager implements vscode.Disposable {
|
||||
export class ExtensionManager implements vscode.Disposable {
|
||||
constructor(public readonly extensionContext: vscode.ExtensionContext) {
|
||||
telemetry.activate(extensionContext);
|
||||
this.showCMakeLists = new Promise<boolean>(resolve => {
|
||||
|
@ -120,7 +122,9 @@ class ExtensionManager implements vscode.Disposable {
|
|||
// We already have this folder, do nothing
|
||||
} else {
|
||||
const subs: vscode.Disposable[] = [];
|
||||
subs.push(newCmt.onCodeModelChanged(FireLate, () => this.updateCodeModel(cmakeWorkspaceFolder)));
|
||||
subs.push(newCmt.onCodeModelChanged(FireLate, () => {
|
||||
this.updateCodeModel(cmakeWorkspaceFolder);
|
||||
}));
|
||||
subs.push(newCmt.onTargetNameChanged(FireLate, () => this.updateCodeModel(cmakeWorkspaceFolder)));
|
||||
subs.push(newCmt.onLaunchTargetNameChanged(FireLate, () => this.updateCodeModel(cmakeWorkspaceFolder)));
|
||||
subs.push(newCmt.onActiveBuildPresetChanged(FireLate, () => this.updateCodeModel(cmakeWorkspaceFolder)));
|
||||
|
@ -167,6 +171,7 @@ class ExtensionManager implements vscode.Disposable {
|
|||
}
|
||||
this.statusBar.setAutoSelectActiveFolder(v);
|
||||
});
|
||||
this.api = new CMakeToolsApiImpl(this);
|
||||
}
|
||||
|
||||
private onDidChangeActiveTextEditorSub: vscode.Disposable = new DummyDisposable();
|
||||
|
@ -204,7 +209,9 @@ class ExtensionManager implements vscode.Disposable {
|
|||
for (const cmakeWorkspaceFolder of this.cmakeWorkspaceFolders) {
|
||||
this.onUseCMakePresetsChangedSub = cmakeWorkspaceFolder.onUseCMakePresetsChanged(useCMakePresets => this.statusBar.useCMakePresets(useCMakePresets));
|
||||
this.codeModelUpdateSubs.set(cmakeWorkspaceFolder.folder.uri.fsPath, [
|
||||
cmakeWorkspaceFolder.cmakeProject.onCodeModelChanged(FireLate, () => this.updateCodeModel(cmakeWorkspaceFolder)),
|
||||
cmakeWorkspaceFolder.cmakeProject.onCodeModelChanged(FireLate, () => {
|
||||
this.updateCodeModel(cmakeWorkspaceFolder);
|
||||
}),
|
||||
cmakeWorkspaceFolder.cmakeProject.onTargetNameChanged(FireLate, () => this.updateCodeModel(cmakeWorkspaceFolder)),
|
||||
cmakeWorkspaceFolder.cmakeProject.onLaunchTargetNameChanged(FireLate, () => this.updateCodeModel(cmakeWorkspaceFolder)),
|
||||
cmakeWorkspaceFolder.cmakeProject.onActiveBuildPresetChanged(FireLate, () => this.updateCodeModel(cmakeWorkspaceFolder))
|
||||
|
@ -266,7 +273,7 @@ class ExtensionManager implements vscode.Disposable {
|
|||
/**
|
||||
* The folder controller manages multiple instances. One per folder.
|
||||
*/
|
||||
private readonly cmakeWorkspaceFolders = new CMakeWorkspaceFolderController(this.extensionContext);
|
||||
public readonly cmakeWorkspaceFolders = new CMakeWorkspaceFolderController(this.extensionContext);
|
||||
|
||||
/**
|
||||
* The map caching for each folder whether it is a CMake project or not.
|
||||
|
@ -679,6 +686,7 @@ class ExtensionManager implements vscode.Disposable {
|
|||
}
|
||||
this.projectOutlineProvider.setActiveFolder(ws);
|
||||
this.setupSubscriptions();
|
||||
this.onActiveProjectChangedEmitter.fire(ws?.uri);
|
||||
}
|
||||
|
||||
private disposeSubs() {
|
||||
|
@ -810,10 +818,12 @@ class ExtensionManager implements vscode.Disposable {
|
|||
this.statusMessageSub = cmakeProject.onStatusMessageChanged(FireNow, s => this.statusBar.setStatusMessage(s));
|
||||
this.targetNameSub = cmakeProject.onTargetNameChanged(FireNow, t => {
|
||||
this.statusBar.setBuildTargetName(t);
|
||||
this.onBuildTargetChangedEmitter.fire(t);
|
||||
});
|
||||
this.buildTypeSub = cmakeProject.onActiveVariantNameChanged(FireNow, bt => this.statusBar.setVariantLabel(bt));
|
||||
this.launchTargetSub = cmakeProject.onLaunchTargetNameChanged(FireNow, t => {
|
||||
this.statusBar.setLaunchTargetName(t || '');
|
||||
this.onLaunchTargetChangedEmitter.fire(t || '');
|
||||
});
|
||||
this.ctestEnabledSub = cmakeProject.onCTestEnabledChanged(FireNow, e => this.statusBar.setCTestEnabled(e));
|
||||
this.testResultsSub = cmakeProject.onTestResultsChanged(FireNow, r => this.statusBar.setTestResults(r));
|
||||
|
@ -1614,9 +1624,26 @@ class ExtensionManager implements vscode.Disposable {
|
|||
|
||||
return presetSelected;
|
||||
}
|
||||
|
||||
public api: CMakeToolsApiImpl;
|
||||
|
||||
get onBuildTargetChanged() {
|
||||
return this.onBuildTargetChangedEmitter.event;
|
||||
}
|
||||
private readonly onBuildTargetChangedEmitter = new vscode.EventEmitter<string>();
|
||||
|
||||
get onLaunchTargetChanged() {
|
||||
return this.onLaunchTargetChangedEmitter.event;
|
||||
}
|
||||
private readonly onLaunchTargetChangedEmitter = new vscode.EventEmitter<string>();
|
||||
|
||||
get onActiveProjectChanged() {
|
||||
return this.onActiveProjectChangedEmitter.event;
|
||||
}
|
||||
private readonly onActiveProjectChangedEmitter = new vscode.EventEmitter<vscode.Uri | undefined>();
|
||||
}
|
||||
|
||||
async function setup(context: vscode.ExtensionContext, progress?: ProgressHandle) {
|
||||
async function setup(context: vscode.ExtensionContext, progress?: ProgressHandle): Promise<api.CMakeToolsExtensionExports> {
|
||||
reportProgress(localize('initial.setup', 'Initial setup'), progress);
|
||||
|
||||
// Load a new extension manager
|
||||
|
@ -1776,6 +1803,8 @@ async function setup(context: vscode.ExtensionContext, progress?: ProgressHandle
|
|||
vscode.commands.registerCommand('cmake.outline.selectWorkspace',
|
||||
(what: WorkspaceFolderNode) => runCommand('selectWorkspace', what.wsFolder))
|
||||
]);
|
||||
|
||||
return { getApi: (_version) => ext.api };
|
||||
}
|
||||
|
||||
class SchemaProvider implements vscode.TextDocumentContentProvider {
|
||||
|
@ -1797,7 +1826,7 @@ class SchemaProvider implements vscode.TextDocumentContentProvider {
|
|||
* @param context The extension context
|
||||
* @returns A promise that will resolve when the extension is ready for use
|
||||
*/
|
||||
export async function activate(context: vscode.ExtensionContext) {
|
||||
export async function activate(context: vscode.ExtensionContext): Promise<api.CMakeToolsExtensionExports> {
|
||||
// CMakeTools versions newer or equal to #1.2 should not coexist with older versions
|
||||
// because the publisher changed (from vector-of-bool into ms-vscode),
|
||||
// causing many undesired behaviors (duplicate operations, registrations for UI elements, etc...)
|
||||
|
@ -1816,10 +1845,6 @@ export async function activate(context: vscode.ExtensionContext) {
|
|||
taskProvider = vscode.tasks.registerTaskProvider(CMakeTaskProvider.CMakeScriptType, cmakeTaskProvider);
|
||||
|
||||
return setup(context);
|
||||
|
||||
// TODO: Return the extension API
|
||||
// context.subscriptions.push(vscode.commands.registerCommand('cmake._extensionInstance', () => cmakeProject));
|
||||
|
||||
}
|
||||
|
||||
// Enable all or part of the CMake Tools palette commands
|
||||
|
|
22
src/proc.ts
22
src/proc.ts
|
@ -12,9 +12,7 @@ import rollbar from './rollbar';
|
|||
import * as util from './util';
|
||||
import * as vscode from 'vscode';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { ExecutionResult } from './api';
|
||||
import { Environment, EnvironmentUtils } from './environmentVariables';
|
||||
export { ExecutionResult } from './api';
|
||||
|
||||
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
|
||||
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
|
||||
|
@ -76,6 +74,26 @@ export interface BuildCommand {
|
|||
|
||||
export interface DebuggerEnvironmentVariable { name: string; value: string }
|
||||
|
||||
/**
|
||||
* The result of executing a program.
|
||||
*/
|
||||
export interface ExecutionResult {
|
||||
/**
|
||||
* The return code of the program.
|
||||
*/
|
||||
retc: number | null;
|
||||
/**
|
||||
* The full standard output of the program. May be `` if standard out
|
||||
* was not captured.
|
||||
*/
|
||||
stdout: string;
|
||||
/**
|
||||
* Standard error output of the program. May be `` if standard error was
|
||||
* not captured
|
||||
*/
|
||||
stderr: string;
|
||||
}
|
||||
|
||||
export interface ExecutionOptions {
|
||||
environment?: Environment;
|
||||
shell?: boolean;
|
||||
|
|
|
@ -849,3 +849,11 @@ export async function scheduleAsyncTask<T>(task: () => Promise<T>): Promise<T> {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Asserts that the given value has no valid type. Useful for exhaustiveness checks.
|
||||
* @param value The value to be checked.
|
||||
*/
|
||||
export function assertNever(value: never): never {
|
||||
throw new Error(`Unexpected value: ${value}`);
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import * as api from '@cmt/api';
|
||||
import { CMakeCache } from '@cmt/cache';
|
||||
import { CMakeCache, CacheEntryType } from '@cmt/cache';
|
||||
import { clearExistingKitConfigurationFile, DefaultEnvironment, expect, getFirstSystemKit } from '@test/util';
|
||||
import { fs } from '@cmt/pr';
|
||||
import * as path from 'path';
|
||||
|
@ -51,7 +50,7 @@ suite('Environment Variables in Variants', () => {
|
|||
const cacheEntry_ = cache.get('variantEnv');
|
||||
expect(cacheEntry_).to.not.be.eq(null, '[variantEnv] Cache entry was not present');
|
||||
const cacheEntry = cacheEntry_!;
|
||||
expect(cacheEntry.type).to.eq(api.CacheEntryType.String, '[variantEnv] unexpected cache entry type');
|
||||
expect(cacheEntry.type).to.eq(CacheEntryType.String, '[variantEnv] unexpected cache entry type');
|
||||
expect(cacheEntry.key).to.eq('variantEnv', '[variantEnv] unexpected cache entry key name');
|
||||
expect(typeof cacheEntry.value).to.eq('string', '[variantEnv] unexpected cache entry value type');
|
||||
expect(cacheEntry.as<string>())
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import * as api from '@cmt/api';
|
||||
import { CMakeCache } from '@cmt/cache';
|
||||
import { CMakeCache, CacheEntryType } from '@cmt/cache';
|
||||
import { clearExistingKitConfigurationFile, DefaultEnvironment, expect, getFirstSystemKit } from '@test/util';
|
||||
import { fs } from '@cmt/pr';
|
||||
import * as path from 'path';
|
||||
|
@ -57,7 +56,7 @@ suite('Environment Variables in Variants', () => {
|
|||
const cacheEntry_ = cache.get('variantEnv');
|
||||
expect(cacheEntry_).to.not.be.eq(null, '[variantEnv] Cache entry was not present');
|
||||
const cacheEntry = cacheEntry_!;
|
||||
expect(cacheEntry.type).to.eq(api.CacheEntryType.String, '[variantEnv] unexpected cache entry type');
|
||||
expect(cacheEntry.type).to.eq(CacheEntryType.String, '[variantEnv] unexpected cache entry type');
|
||||
expect(cacheEntry.key).to.eq('variantEnv', '[variantEnv] unexpected cache entry key name');
|
||||
expect(typeof cacheEntry.value).to.eq('string', '[variantEnv] unexpected cache entry value type');
|
||||
expect(cacheEntry.as<string>())
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import * as api from '@cmt/api';
|
||||
import { CMakeCache } from '@cmt/cache';
|
||||
import { CMakeCache, CacheEntryType } from '@cmt/cache';
|
||||
import { DefaultEnvironment, expect } from '@test/util';
|
||||
import * as vscode from 'vscode';
|
||||
|
||||
|
@ -40,7 +39,7 @@ suite('Environment Variables in Presets', () => {
|
|||
const cacheEntry_ = cache.get('variantEnv');
|
||||
expect(cacheEntry_).to.not.be.eq(null, '[variantEnv] Cache entry was not present');
|
||||
const cacheEntry = cacheEntry_!;
|
||||
expect(cacheEntry.type).to.eq(api.CacheEntryType.String, '[variantEnv] unexpected cache entry type');
|
||||
expect(cacheEntry.type).to.eq(CacheEntryType.String, '[variantEnv] unexpected cache entry type');
|
||||
expect(cacheEntry.key).to.eq('variantEnv', '[variantEnv] unexpected cache entry key name');
|
||||
expect(typeof cacheEntry.value).to.eq('string', '[variantEnv] unexpected cache entry value type');
|
||||
expect(cacheEntry.as<string>()).to.eq('0cbfb6ae-f2ec-4017-8ded-89df8759c502', '[variantEnv] incorrect environment variable');
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import * as api from '@cmt/api';
|
||||
import { CMakeCache } from '@cmt/cache';
|
||||
import { CMakeCache, CacheEntryType, CacheEntry } from '@cmt/cache';
|
||||
import { CMakeProject } from '@cmt/cmakeProject';
|
||||
import { clearExistingKitConfigurationFile, DefaultEnvironment, expect, getFirstSystemKit } from '@test/util';
|
||||
import * as path from 'path';
|
||||
|
@ -42,8 +41,8 @@ suite('Environment', () => {
|
|||
expect(testEnv.projectFolder.buildDirectory.isCMakeCachePresent).to.eql(true, 'expected cache not present');
|
||||
const cache = await CMakeCache.fromPath(await cmakeProject.cachePath);
|
||||
|
||||
const cacheEntry = cache.get('configureEnvironment') as api.CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(api.CacheEntryType.String, '[configureEnvironment] unexpected cache entry type');
|
||||
const cacheEntry = cache.get('configureEnvironment') as CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(CacheEntryType.String, '[configureEnvironment] unexpected cache entry type');
|
||||
expect(cacheEntry.key).to.eq('configureEnvironment', '[configureEnvironment] unexpected cache entry key name');
|
||||
expect(cacheEntry.as<string>())
|
||||
.to.eq(path.basename(testEnv.projectFolder.location), '[configureEnvironment] substitution incorrect');
|
||||
|
@ -64,8 +63,8 @@ suite('Environment', () => {
|
|||
expect(testEnv.projectFolder.buildDirectory.isCMakeCachePresent).to.eql(true, 'expected cache not present');
|
||||
const cache = await CMakeCache.fromPath(await cmakeProject.cachePath);
|
||||
|
||||
const cacheEntry = cache.get('buildEnvironment') as api.CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(api.CacheEntryType.String, '[buildEnvironment] unexpected cache entry type');
|
||||
const cacheEntry = cache.get('buildEnvironment') as CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(CacheEntryType.String, '[buildEnvironment] unexpected cache entry type');
|
||||
expect(cacheEntry.key).to.eq('buildEnvironment', '[buildEnvironment] unexpected cache entry key name');
|
||||
expect(cacheEntry.as<string>()).to.be.eq('', '[buildEnvironment] env-var got passed to CMake');
|
||||
expect(typeof cacheEntry.value).to.eq('string', '[buildEnvironment] unexpected cache entry value type');
|
||||
|
@ -86,8 +85,8 @@ suite('Environment', () => {
|
|||
expect(testEnv.projectFolder.buildDirectory.isCMakeCachePresent).to.eql(true, 'expected cache not present');
|
||||
const cache = await CMakeCache.fromPath(await cmakeProject.cachePath);
|
||||
|
||||
const cacheEntry = cache.get('environment') as api.CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(api.CacheEntryType.String, '[environment] unexpected cache entry type');
|
||||
const cacheEntry = cache.get('environment') as CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(CacheEntryType.String, '[environment] unexpected cache entry type');
|
||||
expect(cacheEntry.key).to.eq('environment', '[environment] unexpected cache entry key name');
|
||||
expect(cacheEntry.as<string>())
|
||||
.to.eq(path.basename(testEnv.projectFolder.location), '[environment] substitution incorrect');
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
/* eslint-disable no-unused-expressions */
|
||||
import * as api from '@cmt/api';
|
||||
import { CMakeCache } from '@cmt/cache';
|
||||
import { CMakeCache, CacheEntry } from '@cmt/cache';
|
||||
import { CMakeProject, ConfigureTrigger } from '@cmt/cmakeProject';
|
||||
import { readKitsFile, kitsForWorkspaceDirectory, getAdditionalKits, USER_KITS_FILEPATH } from '@cmt/kit';
|
||||
import { platformNormalizePath } from '@cmt/util';
|
||||
|
@ -52,7 +51,7 @@ suite('Toolchain Substitution', () => {
|
|||
expect(testEnv.projectFolder.buildDirectory.isCMakeCachePresent).to.eql(true, 'expected cache not present');
|
||||
const cache = await CMakeCache.fromPath(await cmakeProject.cachePath);
|
||||
|
||||
const cacheEntry = cache.get('CMAKE_TOOLCHAIN_FILE') as api.CacheEntry;
|
||||
const cacheEntry = cache.get('CMAKE_TOOLCHAIN_FILE') as CacheEntry;
|
||||
expect(cacheEntry).to.not.be.null;
|
||||
expect(cacheEntry.key).to.eq('CMAKE_TOOLCHAIN_FILE', '[toolchain] unexpected cache entry key name');
|
||||
expect(platformNormalizePath(cacheEntry.as<string>()))
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import * as api from '@cmt/api';
|
||||
import { CMakeCache } from '@cmt/cache';
|
||||
import { CMakeCache, CacheEntryType, CacheEntry } from '@cmt/cache';
|
||||
import { CMakeProject, ConfigureTrigger } from '@cmt/cmakeProject';
|
||||
import paths from '@cmt/paths';
|
||||
import { objectPairs, platformNormalizePath, makeHashString } from '@cmt/util';
|
||||
|
@ -55,46 +54,46 @@ suite('Variable Substitution', () => {
|
|||
const cache = await CMakeCache.fromPath(await cmakeProject.cachePath);
|
||||
|
||||
// Check substitution for "workspaceRoot"
|
||||
let cacheEntry = cache.get('workspaceRoot') as api.CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(api.CacheEntryType.String, '[workspaceRoot] unexpected cache entry type');
|
||||
let cacheEntry = cache.get('workspaceRoot') as CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(CacheEntryType.String, '[workspaceRoot] unexpected cache entry type');
|
||||
expect(cacheEntry.key).to.eq('workspaceRoot', '[workspaceRoot] unexpected cache entry key name');
|
||||
expect(platformNormalizePath(cacheEntry.as<string>()))
|
||||
.to.eq(platformNormalizePath(testEnv.projectFolder.location), '[workspaceRoot] substitution incorrect');
|
||||
expect(typeof cacheEntry.value).to.eq('string', '[workspaceRoot] unexpected cache entry value type');
|
||||
|
||||
// Check substitution for "workspaceFolder".
|
||||
cacheEntry = cache.get('workspaceFolder') as api.CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(api.CacheEntryType.String, '[workspaceFolder] unexpected cache entry type');
|
||||
cacheEntry = cache.get('workspaceFolder') as CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(CacheEntryType.String, '[workspaceFolder] unexpected cache entry type');
|
||||
expect(cacheEntry.key).to.eq('workspaceFolder', '[workspaceFolder] unexpected cache entry key name');
|
||||
expect(platformNormalizePath(cacheEntry.as<string>()))
|
||||
.to.eq(platformNormalizePath(testEnv.projectFolder.location), '[workspaceFolder] substitution incorrect');
|
||||
expect(typeof cacheEntry.value).to.eq('string', '[workspaceFolder] unexpected cache entry value type');
|
||||
|
||||
// Check substitution for "workspaceHash".
|
||||
cacheEntry = cache.get('workspaceHash') as api.CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(api.CacheEntryType.String, '[workspaceHash] unexpected cache entry type');
|
||||
cacheEntry = cache.get('workspaceHash') as CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(CacheEntryType.String, '[workspaceHash] unexpected cache entry type');
|
||||
expect(cacheEntry.key).to.eq('workspaceHash', '[workspaceHash] unexpected cache entry key name');
|
||||
expect(cacheEntry.as<string>()).to.eq(makeHashString(testEnv.projectFolder.location), '[workspaceHash] substitution incorrect');
|
||||
expect(typeof cacheEntry.value).to.eq('string', '[workspaceHash] unexpected cache entry value type');
|
||||
|
||||
// Check substitution for "buildType".
|
||||
cacheEntry = cache.get('buildType') as api.CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(api.CacheEntryType.String, '[buildType] unexpected cache entry type');
|
||||
cacheEntry = cache.get('buildType') as CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(CacheEntryType.String, '[buildType] unexpected cache entry type');
|
||||
expect(cacheEntry.key).to.eq('buildType', '[buildType] unexpected cache entry key name');
|
||||
expect(cacheEntry.as<string>()).to.eq('Debug', '[buildType] substitution incorrect');
|
||||
expect(typeof cacheEntry.value).to.eq('string', '[buildType] unexpected cache entry value type');
|
||||
|
||||
// Check substitution for "buildKit".
|
||||
cacheEntry = cache.get('buildKit') as api.CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(api.CacheEntryType.String, '[buildKit] unexpected cache entry type');
|
||||
cacheEntry = cache.get('buildKit') as CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(CacheEntryType.String, '[buildKit] unexpected cache entry type');
|
||||
expect(cacheEntry.key).to.eq('buildKit', '[buildKit] unexpected cache entry key name');
|
||||
const kit = cmakeProject.activeKit;
|
||||
expect(cacheEntry.as<string>()).to.eq(kit!.name, '[buildKit] substitution incorrect');
|
||||
expect(typeof cacheEntry.value).to.eq('string', '[buildKit] unexpected cache entry value type');
|
||||
|
||||
// Check substitution for "workspaceRootFolderName".
|
||||
cacheEntry = cache.get('workspaceRootFolderName') as api.CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(api.CacheEntryType.String, '[workspaceRootFolderName] unexpected cache entry type');
|
||||
cacheEntry = cache.get('workspaceRootFolderName') as CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(CacheEntryType.String, '[workspaceRootFolderName] unexpected cache entry type');
|
||||
expect(cacheEntry.key)
|
||||
.to.eq('workspaceRootFolderName', '[workspaceRootFolderName] unexpected cache entry key name');
|
||||
expect(cacheEntry.as<string>())
|
||||
|
@ -102,8 +101,8 @@ suite('Variable Substitution', () => {
|
|||
expect(typeof cacheEntry.value).to.eq('string', '[workspaceRootFolderName] unexpected cache entry value type');
|
||||
|
||||
// Check substitution for "workspaceFolderBasename".
|
||||
cacheEntry = cache.get('workspaceFolderBasename') as api.CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(api.CacheEntryType.String, '[workspaceFolderBasename] unexpected cache entry type');
|
||||
cacheEntry = cache.get('workspaceFolderBasename') as CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(CacheEntryType.String, '[workspaceFolderBasename] unexpected cache entry type');
|
||||
expect(cacheEntry.key)
|
||||
.to.eq('workspaceFolderBasename', '[workspaceFolderBasename] unexpected cache entry key name');
|
||||
expect(cacheEntry.as<string>())
|
||||
|
@ -111,23 +110,23 @@ suite('Variable Substitution', () => {
|
|||
expect(typeof cacheEntry.value).to.eq('string', '[workspaceFolderBasename] unexpected cache entry value type');
|
||||
|
||||
// Check substitution for "generator".
|
||||
cacheEntry = cache.get('generator') as api.CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(api.CacheEntryType.String, '[generator] unexpected cache entry type');
|
||||
cacheEntry = cache.get('generator') as CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(CacheEntryType.String, '[generator] unexpected cache entry type');
|
||||
expect(cacheEntry.key).to.eq('generator', '[generator] unexpected cache entry key name');
|
||||
const generator = cache.get('CMAKE_GENERATOR') as api.CacheEntry;
|
||||
const generator = cache.get('CMAKE_GENERATOR') as CacheEntry;
|
||||
expect(cacheEntry.as<string>()).to.eq(generator.as<string>(), '[generator] substitution incorrect');
|
||||
expect(typeof cacheEntry.value).to.eq('string', '[generator] unexpected cache entry value type');
|
||||
|
||||
// Check substitution for "userHome".
|
||||
cacheEntry = cache.get('userHome') as api.CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(api.CacheEntryType.String, '[userHome] unexpected cache entry type');
|
||||
cacheEntry = cache.get('userHome') as CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(CacheEntryType.String, '[userHome] unexpected cache entry type');
|
||||
expect(cacheEntry.key).to.eq('userHome', '[userHome] unexpected cache entry key name');
|
||||
expect(cacheEntry.as<string>()).to.eq(paths.userHome, '[userHome] substitution incorrect');
|
||||
expect(typeof cacheEntry.value).to.eq('string', '[userHome] unexpected cache entry value type');
|
||||
|
||||
// Check substitution within "cmake.installPrefix".
|
||||
cacheEntry = cache.get('CMAKE_INSTALL_PREFIX') as api.CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(api.CacheEntryType.String, '[cmakeInstallPrefix] unexpected cache entry type');
|
||||
cacheEntry = cache.get('CMAKE_INSTALL_PREFIX') as CacheEntry;
|
||||
expect(cacheEntry.type).to.eq(CacheEntryType.String, '[cmakeInstallPrefix] unexpected cache entry type');
|
||||
expect(cacheEntry.key).to.eq('CMAKE_INSTALL_PREFIX', '[cmakeInstallPrefix] unexpected cache entry key name');
|
||||
expect(platformNormalizePath(cacheEntry.as<string>()))
|
||||
.to.eq(platformNormalizePath(testEnv.projectFolder.buildDirectory.location.concat('/dist')),
|
||||
|
@ -155,10 +154,10 @@ suite('Variable Substitution', () => {
|
|||
const [key, expected] = testKey;
|
||||
|
||||
// Get cache entry for given test key
|
||||
const cacheEntry = testCache.get(key) as api.CacheEntry;
|
||||
const cacheEntry = testCache.get(key) as CacheEntry;
|
||||
|
||||
// Check type and value of the retrieved cache entry
|
||||
expect(cacheEntry.type).to.eq(api.CacheEntryType.String, `[variant:${key}] unexpected cache entry type`);
|
||||
expect(cacheEntry.type).to.eq(CacheEntryType.String, `[variant:${key}] unexpected cache entry type`);
|
||||
expect(cacheEntry.key).to.eql(key, `[variant:${key}] unexpected cache entry key name`);
|
||||
expect(cacheEntry.as<string>()).to.eql(expected, `[variant:${key}] incorrect substitution`);
|
||||
expect(typeof cacheEntry.value).to.eq('string', `[variant:${key}] unexpected cache entry value type`);
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
/* eslint-disable no-unused-expressions */
|
||||
|
||||
import * as api from '@cmt/api';
|
||||
import { CMakeCache } from '@cmt/cache';
|
||||
import { CMakeCache, CacheEntryType } from '@cmt/cache';
|
||||
import { CMakeProject } from '@cmt/cmakeProject';
|
||||
import { clearExistingKitConfigurationFile, DefaultEnvironment, expect, getFirstSystemKit } from '@test/util';
|
||||
import { fs } from '@cmt/pr';
|
||||
|
@ -80,7 +79,7 @@ suite('Environment Variables in Variants', () => {
|
|||
const cacheEntry_ = cache.get('variantEnv');
|
||||
expect(cacheEntry_).to.not.be.eq(null, '[variantEnv] Cache entry was not present');
|
||||
const cacheEntry = cacheEntry_!;
|
||||
expect(cacheEntry.type).to.eq(api.CacheEntryType.String, '[variantEnv] unexpected cache entry type');
|
||||
expect(cacheEntry.type).to.eq(CacheEntryType.String, '[variantEnv] unexpected cache entry type');
|
||||
expect(cacheEntry.key).to.eq('variantEnv', '[variantEnv] unexpected cache entry key name');
|
||||
expect(typeof cacheEntry.value).to.eq('string', '[variantEnv] unexpected cache entry value type');
|
||||
expect(cacheEntry.as<string>()).to.eq('0xCAFE', '[variantEnv] incorrect environment variable');
|
||||
|
|
|
@ -6,8 +6,7 @@ import * as path from 'path';
|
|||
chai.use(chaiAsPromised);
|
||||
|
||||
import { expect } from 'chai';
|
||||
import * as api from '../../src/api';
|
||||
import { CMakeCache } from '../../src/cache';
|
||||
import { CMakeCache, CacheEntryType, CacheEntry } from '../../src/cache';
|
||||
import * as util from '../../src/util';
|
||||
|
||||
const here = __dirname;
|
||||
|
@ -18,14 +17,14 @@ function getTestResourceFilePath(filename: string): string {
|
|||
suite('Cache test', () => {
|
||||
test('Read CMake Cache', async () => {
|
||||
const cache = await CMakeCache.fromPath(getTestResourceFilePath('TestCMakeCache.txt'));
|
||||
const generator = cache.get('CMAKE_GENERATOR') as api.CacheEntry;
|
||||
expect(generator.type).to.eq(api.CacheEntryType.Internal);
|
||||
const generator = cache.get('CMAKE_GENERATOR') as CacheEntry;
|
||||
expect(generator.type).to.eq(CacheEntryType.Internal);
|
||||
expect(generator.key).to.eq('CMAKE_GENERATOR');
|
||||
expect(generator.as<string>()).to.eq('Ninja');
|
||||
expect(typeof generator.value).to.eq('string');
|
||||
|
||||
const build_testing = cache.get('BUILD_TESTING') as api.CacheEntry;
|
||||
expect(build_testing.type).to.eq(api.CacheEntryType.Bool);
|
||||
const build_testing = cache.get('BUILD_TESTING') as CacheEntry;
|
||||
expect(build_testing.type).to.eq(CacheEntryType.Bool);
|
||||
expect(build_testing.as<boolean>()).to.be.true;
|
||||
});
|
||||
test('Read cache with various newlines', async () => {
|
||||
|
@ -36,7 +35,7 @@ suite('Cache test', () => {
|
|||
expect(entries.has('SOMETHING')).to.be.true;
|
||||
const entry = entries.get('SOMETHING')!;
|
||||
expect(entry.value).to.eq('foo');
|
||||
expect(entry.type).to.eq(api.CacheEntryType.String);
|
||||
expect(entry.type).to.eq(CacheEntryType.String);
|
||||
expect(entry.helpString).to.eq('This line is docs');
|
||||
}
|
||||
});
|
||||
|
@ -47,7 +46,7 @@ suite('Cache test', () => {
|
|||
expect(entries.has('FIRSTPART:SECONDPART')).to.be.true;
|
||||
const entry = entries.get('FIRSTPART:SECONDPART')!;
|
||||
expect(entry.value).to.eq('value');
|
||||
expect(entry.type).to.eq(api.CacheEntryType.String);
|
||||
expect(entry.type).to.eq(CacheEntryType.String);
|
||||
});
|
||||
test('Read cache entry with double quotes, but no colon', async () => {
|
||||
const str = "\"QUOTED\":STRING=value";
|
||||
|
@ -56,7 +55,7 @@ suite('Cache test', () => {
|
|||
expect(entries.has('QUOTED')).to.be.true;
|
||||
const entry = entries.get('QUOTED')!;
|
||||
expect(entry.value).to.eq('value');
|
||||
expect(entry.type).to.eq(api.CacheEntryType.String);
|
||||
expect(entry.type).to.eq(CacheEntryType.String);
|
||||
});
|
||||
test('Falsey values', () => {
|
||||
const false_things = [
|
||||
|
|
|
@ -6250,6 +6250,11 @@ vsce@^2.7.0:
|
|||
yauzl "^2.3.1"
|
||||
yazl "^2.2.2"
|
||||
|
||||
vscode-cmake-tools@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-cmake-tools/-/vscode-cmake-tools-1.0.0.tgz#0321a74cd073c858c440b01602e164ecb824bd98"
|
||||
integrity sha512-oZO+Ulo+OGaFuGQaPlNh+qDUWth0kmyz0d45Ws6KmqLGf1Q9gCOBct6jz7mAtzR/IqrCe/VV3O/CUmHfXpIZEA==
|
||||
|
||||
vscode-cpptools@^6.1.0:
|
||||
version "6.1.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-cpptools/-/vscode-cpptools-6.1.0.tgz#d89bb225f91da45dbee6acbf45f6940aa3926df1"
|
||||
|
|
Загрузка…
Ссылка в новой задаче