Reactivate all extension test workspaces
This commit is contained in:
Родитель
f029bf098a
Коммит
5cf27f3c88
|
@ -2,11 +2,11 @@ language: cpp
|
|||
|
||||
os:
|
||||
- osx
|
||||
- linux
|
||||
# - linux
|
||||
|
||||
compiler:
|
||||
- clang
|
||||
- gcc
|
||||
# - gcc
|
||||
|
||||
dist: trusty
|
||||
sudo: false
|
||||
|
|
|
@ -59,7 +59,7 @@ if (! $NoTest) {
|
|||
-TestsPath "$REPO_DIR/out/test/unit-tests" `
|
||||
-Workspace "$REPO_DIR/test/unit-tests/test-project-without-cmakelists"
|
||||
|
||||
foreach ($name in @("successful-build"; )) {
|
||||
foreach ($name in @("vs-preferred-gen"; "successful-build"; "without-cmakelist-file"; )) {
|
||||
Invoke-VSCodeTest "CMake Tools: $name" `
|
||||
-TestsPath "$REPO_DIR/out/test/extension-tests/$name" `
|
||||
-Workspace "$REPO_DIR/test/extension-tests/$name/project-folder"
|
||||
|
|
|
@ -16,7 +16,7 @@ import * as proc from './proc';
|
|||
import rollbar from './rollbar';
|
||||
import {StateManager} from './state';
|
||||
import * as util from './util';
|
||||
import {ConfigureArguments, VariantConfigurationOptions} from './variant';
|
||||
import {ConfigureArguments, VariantOption} from './variant';
|
||||
|
||||
const log = logging.createLogger('driver');
|
||||
|
||||
|
@ -259,6 +259,9 @@ export abstract class CMakeDriver implements vscode.Disposable {
|
|||
log.debug('CMakeDriver Kit set to', kit.name);
|
||||
|
||||
this._kitEnvironmentVariables = new Map();
|
||||
if (this._kit.environmentVariables) {
|
||||
util.objectPairs(this._kit.environmentVariables).forEach(([k, v]) => this._kitEnvironmentVariables.set(k, v));
|
||||
}
|
||||
switch (this._kit.type) {
|
||||
case 'vsKit': {
|
||||
const vars = await getVSKitEnvironment(this._kit);
|
||||
|
@ -266,7 +269,7 @@ export abstract class CMakeDriver implements vscode.Disposable {
|
|||
log.error('Invalid VS environment:', this._kit.name);
|
||||
log.error('We couldn\'t find the required environment variables');
|
||||
} else {
|
||||
this._kitEnvironmentVariables = vars;
|
||||
vars.forEach((val, key) => this._kitEnvironmentVariables.set(key, val));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -304,7 +307,7 @@ export abstract class CMakeDriver implements vscode.Disposable {
|
|||
* Change the current options from the variant.
|
||||
* @param opts The new options
|
||||
*/
|
||||
async setVariantOptions(opts: VariantConfigurationOptions) {
|
||||
async setVariantOptions(opts: VariantOption) {
|
||||
log.debug('Setting new variant', opts.long || '(Unnamed)');
|
||||
this._variantBuildType = opts.buildType || this._variantBuildType;
|
||||
this._variantConfigureSettings = opts.settings || this._variantConfigureSettings;
|
||||
|
|
|
@ -46,6 +46,11 @@ export interface BaseKit {
|
|||
* Additional settings to pass to CMake
|
||||
*/
|
||||
cmakeSettings?: {[key: string]: string};
|
||||
|
||||
/**
|
||||
* Additional environment variables for the kit
|
||||
*/
|
||||
environmentVariables?: proc.EnvironmentVariables;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -251,7 +251,7 @@ export function versionLess(lhs: Version, rhs: Version|string): boolean {
|
|||
return !versionGreater(lhs, rhs) && !versionEquals(lhs, rhs);
|
||||
}
|
||||
|
||||
export function mergeEnvironment(...env: EnvironmentVariables[]) {
|
||||
export function mergeEnvironment(...env: EnvironmentVariables[]): EnvironmentVariables {
|
||||
return env.reduce((acc, vars) => {
|
||||
if (process.platform === 'win32') {
|
||||
// Env vars on windows are case insensitive, so we take the ones from
|
||||
|
|
222
src/variant.ts
222
src/variant.ts
|
@ -15,37 +15,132 @@ import {MultiWatcher} from './watcher';
|
|||
|
||||
const log = logging.createLogger('variant');
|
||||
|
||||
/**
|
||||
* Configure arguments for CMake
|
||||
*/
|
||||
export interface ConfigureArguments {
|
||||
[key: string]: (string|string[]|number|boolean);
|
||||
}
|
||||
|
||||
export type ConfigureArguments = {
|
||||
[key: string]: (string|string[]|number|boolean)
|
||||
};
|
||||
|
||||
export interface VariantConfigurationOptions {
|
||||
/**
|
||||
* A `choice` loaded from a `cmake-variants.(yaml|json)`.
|
||||
*/
|
||||
export interface VarFileOption {
|
||||
/**
|
||||
* The short description of the option
|
||||
*/
|
||||
short: string;
|
||||
/**
|
||||
* The long description of the option
|
||||
*/
|
||||
long?: string;
|
||||
/**
|
||||
* The `CMAKE_BUILD_TYPE` for the option.
|
||||
*/
|
||||
buildType?: string;
|
||||
/**
|
||||
* Whether we set `BUILD_SHARED_LIBS`
|
||||
*/
|
||||
linkage?: 'static'|'shared';
|
||||
/**
|
||||
* Other CMake cache arguments for the option
|
||||
*/
|
||||
settings?: ConfigureArguments;
|
||||
generator?: string;
|
||||
toolset?: string;
|
||||
/**
|
||||
* Environment variables to set for the option
|
||||
*/
|
||||
env?: EnvironmentVariables;
|
||||
}
|
||||
|
||||
/**
|
||||
* A setting loaded from a `cmake-variants.(yaml|json)`.
|
||||
*/
|
||||
export interface VarFileSetting {
|
||||
/**
|
||||
* The default option for the setting. Ignored by CMake Tools
|
||||
*/
|
||||
default: string;
|
||||
/**
|
||||
* The description of the setting. Ignored by CMake Tools
|
||||
*/
|
||||
description: string;
|
||||
/**
|
||||
* The possible options for this setting.
|
||||
*/
|
||||
choices: {[key: string]: VarFileOption|undefined;};
|
||||
}
|
||||
/**
|
||||
* The root of a `cmake-variants.(yaml|json)`
|
||||
*/
|
||||
export interface VarFileRoot {
|
||||
[key: string]: VarFileSetting|undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* An option for a variant. Includes all attributes from `VarFileOption` but
|
||||
* adds a `key` to identify it.
|
||||
*/
|
||||
export interface VariantOption extends VarFileOption {
|
||||
/**
|
||||
* The key for the option as it appeared in the `choices` option on the
|
||||
* associated setting in the variants file.
|
||||
*/
|
||||
key: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* A possible variant setting with a list of options
|
||||
*/
|
||||
export interface VariantSetting {
|
||||
description?: string;
|
||||
default_: string;
|
||||
choices: Map<string, VariantConfigurationOptions>;
|
||||
/**
|
||||
* The name of the setting.
|
||||
*/
|
||||
name: string;
|
||||
/**
|
||||
* The default option choice for this variant
|
||||
*/
|
||||
default: string;
|
||||
/**
|
||||
* The options available for this setting.
|
||||
*/
|
||||
choices: VariantOption[];
|
||||
}
|
||||
|
||||
export type VariantSet = Map<string, VariantSetting>;
|
||||
|
||||
export interface VariantCombination extends vscode.QuickPickItem { keywordSettings: Map<string, string>; }
|
||||
|
||||
export interface VariantFileContent {
|
||||
[key: string]: {default: string; description: string; choices: {[name: string]: VariantConfigurationOptions;};};
|
||||
/**
|
||||
* A collection of variant settings
|
||||
*/
|
||||
export interface VariantCollection {
|
||||
/**
|
||||
* The settings in this collection
|
||||
*/
|
||||
settings: VariantSetting[];
|
||||
}
|
||||
|
||||
export const DEFAULT_VARIANTS: VariantFileContent = {
|
||||
/**
|
||||
* A variant combination to show to the user in a selection UI
|
||||
*/
|
||||
export interface VariantCombination extends vscode.QuickPickItem {
|
||||
keywordSettings: Map<string, string>;
|
||||
}
|
||||
|
||||
export function processVariantFileData(root: VarFileRoot): VariantCollection {
|
||||
const settings = util.objectPairs(root).map(([setting_name, setting_def]): VariantSetting => {
|
||||
const choices = util.objectPairs(setting_def!.choices).map(([opt_key, opt_def]): VariantOption => {
|
||||
return {
|
||||
...opt_def!,
|
||||
key: opt_key,
|
||||
};
|
||||
});
|
||||
return {
|
||||
name: setting_name,
|
||||
default: setting_def!.default,
|
||||
choices,
|
||||
};
|
||||
});
|
||||
return {settings};
|
||||
}
|
||||
|
||||
export const DEFAULT_VARIANTS: VarFileRoot = {
|
||||
buildType: {
|
||||
default: 'debug',
|
||||
description: 'The build type',
|
||||
|
@ -78,7 +173,7 @@ export class VariantManager implements vscode.Disposable {
|
|||
/**
|
||||
* The variants available for this project
|
||||
*/
|
||||
private _variants: VariantSet = new Map();
|
||||
private _variants: VariantCollection = {settings: []};
|
||||
|
||||
get onActiveVariantChanged() { return this._activeVariantChanged.event; }
|
||||
private readonly _activeVariantChanged = new vscode.EventEmitter<void>();
|
||||
|
@ -149,12 +244,11 @@ export class VariantManager implements vscode.Disposable {
|
|||
if (filepath.endsWith('.json')) {
|
||||
new_variants = json5.parse(content);
|
||||
} else {
|
||||
new_variants = yaml.load(content) as VariantFileContent;
|
||||
new_variants = yaml.load(content) as VarFileRoot;
|
||||
}
|
||||
} catch (e) { log.error(`Error parsing ${filepath}: ${e}`); }
|
||||
}
|
||||
|
||||
let loaded_default = false;
|
||||
const is_valid = validate(new_variants);
|
||||
if (!is_valid) {
|
||||
const errors = validate.errors as ajv.ErrorObject[];
|
||||
|
@ -163,64 +257,32 @@ export class VariantManager implements vscode.Disposable {
|
|||
log.error(` >> ${err.dataPath}: ${err.message}`);
|
||||
}
|
||||
new_variants = DEFAULT_VARIANTS;
|
||||
loaded_default = true;
|
||||
}
|
||||
|
||||
const sets = new Map() as VariantSet;
|
||||
for (const setting_name in new_variants) {
|
||||
const setting = new_variants[setting_name];
|
||||
let def = setting.default;
|
||||
const desc = setting.description;
|
||||
const choices = new Map<string, VariantConfigurationOptions>();
|
||||
for (const choice_name in setting.choices) {
|
||||
const choice = setting.choices[choice_name];
|
||||
choices.set(choice_name, choice);
|
||||
}
|
||||
|
||||
// Check existence of default choice
|
||||
if (!choices.has(def)) {
|
||||
const newDefault = Array.from(choices.keys())[0];
|
||||
log.warning('Invalid variants specified:');
|
||||
log.warning(` >> [${setting_name}]: invalid default choice "${def}", falling back to "${newDefault}"`);
|
||||
def = newDefault;
|
||||
}
|
||||
|
||||
sets.set(setting_name, {
|
||||
default_: def,
|
||||
description: desc,
|
||||
choices,
|
||||
});
|
||||
}
|
||||
|
||||
if (loaded_default) {
|
||||
log.info('Loaded default variants');
|
||||
} else {
|
||||
log.info('Loaded new set of variants');
|
||||
}
|
||||
|
||||
|
||||
this._variants = sets;
|
||||
this._variants = processVariantFileData(new_variants);
|
||||
}
|
||||
|
||||
get haveVariant(): boolean { return !!this.stateManager.activeVariantSettings; }
|
||||
|
||||
variantConfigurationOptionsForKWs(keywordSetting: Map<string, string>): VariantConfigurationOptions[]|string {
|
||||
variantConfigurationOptionsForKWs(keywordSetting: Map<string, string>): VariantOption[]|string {
|
||||
const vars = this._variants;
|
||||
let error: string|undefined = undefined;
|
||||
const data = Array.from(keywordSetting.entries()).map(([param, setting]): VariantConfigurationOptions => {
|
||||
let choice: VariantConfigurationOptions = {short: 'Unknown'};
|
||||
|
||||
if (vars.has(param)) {
|
||||
const choices = vars.get(param)!.choices;
|
||||
if (choices.has(setting)) {
|
||||
choice = choices.get(setting)!;
|
||||
} else {
|
||||
error = `Missing variant choice "${param}": "${setting}" in variant definition.`;
|
||||
}
|
||||
} else {
|
||||
error = `Missing variant "${param}" in variant definition.`;
|
||||
const data = Array.from(keywordSetting.entries()).map(([setting_key, opt_key]): VariantOption => {
|
||||
const unknown_choice: VariantOption = {short: 'Unknown', key: '__unknown__'};
|
||||
const found_setting = vars.settings.find(s => s.name == setting_key);
|
||||
if (!found_setting) {
|
||||
error = `Missing setting "${setting_key}" in variant definition.`;
|
||||
return unknown_choice;
|
||||
}
|
||||
return choice;
|
||||
const found_choice = found_setting.choices.find(o => o.key == opt_key);
|
||||
if (!found_choice) {
|
||||
error = `Missing variant choice "${opt_key}" on "${setting_key}" in variant definition.`;
|
||||
return unknown_choice;
|
||||
}
|
||||
return found_choice;
|
||||
});
|
||||
|
||||
if (error) {
|
||||
|
@ -230,13 +292,12 @@ export class VariantManager implements vscode.Disposable {
|
|||
}
|
||||
}
|
||||
|
||||
mergeVariantConfigurations(options: VariantConfigurationOptions[]): VariantConfigurationOptions {
|
||||
const init = {short: '', long: '', settings: {}} as any as VariantConfigurationOptions;
|
||||
mergeVariantConfigurations(options: VariantOption[]): VariantOption {
|
||||
const init = {short: '', long: '', settings: {}} as any as VariantOption;
|
||||
return options.reduce((acc, el) => ({
|
||||
key: '__merged__',
|
||||
buildType: el.buildType || acc.buildType,
|
||||
generator: el.generator || acc.generator,
|
||||
linkage: el.linkage || acc.linkage,
|
||||
toolset: el.toolset || acc.toolset,
|
||||
// TS 2.4 doesn't like using object spread here, for some reason.
|
||||
// tslint:disable-next-line:prefer-object-spread
|
||||
settings: Object.assign({}, acc.settings, el.settings),
|
||||
|
@ -247,8 +308,9 @@ export class VariantManager implements vscode.Disposable {
|
|||
init);
|
||||
}
|
||||
|
||||
get activeVariantOptions(): VariantConfigurationOptions {
|
||||
get activeVariantOptions(): VariantOption {
|
||||
const invalid_variant = {
|
||||
key: '__invalid__',
|
||||
short: 'Unknown',
|
||||
long: 'Unknwon',
|
||||
};
|
||||
|
@ -280,11 +342,11 @@ export class VariantManager implements vscode.Disposable {
|
|||
}
|
||||
|
||||
async selectVariant() {
|
||||
const variants
|
||||
= Array.from(this._variants.entries())
|
||||
.map(([key, variant]) => Array.from(variant.choices.entries())
|
||||
.map(([value_name, value]) => (
|
||||
{settingKey: key, settingValue: value_name, settings: value})));
|
||||
const variants = this._variants.settings.map(setting => setting.choices.map(opt => ({
|
||||
settingKey: setting.name,
|
||||
settingValue: opt.key,
|
||||
settings: opt,
|
||||
})));
|
||||
const product = util.product(variants);
|
||||
const items: VariantCombination[]
|
||||
= product.map(optionset => ({
|
||||
|
@ -313,10 +375,10 @@ export class VariantManager implements vscode.Disposable {
|
|||
}
|
||||
|
||||
findDefaultChoiceCombination(): Map<string, string> {
|
||||
const defaults = util.map(this._variants.entries(), ([option, definition]) => ({
|
||||
settingKey: option,
|
||||
settingValue: definition.default_,
|
||||
}));
|
||||
const defaults = this._variants.settings.map(setting => ({
|
||||
settingKey: setting.name,
|
||||
settingValue: setting.default,
|
||||
}));
|
||||
return this.transformChoiceCombinationToKeywordSettings(Array.from(defaults));
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче