* update formatting

* add extensions.json
This commit is contained in:
Garrett Campbell 2024-03-05 12:56:31 -05:00 коммит произвёл GitHub
Родитель 8e48036003
Коммит 889d4fff56
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
34 изменённых файлов: 11264 добавлений и 8486 удалений

7
.vscode/extensions.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,7 @@
{
"recommendations": [
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
"redhat.vscode-yaml"
]
}

102
.vscode/launch.json поставляемый
Просмотреть файл

@ -1,55 +1,51 @@
// A launch configuration that compiles the extension and then opens it inside a new window
{
"version": "0.1.0",
"configurations": [
{
"name": "Launch Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"--extensionDevelopmentPath=${workspaceFolder}",
],
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/**/*.js"
],
"env": {
"MAKEFILE_TOOLS_TESTING": "1",
"WindowsSDKVersion": "12.3.45678.9\\",
"CMT_DEVRUN": "1"
},
"preLaunchTask": "build-with-webpack-watch",
},
{
"name": "Launch Tests",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"${workspaceFolder}/src/test/fakeSuite/Repros",
"--disable-workspace-trust",
"--disable-extensions",
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/src/test/fakeSuite/index"
],
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/out/*",
"${workspaceFolder}/out/src/*",
"${workspaceFolder}/out/src/test/**/*"
],
"env": {
"MAKEFILE_TOOLS_TESTING": "1",
"WindowsSDKVersion": "12.3.45678.9\\"
},
"preLaunchTask": "Pretest",
},
{
"name": "Node Attach",
"type": "node",
"request": "attach",
"port": 5858
}
]
}
"version": "0.1.0",
"configurations": [
{
"name": "Launch Extension",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": ["--extensionDevelopmentPath=${workspaceFolder}"],
"sourceMaps": true,
"outFiles": ["${workspaceFolder}/**/*.js"],
"env": {
"MAKEFILE_TOOLS_TESTING": "1",
"WindowsSDKVersion": "12.3.45678.9\\",
"CMT_DEVRUN": "1"
},
"preLaunchTask": "build-with-webpack-watch"
},
{
"name": "Launch Tests",
"type": "extensionHost",
"request": "launch",
"runtimeExecutable": "${execPath}",
"args": [
"${workspaceFolder}/src/test/fakeSuite/Repros",
"--disable-workspace-trust",
"--disable-extensions",
"--extensionDevelopmentPath=${workspaceFolder}",
"--extensionTestsPath=${workspaceFolder}/out/src/test/fakeSuite/index"
],
"sourceMaps": true,
"outFiles": [
"${workspaceFolder}/out/*",
"${workspaceFolder}/out/src/*",
"${workspaceFolder}/out/src/test/**/*"
],
"env": {
"MAKEFILE_TOOLS_TESTING": "1",
"WindowsSDKVersion": "12.3.45678.9\\"
},
"preLaunchTask": "Pretest"
},
{
"name": "Node Attach",
"type": "node",
"request": "attach",
"port": 5858
}
]
}

45
.vscode/settings.json поставляемый
Просмотреть файл

@ -1,12 +1,37 @@
// Place your settings in this file to overwrite default and user settings.
{
"files.exclude": {
"out": false // set this to true to hide the "out" folder with the compiled JS files
},
"search.exclude": {
"out": true // set this to false to include "out" folder in search results
},
"typescript.tsdk": "./node_modules/typescript/lib",
"editor.detectIndentation": false,
"cmake.configureOnOpen": false // we want to use the TS server from our node_modules folder to control its version
}
"files.exclude": {
"out": false // set this to true to hide the "out" folder with the compiled JS files
},
"search.exclude": {
"out": true // set this to false to include "out" folder in search results
},
"typescript.tsdk": "./node_modules/typescript/lib",
"editor.detectIndentation": false,
"cmake.configureOnOpen": false, // we want to use the TS server from our node_modules folder to control its version
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.tabSize": 2
},
"[javascript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.tabSize": 2
},
"[yaml]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.tabSize": 2
},
"[json]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.tabSize": 2
},
"[jsonc]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.formatOnSave": true,
"editor.tabSize": 2
}
}

118
.vscode/tasks.json поставляемый
Просмотреть файл

@ -1,66 +1,58 @@
{
"version": "2.0.0",
"tasks": [
"version": "2.0.0",
"tasks": [
{
"label": "build-with-webpack-watch",
"type": "npm",
"script": "compile",
"problemMatcher": [
{
"label": "build-with-webpack-watch",
"type": "npm",
"script": "compile",
"problemMatcher": [
{
"owner": "typescript",
"source": "ts",
"applyTo": "closedDocuments",
"fileLocation": "absolute",
"severity": "error",
"pattern": [
{
"regexp": "\\[tsl\\] ERROR in (.*)?\\((\\d+),(\\d+)\\)",
"file": 1,
"line": 2,
"column": 3
},
{
"regexp": "\\s*TS\\d+:\\s*(.*)",
"message": 1
}
],
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "asset"
},
"endsPattern": {
"regexp": "webpack (.*?) compiled (.*?) ms"
}
}
}
],
"isBackground": true
},
{
"label": "Pretest",
"group": "build",
"isBackground": false,
"type": "shell",
"command": "yarn",
"args": [
"run",
"pretest"
],
"dependsOn": [
"Compile"
]
},
{
"label": "Compile",
"group": "build",
"isBackground": false,
"type": "shell",
"command": "yarn",
"args": [
"run",
"compile"
]
"owner": "typescript",
"source": "ts",
"applyTo": "closedDocuments",
"fileLocation": "absolute",
"severity": "error",
"pattern": [
{
"regexp": "\\[tsl\\] ERROR in (.*)?\\((\\d+),(\\d+)\\)",
"file": 1,
"line": 2,
"column": 3
},
{
"regexp": "\\s*TS\\d+:\\s*(.*)",
"message": 1
}
],
"background": {
"activeOnStart": true,
"beginsPattern": {
"regexp": "asset"
},
"endsPattern": {
"regexp": "webpack (.*?) compiled (.*?) ms"
}
}
}
]
}
],
"isBackground": true
},
{
"label": "Pretest",
"group": "build",
"isBackground": false,
"type": "shell",
"command": "yarn",
"args": ["run", "pretest"],
"dependsOn": ["Compile"]
},
{
"label": "Compile",
"group": "build",
"isBackground": false,
"type": "shell",
"command": "yarn",
"args": ["run", "compile"]
}
]
}

Просмотреть файл

@ -3,149 +3,158 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
const gulp = require('gulp');
const eslint = require('gulp-eslint');
const fs = require('fs');
const nls = require('vscode-nls-dev');
const path = require('path');
const minimist = require('minimist');
const es = require('event-stream');
const sourcemaps = require('gulp-sourcemaps');
const ts = require('gulp-typescript');
const typescript = require('typescript');
const tsProject = ts.createProject('./tsconfig.json', { typescript });
const filter = require('gulp-filter');
const vinyl = require('vinyl');
const jsonc = require('jsonc-parser');
"use strict";
const gulp = require("gulp");
const eslint = require("gulp-eslint");
const fs = require("fs");
const nls = require("vscode-nls-dev");
const path = require("path");
const minimist = require("minimist");
const es = require("event-stream");
const sourcemaps = require("gulp-sourcemaps");
const ts = require("gulp-typescript");
const typescript = require("typescript");
const tsProject = ts.createProject("./tsconfig.json", { typescript });
const filter = require("gulp-filter");
const vinyl = require("vinyl");
const jsonc = require("jsonc-parser");
// Patterns to find schema files
const jsonSchemaFilesPatterns = [
"*/*-schema.json"
];
const jsonSchemaFilesPatterns = ["*/*-schema.json"];
const languages = [
{ id: "zh-TW", folderName: "cht", transifexId: "zh-hant" },
{ id: "zh-CN", folderName: "chs", transifexId: "zh-hans" },
{ id: "fr", folderName: "fra" },
{ id: "de", folderName: "deu" },
{ id: "it", folderName: "ita" },
{ id: "es", folderName: "esn" },
{ id: "ja", folderName: "jpn" },
{ id: "ko", folderName: "kor" },
{ id: "ru", folderName: "rus" },
//{ id: "bg", folderName: "bul" }, // VS Code supports Bulgarian, but loc team is not currently generating it
//{ id: "hu", folderName: "hun" }, // VS Code supports Hungarian, but loc team is not currently generating it
{ id: "pt-br", folderName: "ptb", transifexId: "pt-BR" },
{ id: "tr", folderName: "trk" },
{ id: "cs", folderName: "csy" },
{ id: "pl", folderName: "plk" }
{ id: "zh-TW", folderName: "cht", transifexId: "zh-hant" },
{ id: "zh-CN", folderName: "chs", transifexId: "zh-hans" },
{ id: "fr", folderName: "fra" },
{ id: "de", folderName: "deu" },
{ id: "it", folderName: "ita" },
{ id: "es", folderName: "esn" },
{ id: "ja", folderName: "jpn" },
{ id: "ko", folderName: "kor" },
{ id: "ru", folderName: "rus" },
//{ id: "bg", folderName: "bul" }, // VS Code supports Bulgarian, but loc team is not currently generating it
//{ id: "hu", folderName: "hun" }, // VS Code supports Hungarian, but loc team is not currently generating it
{ id: "pt-br", folderName: "ptb", transifexId: "pt-BR" },
{ id: "tr", folderName: "trk" },
{ id: "cs", folderName: "csy" },
{ id: "pl", folderName: "plk" },
];
// ****************************
// Command: translations-export
// The following is used to export and XLF file containing english strings for translations.
// The result will be written to: ./vscode-extensions-localization-export/ms-vscode/
// ****************************
const translationProjectName = "vscode-extensions";
const translationExtensionName = "vscode-makefile-tools";
const translationProjectName = "vscode-extensions";
const translationExtensionName = "vscode-makefile-tools";
function removePathPrefix(path, prefix) {
if (!prefix) {
return path;
}
if (!path.startsWith(prefix)) {
return path;
}
if (path === prefix) {
return "";
}
let ch = prefix.charAt(prefix.length - 1);
if (ch === '/' || ch === '\\') {
return path.substr(prefix.length);
}
ch = path.charAt(prefix.length);
if (ch === '/' || ch === '\\') {
return path.substr(prefix.length + 1);
}
if (!prefix) {
return path;
}
if (!path.startsWith(prefix)) {
return path;
}
if (path === prefix) {
return "";
}
let ch = prefix.charAt(prefix.length - 1);
if (ch === "/" || ch === "\\") {
return path.substr(prefix.length);
}
ch = path.charAt(prefix.length);
if (ch === "/" || ch === "\\") {
return path.substr(prefix.length + 1);
}
return path;
}
// descriptionCallback(path, value, parent) is invoked for attribtues
const traverseJson = (jsonTree, descriptionCallback, prefixPath) => {
for (let fieldName in jsonTree) {
if (jsonTree[fieldName] !== null) {
if (typeof(jsonTree[fieldName]) == "string" && fieldName === "description") {
descriptionCallback(prefixPath, jsonTree[fieldName], jsonTree);
} else if (typeof(jsonTree[fieldName]) == "object") {
let path = prefixPath;
if (path !== "")
path = path + ".";
path = path + fieldName;
traverseJson(jsonTree[fieldName], descriptionCallback, path);
}
}
for (let fieldName in jsonTree) {
if (jsonTree[fieldName] !== null) {
if (
typeof jsonTree[fieldName] == "string" &&
fieldName === "description"
) {
descriptionCallback(prefixPath, jsonTree[fieldName], jsonTree);
} else if (typeof jsonTree[fieldName] == "object") {
let path = prefixPath;
if (path !== "") path = path + ".";
path = path + fieldName;
traverseJson(jsonTree[fieldName], descriptionCallback, path);
}
}
}
};
// Traverses schema json files looking for "description" fields to localized.
// The path to the "description" field is used to create a localization key.
const processJsonSchemaFiles = () => {
return es.through(function (file) {
let jsonTree = JSON.parse(file.contents.toString());
let localizationJsonContents = {};
let filePath = removePathPrefix(file.path, file.cwd);
filePath = filePath.replace(/\\/g, '/')
let localizationMetadataContents = {
messages: [],
keys: [],
filePath: filePath
};
let descriptionCallback = (path, value, parent) => {
let locId = filePath + "." + path;
localizationJsonContents[locId] = value;
localizationMetadataContents.keys.push(locId);
localizationMetadataContents.messages.push(value);
};
traverseJson(jsonTree, descriptionCallback, "");
this.queue(new vinyl({
path: path.join(file.path + '.nls.json'),
contents: Buffer.from(JSON.stringify(localizationJsonContents, null, '\t'), 'utf8')
}));
this.queue(new vinyl({
path: path.join(file.path + '.nls.metadata.json'),
contents: Buffer.from(JSON.stringify(localizationMetadataContents, null, '\t'), 'utf8')
}));
});
return es.through(function (file) {
let jsonTree = JSON.parse(file.contents.toString());
let localizationJsonContents = {};
let filePath = removePathPrefix(file.path, file.cwd);
filePath = filePath.replace(/\\/g, "/");
let localizationMetadataContents = {
messages: [],
keys: [],
filePath: filePath,
};
let descriptionCallback = (path, value, parent) => {
let locId = filePath + "." + path;
localizationJsonContents[locId] = value;
localizationMetadataContents.keys.push(locId);
localizationMetadataContents.messages.push(value);
};
traverseJson(jsonTree, descriptionCallback, "");
this.queue(
new vinyl({
path: path.join(file.path + ".nls.json"),
contents: Buffer.from(
JSON.stringify(localizationJsonContents, null, "\t"),
"utf8"
),
})
);
this.queue(
new vinyl({
path: path.join(file.path + ".nls.metadata.json"),
contents: Buffer.from(
JSON.stringify(localizationMetadataContents, null, "\t"),
"utf8"
),
})
);
});
};
gulp.task("translations-export", (done) => {
// Transpile the TS to JS, and let vscode-nls-dev scan the files for calls to localize.
let jsStream = tsProject
.src()
.pipe(sourcemaps.init())
.pipe(tsProject())
.js.pipe(nls.createMetaDataFiles());
// Transpile the TS to JS, and let vscode-nls-dev scan the files for calls to localize.
let jsStream = tsProject.src()
.pipe(sourcemaps.init())
.pipe(tsProject()).js
.pipe(nls.createMetaDataFiles());
// Scan schema files
let jsonSchemaStream = gulp
.src(jsonSchemaFilesPatterns)
.pipe(processJsonSchemaFiles());
// Scan schema files
let jsonSchemaStream = gulp.src(jsonSchemaFilesPatterns)
.pipe(processJsonSchemaFiles());
// Merge files from all source streams
es.merge(jsStream, jsonSchemaStream)
// Merge files from all source streams
es.merge(jsStream, jsonSchemaStream)
// Filter down to only the files we need
.pipe(filter(['**/*.nls.json', '**/*.nls.metadata.json']))
.pipe(filter(["**/*.nls.json", "**/*.nls.metadata.json"]))
// Consoldate them into nls.metadata.json, which the xlf is built from.
.pipe(nls.bundleMetaDataFiles('ms-vscode.makefile-tools', '.'))
.pipe(nls.bundleMetaDataFiles("ms-vscode.makefile-tools", "."))
// filter down to just the resulting metadata files
.pipe(filter(['**/nls.metadata.header.json', '**/nls.metadata.json']))
.pipe(filter(["**/nls.metadata.header.json", "**/nls.metadata.json"]))
// Add package.nls.json, used to localized package.json
.pipe(gulp.src(["package.nls.json"]))
@ -154,12 +163,13 @@ gulp.task("translations-export", (done) => {
// Does not re-queue any files to the stream. Outputs only the XLF file
.pipe(nls.createXlfFiles(translationProjectName, translationExtensionName))
.pipe(gulp.dest(path.join(`${translationProjectName}-localization-export`)))
.pipe(es.wait(() => {
.pipe(
es.wait(() => {
done();
}));
})
);
});
// ****************************
// Command: translations-import
// The following is used to import an XLF file containing all language strings.
@ -168,24 +178,34 @@ gulp.task("translations-export", (done) => {
// Imports translations from raw localized MLCP strings to VS Code .i18n.json files
gulp.task("translations-import", (done) => {
let options = minimist(process.argv.slice(2), {
string: "location",
default: {
location: "./vscode-translations-import"
}
});
es.merge(languages.map((language) => {
let id = language.transifexId || language.id;
return gulp.src(path.join(options.location, id, translationProjectName, `${translationExtensionName}.xlf`))
.pipe(nls.prepareJsonFiles())
.pipe(gulp.dest(path.join("./i18n", language.folderName)));
}))
.pipe(es.wait(() => {
done();
}));
let options = minimist(process.argv.slice(2), {
string: "location",
default: {
location: "./vscode-translations-import",
},
});
es.merge(
languages.map((language) => {
let id = language.transifexId || language.id;
return gulp
.src(
path.join(
options.location,
id,
translationProjectName,
`${translationExtensionName}.xlf`
)
)
.pipe(nls.prepareJsonFiles())
.pipe(gulp.dest(path.join("./i18n", language.folderName)));
})
).pipe(
es.wait(() => {
done();
})
);
});
// ****************************
// Command: translations-generate
// The following is used to import an i18n directory structure and generate files used at runtime.
@ -194,122 +214,156 @@ gulp.task("translations-import", (done) => {
// Generate package.nls.*.json files from: ./i18n/*/package.i18n.json
// Outputs to root path, as these nls files need to be along side package.json
const generatedAdditionalLocFiles = () => {
return gulp.src(['package.nls.json'])
.pipe(nls.createAdditionalLanguageFiles(languages, 'i18n'))
.pipe(gulp.dest('.'));
return gulp
.src(["package.nls.json"])
.pipe(nls.createAdditionalLanguageFiles(languages, "i18n"))
.pipe(gulp.dest("."));
};
// Generates ./dist/nls.bundle.<language_id>.json from files in ./i18n/** *//<src_path>/<filename>.i18n.json
// Localized strings are read from these files at runtime.
const generatedSrcLocBundle = () => {
// Transpile the TS to JS, and let vscode-nls-dev scan the files for calls to localize.
return tsProject.src()
.pipe(sourcemaps.init())
.pipe(tsProject()).js
.pipe(nls.rewriteLocalizeCalls())
.pipe(nls.createAdditionalLanguageFiles(languages, "i18n"))
.pipe(nls.bundleMetaDataFiles('ms-vscode.makefile-tools', 'dist'))
.pipe(nls.bundleLanguageFiles())
.pipe(filter(['**/nls.bundle.*.json', '**/nls.metadata.header.json', '**/nls.metadata.json']))
.pipe(gulp.dest('dist'));
// Transpile the TS to JS, and let vscode-nls-dev scan the files for calls to localize.
return tsProject
.src()
.pipe(sourcemaps.init())
.pipe(tsProject())
.js.pipe(nls.rewriteLocalizeCalls())
.pipe(nls.createAdditionalLanguageFiles(languages, "i18n"))
.pipe(nls.bundleMetaDataFiles("ms-vscode.makefile-tools", "dist"))
.pipe(nls.bundleLanguageFiles())
.pipe(
filter([
"**/nls.bundle.*.json",
"**/nls.metadata.header.json",
"**/nls.metadata.json",
])
)
.pipe(gulp.dest("dist"));
};
const generateLocalizedJsonSchemaFiles = () => {
return es.through(function (file) {
let jsonTree = JSON.parse(file.contents.toString());
languages.map((language) => {
let stringTable = {};
// Try to open i18n file for this file
let relativePath = removePathPrefix(file.path, file.cwd);
let locFile = path.join("./i18n", language.folderName, relativePath + ".i18n.json");
if (fs.existsSync(locFile)) {
stringTable = jsonc.parse(fs.readFileSync(locFile).toString());
}
// Entire file is scanned and modified, then serialized for that language.
// Even if no translations are available, we still write new files to dist/schema/...
let keyPrefix = relativePath + ".";
keyPrefix = keyPrefix.replace(/\\/g, "/");
let descriptionCallback = (path, value, parent) => {
if (stringTable[keyPrefix + path]) {
parent.description = stringTable[keyPrefix + path];
}
};
traverseJson(jsonTree, descriptionCallback, "");
let newContent = JSON.stringify(jsonTree, null, '\t');
this.queue(new vinyl({
path: path.join("schema", language.id, relativePath),
contents: Buffer.from(newContent, 'utf8')
}));
});
return es.through(function (file) {
let jsonTree = JSON.parse(file.contents.toString());
languages.map((language) => {
let stringTable = {};
// Try to open i18n file for this file
let relativePath = removePathPrefix(file.path, file.cwd);
let locFile = path.join(
"./i18n",
language.folderName,
relativePath + ".i18n.json"
);
if (fs.existsSync(locFile)) {
stringTable = jsonc.parse(fs.readFileSync(locFile).toString());
}
// Entire file is scanned and modified, then serialized for that language.
// Even if no translations are available, we still write new files to dist/schema/...
let keyPrefix = relativePath + ".";
keyPrefix = keyPrefix.replace(/\\/g, "/");
let descriptionCallback = (path, value, parent) => {
if (stringTable[keyPrefix + path]) {
parent.description = stringTable[keyPrefix + path];
}
};
traverseJson(jsonTree, descriptionCallback, "");
let newContent = JSON.stringify(jsonTree, null, "\t");
this.queue(
new vinyl({
path: path.join("schema", language.id, relativePath),
contents: Buffer.from(newContent, "utf8"),
})
);
});
});
};
// Generate localized versions of JSON schema files
// Check for cooresponding localized json file in i18n
// Generate new version of the JSON schema file in dist/schema/<language_id>/<path>
const generateJsonSchemaLoc = () => {
return gulp.src(jsonSchemaFilesPatterns)
.pipe(generateLocalizedJsonSchemaFiles())
.pipe(gulp.dest('dist'));
return gulp
.src(jsonSchemaFilesPatterns)
.pipe(generateLocalizedJsonSchemaFiles())
.pipe(gulp.dest("dist"));
};
const bundleScriptsPatterns = [
"assets/*"
];
const bundleScriptsPatterns = ["assets/*"];
const bundleScripts = () => {
return gulp.src(bundleScriptsPatterns).pipe(gulp.dest("assets"));
}
return gulp.src(bundleScriptsPatterns).pipe(gulp.dest("assets"));
};
gulp.task('bundle-assets', bundleScripts);
gulp.task('translations-generate', gulp.series(generatedSrcLocBundle, generatedAdditionalLocFiles, generateJsonSchemaLoc));
gulp.task("bundle-assets", bundleScripts);
gulp.task(
"translations-generate",
gulp.series(
generatedSrcLocBundle,
generatedAdditionalLocFiles,
generateJsonSchemaLoc
)
);
const allTypeScript = [
'src/**/*.ts',
'test/**/*.ts',
'!**/*.d.ts',
'!**/typings**'
"src/**/*.ts",
"test/**/*.ts",
"!**/*.d.ts",
"!**/typings**",
];
// Prints file path and line number in the same line. Easier to ctrl + left click in VS Code.
const lintReporter = results => {
const lintReporter = (results) => {
const messages = [];
let errorCount = 0;
let warningCount = 0;
let fixableErrorCount = 0;
let fixableWarningCount = 0;
results.forEach(result => {
results.forEach((result) => {
if (result.errorCount || result.warningCount) {
const filePath = result.filePath.replace(/\\/g, '/');
errorCount += result.errorCount;
warningCount += result.warningCount;
fixableErrorCount += result.fixableErrorCount;
fixableWarningCount += result.fixableWarningCount;
const filePath = result.filePath.replace(/\\/g, "/");
errorCount += result.errorCount;
warningCount += result.warningCount;
fixableErrorCount += result.fixableErrorCount;
fixableWarningCount += result.fixableWarningCount;
result.messages.forEach(message => {
messages.push(`[lint] ${filePath}:${message.line}:${message.column}: ${message.message} [${message.ruleId}]`);
});
result.messages.forEach((message) => {
messages.push(
`[lint] ${filePath}:${message.line}:${message.column}: ${message.message} [${message.ruleId}]`
);
});
messages.push('');
messages.push("");
}
});
if (errorCount || warningCount) {
messages.push('\x1b[31m' + ` ${errorCount + warningCount} Problems (${errorCount} Errors, ${warningCount} Warnings)` + '\x1b[39m');
messages.push('\x1b[31m' + ` ${fixableErrorCount} Errors, ${fixableWarningCount} Warnings potentially fixable with \`--fix\` option.` + '\x1b[39m');
messages.push('', '');
messages.push(
"\x1b[31m" +
` ${
errorCount + warningCount
} Problems (${errorCount} Errors, ${warningCount} Warnings)` +
"\x1b[39m"
);
messages.push(
"\x1b[31m" +
` ${fixableErrorCount} Errors, ${fixableWarningCount} Warnings potentially fixable with \`--fix\` option.` +
"\x1b[39m"
);
messages.push("", "");
}
return messages.join('\n');
return messages.join("\n");
};
gulp.task('lint', function () {
// Un-comment these parts for applying auto-fix.
return gulp.src(allTypeScript)
.pipe(eslint({ configFile: ".eslintrc.js" /*, fix: true */}))
.pipe(eslint.format(lintReporter, process.stderr))
//.pipe(gulp.dest(file => file.base))
.pipe(eslint.failAfterError());
gulp.task("lint", function () {
// Un-comment these parts for applying auto-fix.
return (
gulp
.src(allTypeScript)
.pipe(eslint({ configFile: ".eslintrc.js" /*, fix: true */ }))
.pipe(eslint.format(lintReporter, process.stderr))
//.pipe(gulp.dest(file => file.base))
.pipe(eslint.failAfterError())
);
});

Просмотреть файл

@ -4,27 +4,27 @@
trigger:
branches:
include:
- refs/heads/main
- refs/heads/main
resources:
repositories:
- repository: self
type: git
ref: refs/heads/main
- repository: MicroBuildTemplate
type: git
name: 1ESPipelineTemplates/MicroBuildTemplate
ref: refs/tags/release
- repository: self
type: git
ref: refs/heads/main
- repository: MicroBuildTemplate
type: git
name: 1ESPipelineTemplates/MicroBuildTemplate
ref: refs/tags/release
name: $(Date:yyyyMMdd).$(Rev:r)
variables:
- name: Codeql.Enabled
value: true
- name: Codeql.TSAEnabled
value: true
- name: TeamName
value: C++ Cross Platform and Cloud
- name: Codeql.Enabled
value: true
- name: Codeql.TSAEnabled
value: true
- name: TeamName
value: C++ Cross Platform and Cloud
extends:
template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate
@ -42,51 +42,51 @@ extends:
ignoreDirectories: node_modules,dist,i18n
alertWarningLevel: Medium
customBuildTags:
- ES365AIMigrationTooling
- ES365AIMigrationTooling
stages:
- stage: stage
jobs:
- job: Job_1
displayName: Agent job 1
steps:
- checkout: self
fetchTags: false
- task: NodeTool@0
displayName: Use Node 16.x
inputs:
versionSpec: 16.x
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@3
displayName: Use Yarn 1.x
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-task.Yarn@3
displayName: Yarn install
inputs:
arguments: install
- task: Npm@0
displayName: npm install vsce
inputs:
arguments: -g vsce
- task: CmdLine@2
displayName: Run VSCE to package vsix
inputs:
script: |-
echo Building VSIX
vsce package --yarn -o $(Build.StagingDirectory)\makefile-tools.vsix
- task: Npm@0
displayName: npm uninstall vsce
inputs:
command: uninstall
arguments: -g vsce
- task: DeleteFiles@1
displayName: Remove code that should not be scanned
inputs:
Contents: |-
node_modules
dist
i18n
- stage: stage
jobs:
- job: Job_1
displayName: Agent job 1
steps:
- checkout: self
fetchTags: false
- task: NodeTool@0
displayName: Use Node 16.x
inputs:
versionSpec: 16.x
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@3
displayName: Use Yarn 1.x
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-task.Yarn@3
displayName: Yarn install
inputs:
arguments: install
- task: Npm@0
displayName: npm install vsce
inputs:
arguments: -g vsce
- task: CmdLine@2
displayName: Run VSCE to package vsix
inputs:
script: |-
echo Building VSIX
vsce package --yarn -o $(Build.StagingDirectory)\makefile-tools.vsix
- task: Npm@0
displayName: npm uninstall vsce
inputs:
command: uninstall
arguments: -g vsce
- task: DeleteFiles@1
displayName: Remove code that should not be scanned
inputs:
Contents: |-
node_modules
dist
i18n

Просмотреть файл

@ -1,14 +1,14 @@
{
"Projects": [
"Projects": [
{
"LanguangeSet": "VS_Main_Languages",
"LocItems": [
{
"LanguangeSet": "VS_Main_Languages",
"LocItems": [
{
"SourceFile": "vscode-extensions-localization-export\\vscode-extensions\\vscode-makefile-tools.xlf",
"Languages": "cs;de;es;fr;it;ja;ko;pl;pt-BR;ru;tr;zh-Hans;zh-Hant",
"LclFile": "jobs\\loc\\LCL\\{Lang}\\vscode-makefile-tools.xlf.lcl"
}
]
"SourceFile": "vscode-extensions-localization-export\\vscode-extensions\\vscode-makefile-tools.xlf",
"Languages": "cs;de;es;fr;it;ja;ko;pl;pt-BR;ru;tr;zh-Hans;zh-Hant",
"LclFile": "jobs\\loc\\LCL\\{Lang}\\vscode-makefile-tools.xlf.lcl"
}
]
}
]
}
]
}

Просмотреть файл

@ -4,26 +4,26 @@
# ==================================================================================
resources:
repositories:
- repository: self
clean: true
- repository: MicroBuildTemplate
type: git
name: 1ESPipelineTemplates/MicroBuildTemplate
ref: refs/tags/release
- repository: self
clean: true
- repository: MicroBuildTemplate
type: git
name: 1ESPipelineTemplates/MicroBuildTemplate
ref: refs/tags/release
trigger: none
pr: none
schedules:
- cron: "0 7 * * *"
displayName: Daily 7 AM
branches:
include:
- main
always: true
- cron: "0 7 * * *"
displayName: Daily 7 AM
branches:
include:
- main
always: true
variables:
- name: TeamName
value: C++ Cross Platform and Cloud
- name: TeamName
value: C++ Cross Platform and Cloud
extends:
template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate
@ -33,50 +33,50 @@ extends:
image: AzurePipelinesWindows2022compliantGPT
os: windows
sdl:
sourceAnalysisPool:
sourceAnalysisPool:
name: AzurePipelines-EO
image: AzurePipelinesWindows2022compliantGPT
os: windows
customBuildTags:
- ES365AIMigrationTooling
- ES365AIMigrationTooling
stages:
- stage: stage
jobs:
- job: job
templateContext:
outputs:
- output: pipelineArtifact
targetPath: '$(Build.ArtifactStagingDirectory)'
artifactName: 'drop'
publishLocation: 'Container'
steps:
- task: NodeTool@0
inputs:
versionSpec: '16.x'
displayName: 'Install Node.js'
- task: CmdLine@2
inputs:
script: 'yarn install'
- task: CmdLine@2
inputs:
script: 'yarn run translations-export'
- task: OneLocBuild@2
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
inputs:
locProj: 'jobs/loc/LocProject.json'
outDir: '$(Build.ArtifactStagingDirectory)'
isCreatePrSelected: false
prSourceBranchPrefix: 'locfiles'
packageSourceAuth: 'patAuth'
patVariable: '$(OneLocBuildPat)'
LclSource: lclFilesfromPackage
LclPackageId: 'LCL-JUNO-PROD-VMAKEFILE'
lsBuildXLocPackageVersion: '7.0.30510'
- task: CmdLine@2
inputs:
script: 'node ./translations_auto_pr.js microsoft vscode-makefile-tools csigs $(csigsPat) csigs csigs@users.noreply.github.com "$(Build.ArtifactStagingDirectory)/loc" vscode-extensions-localization-export/vscode-extensions'
- stage: stage
jobs:
- job: job
templateContext:
outputs:
- output: pipelineArtifact
targetPath: "$(Build.ArtifactStagingDirectory)"
artifactName: "drop"
publishLocation: "Container"
steps:
- task: NodeTool@0
inputs:
versionSpec: "16.x"
displayName: "Install Node.js"
- task: CmdLine@2
inputs:
script: "yarn install"
- task: CmdLine@2
inputs:
script: "yarn run translations-export"
- task: OneLocBuild@2
env:
SYSTEM_ACCESSTOKEN: $(System.AccessToken)
inputs:
locProj: "jobs/loc/LocProject.json"
outDir: "$(Build.ArtifactStagingDirectory)"
isCreatePrSelected: false
prSourceBranchPrefix: "locfiles"
packageSourceAuth: "patAuth"
patVariable: "$(OneLocBuildPat)"
LclSource: lclFilesfromPackage
LclPackageId: "LCL-JUNO-PROD-VMAKEFILE"
lsBuildXLocPackageVersion: "7.0.30510"
- task: CmdLine@2
inputs:
script: 'node ./translations_auto_pr.js microsoft vscode-makefile-tools csigs $(csigsPat) csigs csigs@users.noreply.github.com "$(Build.ArtifactStagingDirectory)/loc" vscode-extensions-localization-export/vscode-extensions'

Просмотреть файл

@ -4,32 +4,32 @@
trigger: none
schedules:
- cron: 0 4 * * 1,2,3,4,5
branches:
include:
- refs/heads/main
- cron: 0 4 * * 1,2,3,4,5
branches:
include:
- refs/heads/main
resources:
repositories:
- repository: self
type: git
ref: refs/heads/main
- repository: MicroBuildTemplate
type: git
name: 1ESPipelineTemplates/MicroBuildTemplate
ref: refs/tags/release
- repository: self
type: git
ref: refs/heads/main
- repository: MicroBuildTemplate
type: git
name: 1ESPipelineTemplates/MicroBuildTemplate
ref: refs/tags/release
name: $(Date:yyyyMMdd).$(Rev:r)
variables:
- name: IsPreRelease
value: 1
- name: ReleaseVersion
value: unset
- name: TeamName
value: C++ Cross Platform and Cloud
- name: SignType
value: real
- name: IsPreRelease
value: 1
- name: ReleaseVersion
value: unset
- name: TeamName
value: C++ Cross Platform and Cloud
- name: SignType
value: real
extends:
template: azure-pipelines/MicroBuild.1ES.Official.yml@MicroBuildTemplate
@ -40,22 +40,22 @@ extends:
sourceAnalysisPool:
name: VSEngSS-MicroBuild2022-1ES
customBuildTags:
- ES365AIMigrationTooling
- ES365AIMigrationTooling
stages:
- stage: stage
jobs:
- job: Job_1
displayName: Build pre-release
templateContext:
outputs:
- output: pipelineArtifact
displayName: 'Publish VSIX'
targetPath: $(Build.ArtifactStagingDirectory)/vsix
artifactName: vsix
sbomBuildDropPath: $(Build.ArtifactStagingDirectory)
# No need for SBOM, it's now located in the vsix artifact
steps:
- checkout: self
clean: true
fetchTags: false
- template: /jobs/shared/build.yml@self
- stage: stage
jobs:
- job: Job_1
displayName: Build pre-release
templateContext:
outputs:
- output: pipelineArtifact
displayName: "Publish VSIX"
targetPath: $(Build.ArtifactStagingDirectory)/vsix
artifactName: vsix
sbomBuildDropPath: $(Build.ArtifactStagingDirectory)
# No need for SBOM, it's now located in the vsix artifact
steps:
- checkout: self
clean: true
fetchTags: false
- template: /jobs/shared/build.yml@self

Просмотреть файл

@ -2,32 +2,32 @@
# Licensed under the MIT License.
parameters:
- name: SignTypeOverride
displayName: Signing Type Override
type: string
default: default
values:
- default
- test
- real
- name: SignTypeOverride
displayName: Signing Type Override
type: string
default: default
values:
- default
- test
- real
trigger: none
resources:
repositories:
- repository: self
type: git
ref: refs/heads/main
- repository: MicroBuildTemplate
type: git
name: 1ESPipelineTemplates/MicroBuildTemplate
ref: refs/tags/release
- repository: self
type: git
ref: refs/heads/main
- repository: MicroBuildTemplate
type: git
name: 1ESPipelineTemplates/MicroBuildTemplate
ref: refs/tags/release
name: $(Date:yyyyMMdd).$(Rev:r)
variables:
IsPreRelease: 0
# ReleaseVersion is set in the versions tab so it can be edited.
# ReleaseVersion is set in the versions tab so it can be edited.
TeamName: C++ Cross Platform and Cloud
# If the user didn't override the signing type, then only real-sign on main.
${{ if ne(parameters.SignTypeOverride, 'default') }}:
@ -46,32 +46,32 @@ extends:
sourceAnalysisPool:
name: VSEngSS-MicroBuild2022-1ES
customBuildTags:
- ES365AIMigrationTooling
- ES365AIMigrationTooling
stages:
- stage: stage
jobs:
- job: Job_1
displayName: Build release
templateContext:
outputs:
- output: pipelineArtifact
displayName: 'Publish VSIX'
targetPath: $(Build.ArtifactStagingDirectory)/vsix
artifactName: vsix
sbomBuildDropPath: $(Build.ArtifactStagingDirectory)
# No need for the SBOM, it's now located in the vsix artifact
steps:
- checkout: self
clean: true
fetchTags: false
- task: CmdLine@2
displayName: Check ReleaseVersion
inputs:
script: |-
@echo off
if "$(ReleaseVersion)"=="unset" (
echo ^"ReleaseVersion^" was not set
exit /B 1
)
exit /b 0
- template: /jobs/shared/build.yml@self
- stage: stage
jobs:
- job: Job_1
displayName: Build release
templateContext:
outputs:
- output: pipelineArtifact
displayName: "Publish VSIX"
targetPath: $(Build.ArtifactStagingDirectory)/vsix
artifactName: vsix
sbomBuildDropPath: $(Build.ArtifactStagingDirectory)
# No need for the SBOM, it's now located in the vsix artifact
steps:
- checkout: self
clean: true
fetchTags: false
- task: CmdLine@2
displayName: Check ReleaseVersion
inputs:
script: |-
@echo off
if "$(ReleaseVersion)"=="unset" (
echo ^"ReleaseVersion^" was not set
exit /B 1
)
exit /b 0
- template: /jobs/shared/build.yml@self

Просмотреть файл

@ -2,137 +2,137 @@
# Licensed under the MIT License.
parameters:
- name: IsPreRelease
type: string
default: $(IsPreRelease)
- name: ReleaseVersion
type: string
default: $(ReleaseVersion)
- name: IsPreRelease
type: string
default: $(IsPreRelease)
- name: ReleaseVersion
type: string
default: $(ReleaseVersion)
steps:
- task: MicroBuildSigningPlugin@3
displayName: Install MicroBuild Signing
inputs:
signType: $(SignType)
zipSources: false
- task: MicroBuildSigningPlugin@3
displayName: Install MicroBuild Signing
inputs:
signType: $(SignType)
zipSources: false
- task: NodeTool@0
displayName: Use Node 16.x
inputs:
versionSpec: 16.x
- task: NodeTool@0
displayName: Use Node 16.x
inputs:
versionSpec: 16.x
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@3
displayName: Use Yarn 1.x
- task: geeklearningio.gl-vsts-tasks-yarn.yarn-installer-task.YarnInstaller@3
displayName: Use Yarn 1.x
- task: CmdLine@2
displayName: IF EXIST %SYSTEMDRIVE%\Users\%USERNAME%\.npmrc del %SYSTEMDRIVE%\Users\%USERNAME%\.npmrc
inputs:
script: IF EXIST %SYSTEMDRIVE%\Users\%USERNAME%\.npmrc del %SYSTEMDRIVE%\Users\%USERNAME%\.npmrc
- task: CmdLine@2
displayName: IF EXIST %SYSTEMDRIVE%\Users\%USERNAME%\.npmrc del %SYSTEMDRIVE%\Users\%USERNAME%\.npmrc
inputs:
script: IF EXIST %SYSTEMDRIVE%\Users\%USERNAME%\.npmrc del %SYSTEMDRIVE%\Users\%USERNAME%\.npmrc
- task: Npm@0
displayName: npm install VSCE
inputs:
arguments: -g vsce
- task: Npm@0
displayName: npm install VSCE
inputs:
arguments: -g vsce
- task: PowerShell@2
displayName: Update ReleaseVersion for pre-release builds
condition: eq(variables.IsPreRelease, '1')
inputs:
targetType: inline
script: |
#
# Query the Marketplace for the latest version of Makefile Tools
# https://github.com/microsoft/vscode/blob/main/src/vs/platform/extensionManagement/common/extensionGalleryService.ts
#
$uri = 'https://marketplace.visualstudio.com/_apis/public/gallery/extensionquery'
$contentType = 'application/json'
$headers = @{
"Accept" = "application/json; api-version=3.0-preview"
}
$data = '{"filters": [{"criteria": [{"filterType": 7, "value": "ms-vscode.makefile-tools"}]}], "flags": 529}'
$response = Invoke-WebRequest -Method 'POST' -Uri $uri -UseBasicParsing -ContentType $contentType -Headers $headers -Body $data
$newVersion = ''
if ($response.StatusCode.Equals(200)) {
$result = $response.Content | ConvertFrom-Json
# Check the $result.results[0].extensions.versions.properties for the 'Microsoft.VisualStudio.Code.PreRelease' key to make sure it's true,
# if not, we need to bump the .Minor version and reset .Build to 0
$index = $result.results[0].extensions.versions.properties.key.IndexOf("Microsoft.VisualStudio.Code.PreRelease")
$isPreRelease = "false"
if ($index -ge 0) {
$isPreRelease = $result.results[0].extensions.versions.properties.value[$index]
}
$v = [System.Version]::Parse($result.results[0].extensions.versions.version)
if ($isPreRelease.Equals('true')) {
$newVersion = [System.Version]::new($v.Major, $v.Minor, $v.Build + 1).ToString()
} else {
$newVersion = [System.Version]::new($v.Major, $v.Minor + 1, 0).ToString()
}
}
Write-Host "New version is: $newVersion"
Write-Host "##vso[task.setvariable variable=ReleaseVersion]$newVersion"
ignoreLASTEXITCODE: true
- task: PowerShell@2
displayName: Update ReleaseVersion for pre-release builds
condition: eq(variables.IsPreRelease, '1')
inputs:
targetType: inline
script: |
#
# Query the Marketplace for the latest version of Makefile Tools
# https://github.com/microsoft/vscode/blob/main/src/vs/platform/extensionManagement/common/extensionGalleryService.ts
#
$uri = 'https://marketplace.visualstudio.com/_apis/public/gallery/extensionquery'
$contentType = 'application/json'
$headers = @{
"Accept" = "application/json; api-version=3.0-preview"
}
$data = '{"filters": [{"criteria": [{"filterType": 7, "value": "ms-vscode.makefile-tools"}]}], "flags": 529}'
$response = Invoke-WebRequest -Method 'POST' -Uri $uri -UseBasicParsing -ContentType $contentType -Headers $headers -Body $data
$newVersion = ''
if ($response.StatusCode.Equals(200)) {
$result = $response.Content | ConvertFrom-Json
# Check the $result.results[0].extensions.versions.properties for the 'Microsoft.VisualStudio.Code.PreRelease' key to make sure it's true,
# if not, we need to bump the .Minor version and reset .Build to 0
$index = $result.results[0].extensions.versions.properties.key.IndexOf("Microsoft.VisualStudio.Code.PreRelease")
$isPreRelease = "false"
if ($index -ge 0) {
$isPreRelease = $result.results[0].extensions.versions.properties.value[$index]
}
$v = [System.Version]::Parse($result.results[0].extensions.versions.version)
if ($isPreRelease.Equals('true')) {
$newVersion = [System.Version]::new($v.Major, $v.Minor, $v.Build + 1).ToString()
} else {
$newVersion = [System.Version]::new($v.Major, $v.Minor + 1, 0).ToString()
}
}
Write-Host "New version is: $newVersion"
Write-Host "##vso[task.setvariable variable=ReleaseVersion]$newVersion"
ignoreLASTEXITCODE: true
- task: PowerShell@2
displayName: Set build name
inputs:
targetType: inline
script: |-
$str = Get-Date -Format "yyMMdd-HHmm"
Write-Host "##vso[build.updatebuildnumber]${{parameters.ReleaseVersion}} - $str"
- task: PowerShell@2
displayName: Set build name
inputs:
targetType: inline
script: |-
$str = Get-Date -Format "yyMMdd-HHmm"
Write-Host "##vso[build.updatebuildnumber]${{parameters.ReleaseVersion}} - $str"
- task: PowerShell@2
displayName: Update version in package.json
inputs:
targetType: inline
script: |-
$JsonData = Get-Content -Path .\package.json -raw | ConvertFrom-Json
$oldVersion = $JsonData.version
$newVersion = "${{parameters.ReleaseVersion}}"
$JsonData.version = $newVersion
$JsonData | ConvertTo-Json -Depth 20 | Set-Content -Path .\package.json
Write-Host "old version was: $oldVersion"
Write-Host "new version is: $newVersion"
Get-Content -Path .\package.json
- task: PowerShell@2
displayName: Update version in package.json
inputs:
targetType: inline
script: |-
$JsonData = Get-Content -Path .\package.json -raw | ConvertFrom-Json
$oldVersion = $JsonData.version
$newVersion = "${{parameters.ReleaseVersion}}"
$JsonData.version = $newVersion
$JsonData | ConvertTo-Json -Depth 20 | Set-Content -Path .\package.json
Write-Host "old version was: $oldVersion"
Write-Host "new version is: $newVersion"
Get-Content -Path .\package.json
- task: CmdLine@2
displayName: Create release.flag/insiders.flag
inputs:
script: |
if "${{parameters.IsPreRelease}}"=="1" (type nul > "insiders.flag") else (type nul > "release.flag")
- task: CmdLine@2
displayName: Create release.flag/insiders.flag
inputs:
script: |
if "${{parameters.IsPreRelease}}"=="1" (type nul > "insiders.flag") else (type nul > "release.flag")
- template: /jobs/shared/install-nuget.yml@self
- template: /jobs/shared/install-nuget.yml@self
- script: nuget restore $(Build.SourcesDirectory)\build\SignFiles.proj -PackagesDirectory $(Build.SourcesDirectory)\build\packages
displayName: Restore MicroBuild Core
- script: nuget restore $(Build.SourcesDirectory)\build\SignFiles.proj -PackagesDirectory $(Build.SourcesDirectory)\build\packages
displayName: Restore MicroBuild Core
- task: CmdLine@2
displayName: Build files
inputs:
script: |
npm run vscode:prepublish
- task: CmdLine@2
displayName: Build files
inputs:
script: |
npm run vscode:prepublish
- task: MSBuild@1
displayName: Sign files
inputs:
solution: $(Build.SourcesDirectory)\build\SignFiles.proj
msbuildArguments: /p:SignType=$(SignType)
- task: MSBuild@1
displayName: Sign files
inputs:
solution: $(Build.SourcesDirectory)\build\SignFiles.proj
msbuildArguments: /p:SignType=$(SignType)
- task: CmdLine@2
displayName: vsce package
inputs:
script: |
mkdir $(Build.ArtifactStagingDirectory)\vsix
if "${{parameters.IsPreRelease}}"=="1" (vsce package --yarn -o $(Build.ArtifactStagingDirectory)\vsix\makefile-tools.vsix --pre-release) else (vsce package --yarn -o $(Build.ArtifactStagingDirectory)\vsix\makefile-tools.vsix)
- task: CmdLine@2
displayName: vsce package
inputs:
script: |
mkdir $(Build.ArtifactStagingDirectory)\vsix
if "${{parameters.IsPreRelease}}"=="1" (vsce package --yarn -o $(Build.ArtifactStagingDirectory)\vsix\makefile-tools.vsix --pre-release) else (vsce package --yarn -o $(Build.ArtifactStagingDirectory)\vsix\makefile-tools.vsix)
- task: MSBuild@1
displayName: Sign VSIX
inputs:
solution: $(Build.SourcesDirectory)\build\SignVsix.proj
msbuildArguments: /p:SignType=$(SignType)
- task: MSBuild@1
displayName: Sign VSIX
inputs:
solution: $(Build.SourcesDirectory)\build\SignVsix.proj
msbuildArguments: /p:SignType=$(SignType)
- task: CmdLine@2
displayName: Write the version to version.txt
inputs:
script: |
echo ${{parameters.ReleaseVersion}} >> version.txt
move version.txt $(Build.ArtifactStagingDirectory)\vsix\version.txt
- task: CmdLine@2
displayName: Write the version to version.txt
inputs:
script: |
echo ${{parameters.ReleaseVersion}} >> version.txt
move version.txt $(Build.ArtifactStagingDirectory)\vsix\version.txt

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,72 +1,72 @@
{
"makefile-tools.command.makefile.buildTarget.title": "Makefile: Build the current target",
"makefile-tools.command.makefile.buildCleanTarget.title": "Makefile: Build clean the current target",
"makefile-tools.command.makefile.buildAll.title": "Makefile: Build the target ALL",
"makefile-tools.command.makefile.buildCleanAll.title": "Makefile: Build clean the target ALL",
"makefile-tools.command.makefile.launchDebug.title": "Makefile: Debug the selected binary target",
"makefile-tools.command.makefile.launchRun.title": "Makefile: Run the selected binary target in the terminal",
"makefile-tools.command.makefile.setBuildConfiguration.title": "Makefile: Set the current build configuration",
"makefile-tools.command.makefile.setBuildTarget.title": "Makefile: Set the target to be built by make",
"makefile-tools.command.makefile.setLaunchConfiguration.title": "Makefile: Set the make launch configuration",
"makefile-tools.command.makefile.openMakefilePathSetting.title": "Makefile: Open Makefile Path Setting",
"makefile-tools.command.makefile.openMakePathSetting.title": "Makefile: Open Make Path Setting",
"makefile-tools.command.makefile.openBuildLogSetting.title": "Makefile: Open Build Log Setting",
"makefile-tools.command.makefile.openBuildLogFile.title": "Makefile: Open Build Log File",
"makefile-tools.command.makefile.openMakefileFile.title": "Makefile: Open Makefile File",
"workbench.action.openWorkspaceSettings.title": "Preferences: Open Workspace Settings",
"makefile-tools.command.makefile.configure.title": "Makefile: Configure",
"makefile-tools.command.makefile.cleanConfigure.title": "Makefile: Clean Configure",
"makefile-tools.command.makefile.preConfigure.title": "Makefile: Pre-Configure",
"makefile-tools.command.makefile.postConfigure.title": "Makefile: Post-Configure",
"makefile-tools.command.makefile.resetState.title": "Makefile: Reset the Makefile Tools Extension workspace state (For troubleshooting)",
"makefile-tools.configuration.views.makefile.outline.description": "Project Outline",
"makefile-tools.configuration.makefile.makePath.description": "The path to the make tool",
"makefile-tools.configuration.makefile.configurations.description": "The user defined makefile configurations",
"makefile-tools.configuration.makefile.configurations.name.description": "The name of the makefile configuration",
"makefile-tools.configuration.makefile.configurations.makefilePath.description": "File path to the makefile",
"makefile-tools.configuration.makefile.configurations.makePath.description": "File path to the make command",
"makefile-tools.configuration.makefile.configurations.makeDirectory.description": "Folder path passed to make via the -C switch",
"makefile-tools.configuration.makefile.configurations.makeArgs.description": "Arguments to pass to the make command",
"makefile-tools.configuration.makefile.configurations.problemMatchers.description": "Problem matcher names to use when building the current target",
"makefile-tools.configuration.makefile.configurations.buildLog.description": "File path to the build log used instead of dry-run output",
"makefile-tools.configuration.makefile.defaultLaunchConfiguration.description": "Various global debugger settings",
"makefile-tools.configuration.makefile.defaultLaunchConfiguration.MIMode.description": "The non VS debugger type: gdb or lldb",
"makefile-tools.configuration.makefile.defaultLaunchConfiguration.miDebuggerPath.description": "Path to the non VS debugger (gdb or lldb)",
"makefile-tools.configuration.makefile.defaultLaunchConfiguration.stopAtEntry.description": "Stop at the entry point of the target",
"makefile-tools.configuration.makefile.defaultLaunchConfiguration.symbolSearchPath.description": "The path to the symbols",
"makefile-tools.configuration.makefile.launchConfigurations.description": "The user defined launch (debug/run) configurations",
"makefile-tools.configuration.makefile.launchConfigurations.binaryPath.description": "The full path to the binary to run or debug",
"makefile-tools.configuration.makefile.launchConfigurations.binaryArgs.description": "Arguments to pass to program command line",
"makefile-tools.configuration.makefile.launchConfigurations.cwd.description": "Set the working directory for the program",
"makefile-tools.configuration.makefile.launchConfigurations.MIMode.description": "The non VS debugger type: gdb or lldb",
"makefile-tools.configuration.makefile.launchConfigurations.miDebuggerPath.description": "Path to the non VS debugger (gdb or lldb)",
"makefile-tools.configuration.makefile.launchConfigurations.stopAtEntry.description": "Stop at the entry point of the target",
"makefile-tools.configuration.makefile.launchConfigurations.symbolSearchPath.description": "The path to the symbols",
"makefile-tools.configuration.makefile.loggingLevel.description": "The logging level for the makefile tools extension",
"makefile-tools.configuration.makefile.makeDirectory.description": "The folder path to be passed to make via the switch -C",
"makefile-tools.configuration.makefile.makefilePath.description": "The path to the makefile of the project",
"makefile-tools.configuration.makefile.buildLog.description": "The path to the build log that is read to bypass a dry-run",
"makefile-tools.configuration.makefile.extensionOutputFolder.description": "The path to various output files produced by the extension. Defaults to the VS Code workspace storage location.",
"makefile-tools.configuration.makefile.extensionLog.description": "The path to an output file storing all content from the Makefile output channel. Defaults to the value of the 'makefile.extensionOutputFolder' setting.",
"makefile-tools.configuration.makefile.configurationCachePath.description": "The path to a cache file storing the output of the last dry-run make command. When unset, a file named 'configurationCache.log' is stored at the path specified by the 'makefile.extensionOutputFolder' setting.",
"makefile-tools.configuration.makefile.dryrunSwitches.description": "Arguments to pass to the dry-run make invocation",
"makefile-tools.configuration.makefile.additionalCompilerNames.description": "Names of compiler tools to be added to the extension known list",
"makefile-tools.configuration.makefile.excludeCompilerNames.description": "Names of compiler tools to be excluded from the extension known list",
"makefile-tools.configuration.makefile.configureOnOpen.description": "Automatically configure Makefile project directories when they are opened",
"makefile-tools.configuration.makefile.configureOnEdit.description": "Automatically configure Makefile project directories when any relevant makefiles and/or settings are changed",
"makefile-tools.configuration.makefile.configureAfterCommand.description": "Automatically configure Makefile project directories after relevant operations, like change build configuration or makefile target",
"makefile-tools.configuration.makefile.preConfigureScript.description": "The path to the script that needs to be run at least once before configure",
"makefile-tools.configuration.makefile.preConfigureArgs.description": "Arguments to pass to the pre-configure script",
"makefile-tools.configuration.makefile.postConfigureScript.description": "The path to the script that needs to be run at least once after configure",
"makefile-tools.configuration.makefile.postConfigureArgs.description": "Arguments to pass to the post-configure script",
"makefile-tools.configuration.makefile.alwaysPreConfigure.description": "Always run the pre-configure script before configure",
"makefile-tools.configuration.makefile.alwaysPostConfigure.description": "Always run the post-configure script after configure",
"makefile-tools.configuration.makefile.ignoreDirectoryCommands.description": "Don't analyze directory changing commands like cd, push, pop.",
"makefile-tools.configuration.makefile.phonyOnlyTargets.description": "Display only the phony targets",
"makefile-tools.configuration.makefile.saveBeforeBuildOrConfigure.description": "Save opened files before building or configuring",
"makefile-tools.configuration.makefile.buildBeforeLaunch.description": "Build the current target before launch (debug/run)",
"makefile-tools.configuration.makefile.clearOutputBeforeBuild.description": "Clear the output channel at the beginning of a build",
"makefile-tools.configuration.makefile.compileCommandsPath.description": "The path to the compilation database file",
"makefile-tools.configuration.makefile.panel.visibility.debug.description": "Enable debugging locally (in this host) images built by this extension",
"makefile-tools.configuration.makefile.panel.visibility.run.description": "Enable running locally (in this host) images built by this extension"
"makefile-tools.command.makefile.buildTarget.title": "Makefile: Build the current target",
"makefile-tools.command.makefile.buildCleanTarget.title": "Makefile: Build clean the current target",
"makefile-tools.command.makefile.buildAll.title": "Makefile: Build the target ALL",
"makefile-tools.command.makefile.buildCleanAll.title": "Makefile: Build clean the target ALL",
"makefile-tools.command.makefile.launchDebug.title": "Makefile: Debug the selected binary target",
"makefile-tools.command.makefile.launchRun.title": "Makefile: Run the selected binary target in the terminal",
"makefile-tools.command.makefile.setBuildConfiguration.title": "Makefile: Set the current build configuration",
"makefile-tools.command.makefile.setBuildTarget.title": "Makefile: Set the target to be built by make",
"makefile-tools.command.makefile.setLaunchConfiguration.title": "Makefile: Set the make launch configuration",
"makefile-tools.command.makefile.openMakefilePathSetting.title": "Makefile: Open Makefile Path Setting",
"makefile-tools.command.makefile.openMakePathSetting.title": "Makefile: Open Make Path Setting",
"makefile-tools.command.makefile.openBuildLogSetting.title": "Makefile: Open Build Log Setting",
"makefile-tools.command.makefile.openBuildLogFile.title": "Makefile: Open Build Log File",
"makefile-tools.command.makefile.openMakefileFile.title": "Makefile: Open Makefile File",
"workbench.action.openWorkspaceSettings.title": "Preferences: Open Workspace Settings",
"makefile-tools.command.makefile.configure.title": "Makefile: Configure",
"makefile-tools.command.makefile.cleanConfigure.title": "Makefile: Clean Configure",
"makefile-tools.command.makefile.preConfigure.title": "Makefile: Pre-Configure",
"makefile-tools.command.makefile.postConfigure.title": "Makefile: Post-Configure",
"makefile-tools.command.makefile.resetState.title": "Makefile: Reset the Makefile Tools Extension workspace state (For troubleshooting)",
"makefile-tools.configuration.views.makefile.outline.description": "Project Outline",
"makefile-tools.configuration.makefile.makePath.description": "The path to the make tool",
"makefile-tools.configuration.makefile.configurations.description": "The user defined makefile configurations",
"makefile-tools.configuration.makefile.configurations.name.description": "The name of the makefile configuration",
"makefile-tools.configuration.makefile.configurations.makefilePath.description": "File path to the makefile",
"makefile-tools.configuration.makefile.configurations.makePath.description": "File path to the make command",
"makefile-tools.configuration.makefile.configurations.makeDirectory.description": "Folder path passed to make via the -C switch",
"makefile-tools.configuration.makefile.configurations.makeArgs.description": "Arguments to pass to the make command",
"makefile-tools.configuration.makefile.configurations.problemMatchers.description": "Problem matcher names to use when building the current target",
"makefile-tools.configuration.makefile.configurations.buildLog.description": "File path to the build log used instead of dry-run output",
"makefile-tools.configuration.makefile.defaultLaunchConfiguration.description": "Various global debugger settings",
"makefile-tools.configuration.makefile.defaultLaunchConfiguration.MIMode.description": "The non VS debugger type: gdb or lldb",
"makefile-tools.configuration.makefile.defaultLaunchConfiguration.miDebuggerPath.description": "Path to the non VS debugger (gdb or lldb)",
"makefile-tools.configuration.makefile.defaultLaunchConfiguration.stopAtEntry.description": "Stop at the entry point of the target",
"makefile-tools.configuration.makefile.defaultLaunchConfiguration.symbolSearchPath.description": "The path to the symbols",
"makefile-tools.configuration.makefile.launchConfigurations.description": "The user defined launch (debug/run) configurations",
"makefile-tools.configuration.makefile.launchConfigurations.binaryPath.description": "The full path to the binary to run or debug",
"makefile-tools.configuration.makefile.launchConfigurations.binaryArgs.description": "Arguments to pass to program command line",
"makefile-tools.configuration.makefile.launchConfigurations.cwd.description": "Set the working directory for the program",
"makefile-tools.configuration.makefile.launchConfigurations.MIMode.description": "The non VS debugger type: gdb or lldb",
"makefile-tools.configuration.makefile.launchConfigurations.miDebuggerPath.description": "Path to the non VS debugger (gdb or lldb)",
"makefile-tools.configuration.makefile.launchConfigurations.stopAtEntry.description": "Stop at the entry point of the target",
"makefile-tools.configuration.makefile.launchConfigurations.symbolSearchPath.description": "The path to the symbols",
"makefile-tools.configuration.makefile.loggingLevel.description": "The logging level for the makefile tools extension",
"makefile-tools.configuration.makefile.makeDirectory.description": "The folder path to be passed to make via the switch -C",
"makefile-tools.configuration.makefile.makefilePath.description": "The path to the makefile of the project",
"makefile-tools.configuration.makefile.buildLog.description": "The path to the build log that is read to bypass a dry-run",
"makefile-tools.configuration.makefile.extensionOutputFolder.description": "The path to various output files produced by the extension. Defaults to the VS Code workspace storage location.",
"makefile-tools.configuration.makefile.extensionLog.description": "The path to an output file storing all content from the Makefile output channel. Defaults to the value of the 'makefile.extensionOutputFolder' setting.",
"makefile-tools.configuration.makefile.configurationCachePath.description": "The path to a cache file storing the output of the last dry-run make command. When unset, a file named 'configurationCache.log' is stored at the path specified by the 'makefile.extensionOutputFolder' setting.",
"makefile-tools.configuration.makefile.dryrunSwitches.description": "Arguments to pass to the dry-run make invocation",
"makefile-tools.configuration.makefile.additionalCompilerNames.description": "Names of compiler tools to be added to the extension known list",
"makefile-tools.configuration.makefile.excludeCompilerNames.description": "Names of compiler tools to be excluded from the extension known list",
"makefile-tools.configuration.makefile.configureOnOpen.description": "Automatically configure Makefile project directories when they are opened",
"makefile-tools.configuration.makefile.configureOnEdit.description": "Automatically configure Makefile project directories when any relevant makefiles and/or settings are changed",
"makefile-tools.configuration.makefile.configureAfterCommand.description": "Automatically configure Makefile project directories after relevant operations, like change build configuration or makefile target",
"makefile-tools.configuration.makefile.preConfigureScript.description": "The path to the script that needs to be run at least once before configure",
"makefile-tools.configuration.makefile.preConfigureArgs.description": "Arguments to pass to the pre-configure script",
"makefile-tools.configuration.makefile.postConfigureScript.description": "The path to the script that needs to be run at least once after configure",
"makefile-tools.configuration.makefile.postConfigureArgs.description": "Arguments to pass to the post-configure script",
"makefile-tools.configuration.makefile.alwaysPreConfigure.description": "Always run the pre-configure script before configure",
"makefile-tools.configuration.makefile.alwaysPostConfigure.description": "Always run the post-configure script after configure",
"makefile-tools.configuration.makefile.ignoreDirectoryCommands.description": "Don't analyze directory changing commands like cd, push, pop.",
"makefile-tools.configuration.makefile.phonyOnlyTargets.description": "Display only the phony targets",
"makefile-tools.configuration.makefile.saveBeforeBuildOrConfigure.description": "Save opened files before building or configuring",
"makefile-tools.configuration.makefile.buildBeforeLaunch.description": "Build the current target before launch (debug/run)",
"makefile-tools.configuration.makefile.clearOutputBeforeBuild.description": "Clear the output channel at the beginning of a build",
"makefile-tools.configuration.makefile.compileCommandsPath.description": "The path to the compilation database file",
"makefile-tools.configuration.makefile.panel.visibility.debug.description": "Enable debugging locally (in this host) images built by this extension",
"makefile-tools.configuration.makefile.panel.visibility.run.description": "Enable running locally (in this host) images built by this extension"
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -3,167 +3,269 @@
// Support for integration with CppTools Custom Configuration Provider
import * as configuration from './configuration';
import * as logger from './logger';
import * as make from './make';
import * as parser from './parser';
import * as path from 'path';
import * as util from './util';
import * as vscode from 'vscode';
import * as cpp from 'vscode-cpptools';
import * as configuration from "./configuration";
import * as logger from "./logger";
import * as make from "./make";
import * as parser from "./parser";
import * as path from "path";
import * as util from "./util";
import * as vscode from "vscode";
import * as cpp from "vscode-cpptools";
export interface SourceFileConfigurationItem extends cpp.SourceFileConfigurationItem {
readonly compileCommand: parser.CompileCommand;
export interface SourceFileConfigurationItem
extends cpp.SourceFileConfigurationItem {
readonly compileCommand: parser.CompileCommand;
}
export interface CustomConfigurationProvider {
workspaceBrowse: cpp.WorkspaceBrowseConfiguration;
fileIndex: Map<string, SourceFileConfigurationItem>;
workspaceBrowse: cpp.WorkspaceBrowseConfiguration;
fileIndex: Map<string, SourceFileConfigurationItem>;
}
export class CppConfigurationProvider implements cpp.CustomConfigurationProvider {
public readonly name = 'Makefile Tools';
public readonly extensionId = 'ms-vscode.makefile-tools';
export class CppConfigurationProvider
implements cpp.CustomConfigurationProvider
{
public readonly name = "Makefile Tools";
public readonly extensionId = "ms-vscode.makefile-tools";
private workspaceBrowseConfiguration: cpp.WorkspaceBrowseConfiguration = { browsePath: [] };
private workspaceBrowseConfiguration: cpp.WorkspaceBrowseConfiguration = {
browsePath: [],
};
private getConfiguration(uri: vscode.Uri): SourceFileConfigurationItem | undefined {
let norm_path: string = path.normalize(uri.fsPath);
if (process.platform === "win32") {
norm_path = norm_path.toUpperCase();
}
// First look in the file index computed during the last configure.
// If nothing is found and there is a configure running right now,
// try also the temporary index of the current configure.
let sourceFileConfiguration: SourceFileConfigurationItem | undefined = this.fileIndex.get(norm_path);
if (!sourceFileConfiguration && make.getIsConfiguring()) {
sourceFileConfiguration = make.getDeltaCustomConfigurationProvider().fileIndex.get(norm_path);
logger.message(`Configuration for file ${norm_path} was not found. Searching in the current configure temporary file index.`);
}
if (!sourceFileConfiguration) {
logger.message(`Configuration for file ${norm_path} was not found. CppTools will set a default configuration.`);
}
return sourceFileConfiguration;
private getConfiguration(
uri: vscode.Uri
): SourceFileConfigurationItem | undefined {
let norm_path: string = path.normalize(uri.fsPath);
if (process.platform === "win32") {
norm_path = norm_path.toUpperCase();
}
public async canProvideConfiguration(uri: vscode.Uri): Promise<boolean> {
return !!this.getConfiguration(uri);
// First look in the file index computed during the last configure.
// If nothing is found and there is a configure running right now,
// try also the temporary index of the current configure.
let sourceFileConfiguration: SourceFileConfigurationItem | undefined =
this.fileIndex.get(norm_path);
if (!sourceFileConfiguration && make.getIsConfiguring()) {
sourceFileConfiguration = make
.getDeltaCustomConfigurationProvider()
.fileIndex.get(norm_path);
logger.message(
`Configuration for file ${norm_path} was not found. Searching in the current configure temporary file index.`
);
}
public async provideConfigurations(uris: vscode.Uri[]): Promise<cpp.SourceFileConfigurationItem[]> {
return util.dropNulls(uris.map(u => this.getConfiguration(u)));
if (!sourceFileConfiguration) {
logger.message(
`Configuration for file ${norm_path} was not found. CppTools will set a default configuration.`
);
}
// Used when saving all the computed configurations into a cache.
public getCustomConfigurationProvider(): CustomConfigurationProvider {
let provider: CustomConfigurationProvider = {
fileIndex: this.fileIndex,
workspaceBrowse: this.workspaceBrowseConfiguration
};
return sourceFileConfiguration;
}
return provider;
public async canProvideConfiguration(uri: vscode.Uri): Promise<boolean> {
return !!this.getConfiguration(uri);
}
public async provideConfigurations(
uris: vscode.Uri[]
): Promise<cpp.SourceFileConfigurationItem[]> {
return util.dropNulls(uris.map((u) => this.getConfiguration(u)));
}
// Used when saving all the computed configurations into a cache.
public getCustomConfigurationProvider(): CustomConfigurationProvider {
let provider: CustomConfigurationProvider = {
fileIndex: this.fileIndex,
workspaceBrowse: this.workspaceBrowseConfiguration,
};
return provider;
}
// Used to reset all the configurations with what was previously cached.
public setCustomConfigurationProvider(
provider: CustomConfigurationProvider
): void {
this.fileIndex = provider.fileIndex;
this.workspaceBrowseConfiguration = provider.workspaceBrowse;
}
// Used to merge a new set of configurations on top of what was calculated during the previous configure.
// If this is clean configure, clear all the arrays before the merge.
public mergeCustomConfigurationProvider(
provider: CustomConfigurationProvider
): void {
if (make.getConfigureIsClean()) {
this.fileIndex.clear();
this.workspaceBrowseConfiguration = {
browsePath: [],
compilerArgs: [],
compilerPath: undefined,
standard: undefined,
windowsSdkVersion: undefined,
};
}
// Used to reset all the configurations with what was previously cached.
public setCustomConfigurationProvider(provider: CustomConfigurationProvider): void {
this.fileIndex = provider.fileIndex;
this.workspaceBrowseConfiguration = provider.workspaceBrowse;
let map: Map<string, SourceFileConfigurationItem> = this.fileIndex;
provider.fileIndex.forEach(function (value, key): void {
map.set(key, value);
});
this.workspaceBrowseConfiguration = {
browsePath: util.sortAndRemoveDuplicates(
this.workspaceBrowseConfiguration.browsePath.concat(
provider.workspaceBrowse.browsePath
)
),
compilerArgs: this.workspaceBrowseConfiguration.compilerArgs?.concat(
provider.workspaceBrowse.compilerArgs || []
),
compilerPath: provider.workspaceBrowse.compilerPath,
standard: provider.workspaceBrowse.standard,
windowsSdkVersion: provider.workspaceBrowse.windowsSdkVersion,
};
}
public async canProvideBrowseConfiguration(): Promise<boolean> {
return this.workspaceBrowseConfiguration.browsePath.length > 0;
}
public async canProvideBrowseConfigurationsPerFolder(): Promise<boolean> {
return false;
}
public async provideFolderBrowseConfiguration(
_uri: vscode.Uri
): Promise<cpp.WorkspaceBrowseConfiguration> {
if (_uri.fsPath !== util.getWorkspaceRoot()) {
logger.message("Makefile Tools supports single root for now.");
}
// Used to merge a new set of configurations on top of what was calculated during the previous configure.
// If this is clean configure, clear all the arrays before the merge.
public mergeCustomConfigurationProvider(provider: CustomConfigurationProvider): void {
if (make.getConfigureIsClean()) {
this.fileIndex.clear();
this.workspaceBrowseConfiguration = {
browsePath: [],
compilerArgs: [],
compilerPath: undefined,
standard: undefined,
windowsSdkVersion: undefined
};
}
return this.workspaceBrowseConfiguration;
}
let map: Map<string, SourceFileConfigurationItem> = this.fileIndex;
provider.fileIndex.forEach(function(value, key): void {
map.set(key, value);
});
public async provideBrowseConfiguration(): Promise<cpp.WorkspaceBrowseConfiguration> {
return this.workspaceBrowseConfiguration;
}
public setBrowseConfiguration(
browseConfiguration: cpp.WorkspaceBrowseConfiguration
): void {
this.workspaceBrowseConfiguration = browseConfiguration;
}
this.workspaceBrowseConfiguration = {
browsePath: util.sortAndRemoveDuplicates(this.workspaceBrowseConfiguration.browsePath.concat(provider.workspaceBrowse.browsePath)),
compilerArgs: this.workspaceBrowseConfiguration.compilerArgs?.concat(provider.workspaceBrowse.compilerArgs || []),
compilerPath: provider.workspaceBrowse.compilerPath,
standard: provider.workspaceBrowse.standard,
windowsSdkVersion: provider.workspaceBrowse.windowsSdkVersion
};
public dispose(): void {}
private fileIndex = new Map<string, SourceFileConfigurationItem>();
public logConfigurationProviderBrowse(): void {
logger.message(
"Sending Workspace Browse Configuration: -----------------------------------",
"Verbose"
);
logger.message(
" Browse Path: " +
this.workspaceBrowseConfiguration.browsePath.join(";"),
"Verbose"
);
logger.message(
" Standard: " + this.workspaceBrowseConfiguration.standard,
"Verbose"
);
logger.message(
" Compiler Path: " + this.workspaceBrowseConfiguration.compilerPath,
"Verbose"
);
logger.message(
" Compiler Arguments: " +
this.workspaceBrowseConfiguration.compilerArgs?.join(";"),
"Verbose"
);
if (
process.platform === "win32" &&
this.workspaceBrowseConfiguration.windowsSdkVersion
) {
logger.message(
" Windows SDK Version: " +
this.workspaceBrowseConfiguration.windowsSdkVersion,
"Verbose"
);
}
logger.message(
"----------------------------------------------------------------------------",
"Verbose"
);
}
public async canProvideBrowseConfiguration(): Promise<boolean> {
return this.workspaceBrowseConfiguration.browsePath.length > 0;
public logConfigurationProviderItem(
filePath: SourceFileConfigurationItem,
fromCache: boolean = false
): void {
let uriObj: vscode.Uri = <vscode.Uri>filePath.uri;
logger.message(
"Sending configuration " +
(fromCache ? "(from cache) " : "") +
"for file " +
uriObj.fsPath +
" -----------------------------------",
"Normal"
);
logger.message(
" Defines: " + filePath.configuration.defines.join(";"),
"Verbose"
);
logger.message(
" Includes: " + filePath.configuration.includePath.join(";"),
"Verbose"
);
if (filePath.configuration.forcedInclude) {
logger.message(
" Force Includes: " + filePath.configuration.forcedInclude.join(";"),
"Verbose"
);
}
public async canProvideBrowseConfigurationsPerFolder(): Promise<boolean> {
return false;
logger.message(
" Standard: " + filePath.configuration.standard,
"Verbose"
);
logger.message(
" IntelliSense Mode: " + filePath.configuration.intelliSenseMode,
"Verbose"
);
logger.message(
" Compiler Path: " + filePath.configuration.compilerPath,
"Verbose"
);
logger.message(
" Compiler Arguments: " +
filePath.configuration.compilerArgs?.join(";"),
"Verbose"
);
if (
process.platform === "win32" &&
filePath.configuration.windowsSdkVersion
) {
logger.message(
" Windows SDK Version: " + filePath.configuration.windowsSdkVersion,
"Verbose"
);
}
logger.message(
"---------------------------------------------------------------------------------------------------",
"Verbose"
);
}
public async provideFolderBrowseConfiguration(_uri: vscode.Uri): Promise<cpp.WorkspaceBrowseConfiguration> {
if (_uri.fsPath !== util.getWorkspaceRoot()) {
logger.message("Makefile Tools supports single root for now.");
}
public logConfigurationProviderComplete(): void {
if (configuration.getLoggingLevel() !== "Normal") {
this.logConfigurationProviderBrowse();
return this.workspaceBrowseConfiguration;
}
public async provideBrowseConfiguration(): Promise<cpp.WorkspaceBrowseConfiguration> { return this.workspaceBrowseConfiguration; }
public setBrowseConfiguration(browseConfiguration: cpp.WorkspaceBrowseConfiguration): void { this.workspaceBrowseConfiguration = browseConfiguration; }
public dispose(): void { }
private fileIndex = new Map<string, SourceFileConfigurationItem>();
public logConfigurationProviderBrowse(): void {
logger.message("Sending Workspace Browse Configuration: -----------------------------------", "Verbose");
logger.message(" Browse Path: " + this.workspaceBrowseConfiguration.browsePath.join(";"), "Verbose");
logger.message(" Standard: " + this.workspaceBrowseConfiguration.standard, "Verbose");
logger.message(" Compiler Path: " + this.workspaceBrowseConfiguration.compilerPath, "Verbose");
logger.message(" Compiler Arguments: " + this.workspaceBrowseConfiguration.compilerArgs?.join(";"), "Verbose");
if (process.platform === "win32" && this.workspaceBrowseConfiguration.windowsSdkVersion) {
logger.message(" Windows SDK Version: " + this.workspaceBrowseConfiguration.windowsSdkVersion, "Verbose");
}
logger.message("----------------------------------------------------------------------------", "Verbose");
}
public logConfigurationProviderItem(filePath: SourceFileConfigurationItem, fromCache: boolean = false): void {
let uriObj: vscode.Uri = <vscode.Uri>filePath.uri;
logger.message("Sending configuration " + (fromCache ? "(from cache) " : "") + "for file " + uriObj.fsPath + " -----------------------------------", "Normal");
logger.message(" Defines: " + filePath.configuration.defines.join(";"), "Verbose");
logger.message(" Includes: " + filePath.configuration.includePath.join(";"), "Verbose");
if (filePath.configuration.forcedInclude) {
logger.message(" Force Includes: " + filePath.configuration.forcedInclude.join(";"), "Verbose");
}
logger.message(" Standard: " + filePath.configuration.standard, "Verbose");
logger.message(" IntelliSense Mode: " + filePath.configuration.intelliSenseMode, "Verbose");
logger.message(" Compiler Path: " + filePath.configuration.compilerPath, "Verbose");
logger.message(" Compiler Arguments: " + filePath.configuration.compilerArgs?.join(";"), "Verbose");
if (process.platform === "win32" && filePath.configuration.windowsSdkVersion) {
logger.message(" Windows SDK Version: " + filePath.configuration.windowsSdkVersion, "Verbose");
}
logger.message("---------------------------------------------------------------------------------------------------", "Verbose");
}
public logConfigurationProviderComplete(): void {
if (configuration.getLoggingLevel() !== "Normal") {
this.logConfigurationProviderBrowse();
this.fileIndex.forEach(filePath => {
// logConfigurationProviderComplete is called (so far) only after loading
// the configurations from cache, so mark the boolean to be able to distinguish
// the log entries in case of interleaved output.
this.logConfigurationProviderItem(filePath, true);
});
}
this.fileIndex.forEach((filePath) => {
// logConfigurationProviderComplete is called (so far) only after loading
// the configurations from cache, so mark the boolean to be able to distinguish
// the log entries in case of interleaved output.
this.logConfigurationProviderItem(filePath, true);
});
}
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -3,368 +3,485 @@
// Launch support: debug and run in terminal
import * as configuration from './configuration';
import * as extension from './extension';
import * as logger from './logger';
import * as make from './make';
import * as path from 'path';
import * as telemetry from './telemetry';
import * as util from './util';
import * as vscode from 'vscode';
import * as configuration from "./configuration";
import * as extension from "./extension";
import * as logger from "./logger";
import * as make from "./make";
import * as path from "path";
import * as telemetry from "./telemetry";
import * as util from "./util";
import * as vscode from "vscode";
import * as nls from 'vscode-nls';
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
import * as nls from "vscode-nls";
nls.config({
messageFormat: nls.MessageFormat.bundle,
bundleFormat: nls.BundleFormat.standalone,
})();
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
export enum LaunchStatuses {
success = "success",
blocked = "blocked by (pre)configure or build",
noLaunchConfigurationSet = "no launch configuration set by the user",
launchTargetsListEmpty = "launch targets list empty",
buildFailed = "build failed",
success = "success",
blocked = "blocked by (pre)configure or build",
noLaunchConfigurationSet = "no launch configuration set by the user",
launchTargetsListEmpty = "launch targets list empty",
buildFailed = "build failed",
}
let launcher: Launcher;
export class Launcher implements vscode.Disposable {
// Command property accessible from launch.json:
// the full path of the target binary currently set for launch
public getLaunchTargetPath(): string {
let launchConfiguration: configuration.LaunchConfiguration | undefined = configuration.getCurrentLaunchConfiguration();
if (launchConfiguration) {
return launchConfiguration.binaryPath;
} else {
return "";
}
// Command property accessible from launch.json:
// the full path of the target binary currently set for launch
public getLaunchTargetPath(): string {
let launchConfiguration: configuration.LaunchConfiguration | undefined =
configuration.getCurrentLaunchConfiguration();
if (launchConfiguration) {
return launchConfiguration.binaryPath;
} else {
return "";
}
}
// Command property accessible from launch.json:
// calls getLaunchTargetPath after triggering a build of the current target,
// if makefile.buildBeforeLaunch allows it.
public async launchTargetPath(): Promise<string> {
if (configuration.getBuildBeforeLaunch()) {
await make.buildTarget(
make.TriggeredBy.launch,
configuration.getCurrentTarget() || ""
);
}
// Command property accessible from launch.json:
// calls getLaunchTargetPath after triggering a build of the current target,
// if makefile.buildBeforeLaunch allows it.
public async launchTargetPath(): Promise<string> {
if (configuration.getBuildBeforeLaunch()) {
await make.buildTarget(make.TriggeredBy.launch, configuration.getCurrentTarget() || "");
}
return this.getLaunchTargetPath();
}
return this.getLaunchTargetPath();
// Command property accessible from launch.json:
// the full path from where the target binary is to be launched
public getLaunchTargetDirectory(): string {
let launchConfiguration: configuration.LaunchConfiguration | undefined =
configuration.getCurrentLaunchConfiguration();
if (launchConfiguration) {
return launchConfiguration.cwd;
} else {
return util.getWorkspaceRoot();
}
}
// Command property accessible from launch.json:
// the file name of the current target binary, without path or extension.
public getLaunchTargetFileName(): string {
let launchConfiguration: configuration.LaunchConfiguration | undefined =
configuration.getCurrentLaunchConfiguration();
if (launchConfiguration) {
return path.parse(launchConfiguration.binaryPath).name;
} else {
return "";
}
}
// Command property accessible from launch.json:
// calls getLaunchTargetFileName after triggering a build of the current target,
// if makefile.buildBeforeLaunch allows it.
public async launchTargetFileName(): Promise<string> {
if (configuration.getBuildBeforeLaunch()) {
await make.buildTarget(
make.TriggeredBy.launch,
configuration.getCurrentTarget() || ""
);
}
// Command property accessible from launch.json:
// the full path from where the target binary is to be launched
public getLaunchTargetDirectory(): string {
let launchConfiguration: configuration.LaunchConfiguration | undefined = configuration.getCurrentLaunchConfiguration();
if (launchConfiguration) {
return launchConfiguration.cwd;
} else {
return util.getWorkspaceRoot();
}
return this.getLaunchTargetFileName();
}
// Command property accessible from launch.json:
// the arguments sent to the target binary, returned as array of string
// This is used by the debug/terminal VS Code APIs.
public getLaunchTargetArgs(): string[] {
let launchConfiguration: configuration.LaunchConfiguration | undefined =
configuration.getCurrentLaunchConfiguration();
if (launchConfiguration) {
return launchConfiguration.binaryArgs;
} else {
return [];
}
}
// Command property accessible from launch.json:
// the arguments sent to the target binary, returned as one simple string
// This is an alternative to define the arguments in launch.json,
// since the string array syntax is not working.
// This is not a perfect solution, it all depends on how the main entry point
// is parsing its given arguments.
// Example: for [CWD>tool arg1 arg2 arg3], the tool will receive
// 2 arguments: tool and "arg1 arg2 arg3"
// As opposed to the above case when the tool will receive
// 4 arguments: tool, arg1, arg2, arg3
// TODO: investigate how we can define string array arguments
// for the target binary in launch.json
public getLaunchTargetArgsConcat(): string {
return this.getLaunchTargetArgs().join(" ");
}
// Invoke a VS Code debugging session passing it all the information
// from the current launch configuration.
// Debugger (imperfect) guess logic:
// - VS for msvc toolset, lldb for clang toolset, gdb for anything else.
// - debugger path is assumed to be the same as the compiler path.
// Exceptions for miMode:
// - if the above logic results in a debugger that is missing, try the other one.
// This is needed either because the system might not be equipped
// with the preffered debugger that corresponds to the toolset in use,
// but also because there might be a compiler alias that is not properly identified
// (example: "cc" alias that points to clang but is not identified as clang,
// therefore requesting a gdb debugger which may be missing
// because there is no gcc toolset installed).
// TODO: implement proper detection of aliases and their commands.
// Exceptions for miDebuggerPath:
// - for MacOS, point to the lldb-mi debugger that is installed by CppTools
// - if CppTools extension is not installed, intentionally do not provide a miDebuggerPath On MAC,
// because the debugger knows how to find automatically the right lldb-mi when miMode is lldb and miDebuggerPath is undefined
// (this is true for systems older than Catalina).
// Additionally, cppvsdbg ignores miMode and miDebuggerPath.
public prepareDebugCurrentTarget(
currentLaunchConfiguration: configuration.LaunchConfiguration
): vscode.DebugConfiguration {
let args: string[] = this.getLaunchTargetArgs();
let compilerPath: string | undefined =
extension.extension.getCompilerFullPath();
let parsedObjPath: path.ParsedPath | undefined = compilerPath
? path.parse(compilerPath)
: undefined;
let isClangCompiler: boolean | undefined =
parsedObjPath?.name.startsWith("clang");
let isMsvcCompiler: boolean | undefined =
!isClangCompiler && parsedObjPath?.name.startsWith("cl");
let dbg: string = isMsvcCompiler ? "cppvsdbg" : "cppdbg";
// Initial debugger guess
let guessMiDebuggerPath: string | undefined =
!isMsvcCompiler && parsedObjPath ? parsedObjPath.dir : undefined;
let guessMiMode: string | undefined;
if (parsedObjPath?.name.startsWith("clang")) {
guessMiMode = "lldb";
} else if (!parsedObjPath?.name.startsWith("cl")) {
guessMiMode = "gdb";
}
// Command property accessible from launch.json:
// the file name of the current target binary, without path or extension.
public getLaunchTargetFileName(): string {
let launchConfiguration: configuration.LaunchConfiguration | undefined = configuration.getCurrentLaunchConfiguration();
if (launchConfiguration) {
return path.parse(launchConfiguration.binaryPath).name;
} else {
return "";
}
// If the first chosen debugger is not installed, try the other one.
if (guessMiDebuggerPath && guessMiMode) {
// if the guessMiDebuggerPath is already a file, then go with that. Otherwise, append the guessMiMode.
let debuggerPath: string = util.checkFileExistsSync(guessMiDebuggerPath)
? guessMiDebuggerPath
: path.join(guessMiDebuggerPath, guessMiMode);
if (process.platform === "win32") {
// On mingw a file is not found if the extension is not part of the path
debuggerPath = debuggerPath + ".exe";
}
if (!util.checkFileExistsSync(debuggerPath)) {
guessMiMode = guessMiMode === "gdb" ? "lldb" : "gdb";
}
}
// Command property accessible from launch.json:
// calls getLaunchTargetFileName after triggering a build of the current target,
// if makefile.buildBeforeLaunch allows it.
public async launchTargetFileName(): Promise<string> {
if (configuration.getBuildBeforeLaunch()) {
await make.buildTarget(make.TriggeredBy.launch, configuration.getCurrentTarget() || "");
}
// Properties defined by makefile.launchConfigurations override makefile.defaultLaunchConfiguration
// and they both override the guessed values.
let defaultLaunchConfiguration:
| configuration.DefaultLaunchConfiguration
| undefined = configuration.getDefaultLaunchConfiguration();
let miMode: string | undefined =
currentLaunchConfiguration.MIMode ||
defaultLaunchConfiguration?.MIMode ||
guessMiMode;
let miDebuggerPath: string | undefined =
currentLaunchConfiguration.miDebuggerPath ||
defaultLaunchConfiguration?.miDebuggerPath ||
guessMiDebuggerPath;
return this.getLaunchTargetFileName();
// Exception for MAC-lldb, point to the lldb-mi installed by CppTools or set debugger path to undefined
// (more details in the comment at the beginning of this function).
if (miMode === "lldb" && process.platform === "darwin") {
const cpptoolsExtension: vscode.Extension<any> | undefined =
vscode.extensions.getExtension("ms-vscode.cpptools");
miDebuggerPath = cpptoolsExtension
? path.join(
cpptoolsExtension.extensionPath,
"debugAdapters",
"lldb-mi",
"bin",
"lldb-mi"
)
: undefined;
} else if (miDebuggerPath && miMode) {
// if the miDebuggerPath is already a file, rather than a directory, go with it.
// Otherwise, append the MiMode.
miDebuggerPath = util.checkFileExistsSync(miDebuggerPath)
? miDebuggerPath
: path.join(miDebuggerPath, miMode);
if (process.platform === "win32") {
miDebuggerPath = miDebuggerPath + ".exe";
}
}
// Command property accessible from launch.json:
// the arguments sent to the target binary, returned as array of string
// This is used by the debug/terminal VS Code APIs.
public getLaunchTargetArgs(): string[] {
let launchConfiguration: configuration.LaunchConfiguration | undefined = configuration.getCurrentLaunchConfiguration();
if (launchConfiguration) {
return launchConfiguration.binaryArgs;
} else {
return [];
}
let debugConfig: vscode.DebugConfiguration = {
type: dbg,
name: `Debug My Program`,
request: "launch",
cwd: this.getLaunchTargetDirectory(),
args,
env: util.mergeEnvironment(process.env as util.EnvironmentVariables),
program: this.getLaunchTargetPath(),
MIMode: miMode,
miDebuggerPath: miDebuggerPath,
console: "internalConsole",
internalConsoleOptions: "openOnSessionStart",
stopAtEntry:
currentLaunchConfiguration.stopAtEntry ||
defaultLaunchConfiguration?.stopAtEntry,
symbolSearchPath:
currentLaunchConfiguration.symbolSearchPath ||
defaultLaunchConfiguration?.symbolSearchPath,
};
logger.message(
"Created the following debug config:\n type = " +
debugConfig.type +
"\n cwd = " +
debugConfig.cwd +
" (= " +
this.getLaunchTargetDirectory() +
")" +
"\n args = " +
args.join(" ") +
"\n program = " +
debugConfig.program +
" (= " +
this.getLaunchTargetPath() +
")" +
"\n MIMode = " +
debugConfig.MIMode +
"\n miDebuggerPath = " +
debugConfig.miDebuggerPath +
"\n stopAtEntry = " +
debugConfig.stopAtEntry +
"\n symbolSearchPath = " +
debugConfig.symbolSearchPath
);
return debugConfig;
}
async validateLaunchConfiguration(op: make.Operations): Promise<string> {
// Cannot debug the project if it is currently building or (pre-)configuring.
if (make.blockedByOp(op)) {
return LaunchStatuses.blocked;
}
// Command property accessible from launch.json:
// the arguments sent to the target binary, returned as one simple string
// This is an alternative to define the arguments in launch.json,
// since the string array syntax is not working.
// This is not a perfect solution, it all depends on how the main entry point
// is parsing its given arguments.
// Example: for [CWD>tool arg1 arg2 arg3], the tool will receive
// 2 arguments: tool and "arg1 arg2 arg3"
// As opposed to the above case when the tool will receive
// 4 arguments: tool, arg1, arg2, arg3
// TODO: investigate how we can define string array arguments
// for the target binary in launch.json
public getLaunchTargetArgsConcat(): string {
return this.getLaunchTargetArgs().join(" ");
}
// Invoke a VS Code debugging session passing it all the information
// from the current launch configuration.
// Debugger (imperfect) guess logic:
// - VS for msvc toolset, lldb for clang toolset, gdb for anything else.
// - debugger path is assumed to be the same as the compiler path.
// Exceptions for miMode:
// - if the above logic results in a debugger that is missing, try the other one.
// This is needed either because the system might not be equipped
// with the preffered debugger that corresponds to the toolset in use,
// but also because there might be a compiler alias that is not properly identified
// (example: "cc" alias that points to clang but is not identified as clang,
// therefore requesting a gdb debugger which may be missing
// because there is no gcc toolset installed).
// TODO: implement proper detection of aliases and their commands.
// Exceptions for miDebuggerPath:
// - for MacOS, point to the lldb-mi debugger that is installed by CppTools
// - if CppTools extension is not installed, intentionally do not provide a miDebuggerPath On MAC,
// because the debugger knows how to find automatically the right lldb-mi when miMode is lldb and miDebuggerPath is undefined
// (this is true for systems older than Catalina).
// Additionally, cppvsdbg ignores miMode and miDebuggerPath.
public prepareDebugCurrentTarget(currentLaunchConfiguration: configuration.LaunchConfiguration): vscode.DebugConfiguration {
let args: string[] = this.getLaunchTargetArgs();
let compilerPath : string | undefined = extension.extension.getCompilerFullPath();
let parsedObjPath : path.ParsedPath | undefined = compilerPath ? path.parse(compilerPath) : undefined;
let isClangCompiler : boolean | undefined = parsedObjPath?.name.startsWith("clang");
let isMsvcCompiler : boolean | undefined = !isClangCompiler && parsedObjPath?.name.startsWith("cl");
let dbg: string = (isMsvcCompiler) ? "cppvsdbg" : "cppdbg";
// Initial debugger guess
let guessMiDebuggerPath : string | undefined = (!isMsvcCompiler && parsedObjPath) ? parsedObjPath.dir : undefined;
let guessMiMode: string | undefined;
if (parsedObjPath?.name.startsWith("clang")) {
guessMiMode = "lldb";
} else if (!parsedObjPath?.name.startsWith("cl")) {
guessMiMode = "gdb";
}
// If the first chosen debugger is not installed, try the other one.
if (guessMiDebuggerPath && guessMiMode) {
// if the guessMiDebuggerPath is already a file, then go with that. Otherwise, append the guessMiMode.
let debuggerPath: string = util.checkFileExistsSync(guessMiDebuggerPath) ? guessMiDebuggerPath : path.join(guessMiDebuggerPath, guessMiMode);
if (process.platform === "win32") {
// On mingw a file is not found if the extension is not part of the path
debuggerPath = debuggerPath + ".exe";
if (configuration.getBuildBeforeLaunch()) {
let currentBuildTarget: string = configuration.getCurrentTarget() || "";
logger.message(
`Building current target before launch: "${currentBuildTarget}"`
);
let buildSuccess: boolean =
(await make.buildTarget(
make.TriggeredBy.buildTarget,
currentBuildTarget,
false
)) === make.ConfigureBuildReturnCodeTypes.success;
if (!buildSuccess) {
logger.message(`Building target "${currentBuildTarget}" failed.`);
let noButton: string = localize("no", "No");
let yesButton: string = localize("yes", "Yes");
const message: string = localize(
"build.failed.continue.anyway",
"Build failed. Do you want to continue anyway?"
);
const chosen: vscode.MessageItem | undefined =
await vscode.window.showErrorMessage<vscode.MessageItem>(
message,
{
title: yesButton,
isCloseAffordance: false,
},
{
title: noButton,
isCloseAffordance: true,
}
);
if (!util.checkFileExistsSync(debuggerPath)) {
guessMiMode = (guessMiMode === "gdb") ? "lldb" : "gdb";
}
if (chosen === undefined || chosen.title === noButton) {
return LaunchStatuses.buildFailed;
}
// Properties defined by makefile.launchConfigurations override makefile.defaultLaunchConfiguration
// and they both override the guessed values.
let defaultLaunchConfiguration: configuration.DefaultLaunchConfiguration | undefined = configuration.getDefaultLaunchConfiguration();
let miMode: string | undefined = currentLaunchConfiguration.MIMode || defaultLaunchConfiguration?.MIMode || guessMiMode;
let miDebuggerPath: string | undefined = currentLaunchConfiguration.miDebuggerPath || defaultLaunchConfiguration?.miDebuggerPath || guessMiDebuggerPath;
// Exception for MAC-lldb, point to the lldb-mi installed by CppTools or set debugger path to undefined
// (more details in the comment at the beginning of this function).
if (miMode === "lldb" && process.platform === "darwin") {
const cpptoolsExtension: vscode.Extension<any> | undefined = vscode.extensions.getExtension('ms-vscode.cpptools');
miDebuggerPath = cpptoolsExtension ? path.join(cpptoolsExtension.extensionPath, "debugAdapters", "lldb-mi", "bin", "lldb-mi") : undefined;
} else if (miDebuggerPath && miMode) {
// if the miDebuggerPath is already a file, rather than a directory, go with it.
// Otherwise, append the MiMode.
miDebuggerPath = util.checkFileExistsSync(miDebuggerPath) ? miDebuggerPath : path.join(miDebuggerPath, miMode);
if (process.platform === "win32") {
miDebuggerPath = miDebuggerPath + ".exe";
}
}
let debugConfig: vscode.DebugConfiguration = {
type: dbg,
name: `Debug My Program`,
request: 'launch',
cwd: this.getLaunchTargetDirectory(),
args,
env: util.mergeEnvironment(process.env as util.EnvironmentVariables),
program: this.getLaunchTargetPath(),
MIMode: miMode,
miDebuggerPath: miDebuggerPath,
console: "internalConsole",
internalConsoleOptions: "openOnSessionStart",
stopAtEntry: currentLaunchConfiguration.stopAtEntry || defaultLaunchConfiguration?.stopAtEntry,
symbolSearchPath: currentLaunchConfiguration.symbolSearchPath || defaultLaunchConfiguration?.symbolSearchPath
};
logger.message("Created the following debug config:\n type = " + debugConfig.type +
"\n cwd = " + debugConfig.cwd + " (= " + this.getLaunchTargetDirectory() + ")" +
"\n args = " + args.join(" ") +
"\n program = " + debugConfig.program + " (= " + this.getLaunchTargetPath() + ")" +
"\n MIMode = " + debugConfig.MIMode +
"\n miDebuggerPath = " + debugConfig.miDebuggerPath +
"\n stopAtEntry = " + debugConfig.stopAtEntry +
"\n symbolSearchPath = " + debugConfig.symbolSearchPath);
return debugConfig;
}
}
async validateLaunchConfiguration(op: make.Operations): Promise<string> {
// Cannot debug the project if it is currently building or (pre-)configuring.
if (make.blockedByOp(op)) {
return LaunchStatuses.blocked;
}
let currentLaunchConfiguration:
| configuration.LaunchConfiguration
| undefined = configuration.getCurrentLaunchConfiguration();
if (!currentLaunchConfiguration) {
// If no launch configuration is set, give the user a chance to select one now from the quick pick
// (unless we know it's going to be empty).
if (configuration.getLaunchTargets().length === 0) {
vscode.window.showErrorMessage(
localize(
"cannot.op.no.launch.config.targets",
"Cannot {0} because there is no launch configuration set and the list of launch targets is empty. Double check the makefile configuration and the build target.",
`'${op}'`
)
);
return LaunchStatuses.launchTargetsListEmpty;
} else {
vscode.window.showErrorMessage(
localize(
"cannot.op.choose.launch.config",
"Cannot {0} because there is no launch configuration set. Choose one from the quick pick.",
`'${op}'`
)
);
await configuration.selectLaunchConfiguration();
if (configuration.getBuildBeforeLaunch()) {
let currentBuildTarget: string = configuration.getCurrentTarget() || "";
logger.message(`Building current target before launch: "${currentBuildTarget}"`);
let buildSuccess: boolean = (await make.buildTarget(make.TriggeredBy.buildTarget, currentBuildTarget, false)) === make.ConfigureBuildReturnCodeTypes.success;
if (!buildSuccess) {
logger.message(`Building target "${currentBuildTarget}" failed.`);
let noButton: string = localize("no", "No");
let yesButton: string = localize("yes", "Yes");
const message: string = localize("build.failed.continue.anyway", "Build failed. Do you want to continue anyway?");
const chosen: vscode.MessageItem | undefined = await vscode.window.showErrorMessage<vscode.MessageItem>(message,
{
title: yesButton,
isCloseAffordance: false,
},
{
title: noButton,
isCloseAffordance: true
});
if (chosen === undefined || chosen.title === noButton) {
return LaunchStatuses.buildFailed;
}
}
}
let currentLaunchConfiguration: configuration.LaunchConfiguration | undefined = configuration.getCurrentLaunchConfiguration();
// Read again the current launch configuration. If a current launch configuration is stil not set
// (the user cancelled the quick pick or the parser found zero launch targets) message and fail.
currentLaunchConfiguration =
configuration.getCurrentLaunchConfiguration();
if (!currentLaunchConfiguration) {
// If no launch configuration is set, give the user a chance to select one now from the quick pick
// (unless we know it's going to be empty).
if (configuration.getLaunchTargets().length === 0) {
vscode.window.showErrorMessage(localize("cannot.op.no.launch.config.targets",
"Cannot {0} because there is no launch configuration set and the list of launch targets is empty. Double check the makefile configuration and the build target.", `'${op}'`));
return LaunchStatuses.launchTargetsListEmpty;
} else {
vscode.window.showErrorMessage(localize("cannot.op.choose.launch.config", "Cannot {0} because there is no launch configuration set. Choose one from the quick pick.", `'${op}'`));
await configuration.selectLaunchConfiguration();
// Read again the current launch configuration. If a current launch configuration is stil not set
// (the user cancelled the quick pick or the parser found zero launch targets) message and fail.
currentLaunchConfiguration = configuration.getCurrentLaunchConfiguration();
if (!currentLaunchConfiguration) {
vscode.window.showErrorMessage(localize("cannot.op.without.launch.config", "Cannot {0} until you select an active launch configuration.", `'${op}'`));
return LaunchStatuses.noLaunchConfigurationSet;
}
}
vscode.window.showErrorMessage(
localize(
"cannot.op.without.launch.config",
"Cannot {0} until you select an active launch configuration.",
`'${op}'`
)
);
return LaunchStatuses.noLaunchConfigurationSet;
}
return LaunchStatuses.success;
}
}
public async debugCurrentTarget(): Promise<vscode.DebugSession | undefined> {
let status: string = await this.validateLaunchConfiguration(make.Operations.debug);
let currentLaunchConfiguration: configuration.LaunchConfiguration | undefined;
if (status === LaunchStatuses.success) {
currentLaunchConfiguration = configuration.getCurrentLaunchConfiguration();
}
return LaunchStatuses.success;
}
if (currentLaunchConfiguration) {
let debugConfig: vscode.DebugConfiguration = this.prepareDebugCurrentTarget(currentLaunchConfiguration);
let startFolder: vscode.WorkspaceFolder;
if (vscode.workspace.workspaceFolders) {
startFolder = vscode.workspace.workspaceFolders[0];
await vscode.debug.startDebugging(startFolder, debugConfig);
} else {
await vscode.debug.startDebugging(undefined, debugConfig);
}
if (!vscode.debug.activeDebugSession) {
status = "failed";
}
}
let telemetryProperties: telemetry.Properties = {
status: status
};
telemetry.logEvent("debug", telemetryProperties);
return vscode.debug.activeDebugSession;
public async debugCurrentTarget(): Promise<vscode.DebugSession | undefined> {
let status: string = await this.validateLaunchConfiguration(
make.Operations.debug
);
let currentLaunchConfiguration:
| configuration.LaunchConfiguration
| undefined;
if (status === LaunchStatuses.success) {
currentLaunchConfiguration =
configuration.getCurrentLaunchConfiguration();
}
private launchTerminal: vscode.Terminal | undefined;
if (currentLaunchConfiguration) {
let debugConfig: vscode.DebugConfiguration =
this.prepareDebugCurrentTarget(currentLaunchConfiguration);
let startFolder: vscode.WorkspaceFolder;
if (vscode.workspace.workspaceFolders) {
startFolder = vscode.workspace.workspaceFolders[0];
await vscode.debug.startDebugging(startFolder, debugConfig);
} else {
await vscode.debug.startDebugging(undefined, debugConfig);
}
// Watch for the user closing our terminal
private readonly onTerminalClose = vscode.window.onDidCloseTerminal(term => {
if (term === this.launchTerminal) {
this.launchTerminal = undefined;
}
});
// Invoke a VS Code running terminal passing it all the information
// from the current launch configuration
public prepareRunCurrentTarget(): string {
// Add a pair of quotes just in case there is a space in the binary path
let terminalCommand: string = '"' + this.getLaunchTargetPath() + '" ';
terminalCommand += this.getLaunchTargetArgs().join(" ");
// Log the message for high verbosity only because the output channel will become visible over the terminal,
// even if the terminal show() is called after the logger show().
logger.message("Running command '" + terminalCommand + "' in the terminal from location '" + this.getLaunchTargetDirectory() + "'", "Debug");
return terminalCommand;
if (!vscode.debug.activeDebugSession) {
status = "failed";
}
}
public async runCurrentTarget(): Promise<vscode.Terminal> {
const terminalOptions: vscode.TerminalOptions = {
name: 'Make/Launch',
};
let telemetryProperties: telemetry.Properties = {
status: status,
};
telemetry.logEvent("debug", telemetryProperties);
// Use cmd.exe on Windows
if (process.platform === 'win32') {
terminalOptions.shellPath = 'C:\\Windows\\System32\\cmd.exe';
}
return vscode.debug.activeDebugSession;
}
terminalOptions.cwd = this.getLaunchTargetDirectory();
terminalOptions.env = util.mergeEnvironment(process.env as util.EnvironmentVariables);
private launchTerminal: vscode.Terminal | undefined;
if (!this.launchTerminal) {
this.launchTerminal = vscode.window.createTerminal(terminalOptions);
}
// Watch for the user closing our terminal
private readonly onTerminalClose = vscode.window.onDidCloseTerminal(
(term) => {
if (term === this.launchTerminal) {
this.launchTerminal = undefined;
}
}
);
let status: string = await this.validateLaunchConfiguration(make.Operations.run);
let currentLaunchConfiguration: configuration.LaunchConfiguration | undefined;
if (status === LaunchStatuses.success) {
currentLaunchConfiguration = configuration.getCurrentLaunchConfiguration();
let terminalCommand: string = this.prepareRunCurrentTarget();
this.launchTerminal.sendText(terminalCommand);
// Invoke a VS Code running terminal passing it all the information
// from the current launch configuration
public prepareRunCurrentTarget(): string {
// Add a pair of quotes just in case there is a space in the binary path
let terminalCommand: string = '"' + this.getLaunchTargetPath() + '" ';
terminalCommand += this.getLaunchTargetArgs().join(" ");
let telemetryProperties: telemetry.Properties = {
status: status
};
telemetry.logEvent("run", telemetryProperties);
this.launchTerminal.show();
}
// Log the message for high verbosity only because the output channel will become visible over the terminal,
// even if the terminal show() is called after the logger show().
logger.message(
"Running command '" +
terminalCommand +
"' in the terminal from location '" +
this.getLaunchTargetDirectory() +
"'",
"Debug"
);
return terminalCommand;
}
return this.launchTerminal;
public async runCurrentTarget(): Promise<vscode.Terminal> {
const terminalOptions: vscode.TerminalOptions = {
name: "Make/Launch",
};
// Use cmd.exe on Windows
if (process.platform === "win32") {
terminalOptions.shellPath = "C:\\Windows\\System32\\cmd.exe";
}
public dispose(): void {
if (this.launchTerminal) {
this.launchTerminal.dispose();
}
terminalOptions.cwd = this.getLaunchTargetDirectory();
terminalOptions.env = util.mergeEnvironment(
process.env as util.EnvironmentVariables
);
this.onTerminalClose.dispose();
if (!this.launchTerminal) {
this.launchTerminal = vscode.window.createTerminal(terminalOptions);
}
let status: string = await this.validateLaunchConfiguration(
make.Operations.run
);
let currentLaunchConfiguration:
| configuration.LaunchConfiguration
| undefined;
if (status === LaunchStatuses.success) {
currentLaunchConfiguration =
configuration.getCurrentLaunchConfiguration();
let terminalCommand: string = this.prepareRunCurrentTarget();
this.launchTerminal.sendText(terminalCommand);
let telemetryProperties: telemetry.Properties = {
status: status,
};
telemetry.logEvent("run", telemetryProperties);
this.launchTerminal.show();
}
return this.launchTerminal;
}
public dispose(): void {
if (this.launchTerminal) {
this.launchTerminal.dispose();
}
this.onTerminalClose.dispose();
}
}
export function getLauncher(): Launcher {
if (launcher === undefined) {
launcher = new Launcher();
}
if (launcher === undefined) {
launcher = new Launcher();
}
return launcher;
return launcher;
}

Просмотреть файл

@ -3,78 +3,78 @@
// Logging support
import * as fs from 'fs';
import * as configuration from './configuration';
import * as vscode from 'vscode';
import * as fs from "fs";
import * as configuration from "./configuration";
import * as vscode from "vscode";
let makeOutputChannel: vscode.OutputChannel | undefined;
function getOutputChannel(): vscode.OutputChannel {
if (!makeOutputChannel) {
makeOutputChannel = vscode.window.createOutputChannel("Makefile tools");
}
if (!makeOutputChannel) {
makeOutputChannel = vscode.window.createOutputChannel("Makefile tools");
}
return makeOutputChannel;
return makeOutputChannel;
}
// TODO: process verbosities with enums instead of strings.
// This is a temporary hack.
function loggingLevelApplies(messageVerbosity: string | undefined): boolean {
let projectVerbosity: string | undefined = configuration.getLoggingLevel();
let projectVerbosity: string | undefined = configuration.getLoggingLevel();
if (messageVerbosity === "Debug") {
return projectVerbosity === "Debug";
} else if (messageVerbosity === "Verbose") {
return projectVerbosity === "Verbose" || projectVerbosity === "Debug";
}
if (messageVerbosity === "Debug") {
return projectVerbosity === "Debug";
} else if (messageVerbosity === "Verbose") {
return projectVerbosity === "Verbose" || projectVerbosity === "Debug";
}
return true;
return true;
}
export function showOutputChannel(): void {
if (makeOutputChannel) {
makeOutputChannel.show(true);
}
if (makeOutputChannel) {
makeOutputChannel.show(true);
}
}
export function clearOutputChannel(): void {
if (makeOutputChannel) {
makeOutputChannel.clear();
}
if (makeOutputChannel) {
makeOutputChannel.clear();
}
}
//TODO: implement more verbosity levels for the output log
export function message(message: string, loggingLevel?: string): void {
// Print the message only if the intended logging level matches the settings
// or if no loggingLevel restriction is provided.
if (!loggingLevelApplies(loggingLevel)) {
return;
}
// Print the message only if the intended logging level matches the settings
// or if no loggingLevel restriction is provided.
if (!loggingLevelApplies(loggingLevel)) {
return;
}
let channel: vscode.OutputChannel = getOutputChannel();
channel.appendLine(message);
let channel: vscode.OutputChannel = getOutputChannel();
channel.appendLine(message);
let extensionLog : string | undefined = configuration.getExtensionLog();
if (extensionLog) {
fs.appendFileSync(extensionLog, message);
fs.appendFileSync(extensionLog, "\n");
}
let extensionLog: string | undefined = configuration.getExtensionLog();
if (extensionLog) {
fs.appendFileSync(extensionLog, message);
fs.appendFileSync(extensionLog, "\n");
}
}
// This is used for a few scenarios where the message already has end of line incorporated.
// Example: stdout/stderr of a child process read before the stream is closed.
export function messageNoCR(message: string, loggingLevel?: string): void {
// Print the message only if the intended logging level matches the settings
// or if no loggingLevel restriction is provided.
if (!loggingLevelApplies(loggingLevel)) {
return;
}
// Print the message only if the intended logging level matches the settings
// or if no loggingLevel restriction is provided.
if (!loggingLevelApplies(loggingLevel)) {
return;
}
let channel: vscode.OutputChannel = getOutputChannel();
channel.append(message);
let channel: vscode.OutputChannel = getOutputChannel();
channel.append(message);
let extensionLog : string | undefined = configuration.getExtensionLog();
if (extensionLog) {
fs.appendFileSync(extensionLog, message);
}
let extensionLog: string | undefined = configuration.getExtensionLog();
if (extensionLog) {
fs.appendFileSync(extensionLog, message);
}
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -3,7 +3,7 @@
// state.ts
import * as vscode from 'vscode';
import * as vscode from "vscode";
// Class for the management of all the workspace state variables
export class StateManager {
@ -20,26 +20,26 @@ export class StateManager {
// The project build configuration (one of the entries in the array of makefile.configurations
// or a default).
get buildConfiguration(): string | undefined {
return this._get<string>('buildConfiguration');
return this._get<string>("buildConfiguration");
}
set buildConfiguration(v: string | undefined) {
this._update('buildConfiguration', v);
this._update("buildConfiguration", v);
}
// The project build target (one of the targets defined in the makefile).
get buildTarget(): string | undefined {
return this._get<string>('buildTarget');
return this._get<string>("buildTarget");
}
set buildTarget(v: string | undefined) {
this._update('buildTarget', v);
this._update("buildTarget", v);
}
// The project launch configuration (one of the entries in the array of makefile.launchConfigurations).
get launchConfiguration(): string | undefined {
return this._get<string>('launchConfiguration');
return this._get<string>("launchConfiguration");
}
set launchConfiguration(v: string | undefined) {
this._update('launchConfiguration', v);
this._update("launchConfiguration", v);
}
// Whether this project had any configure attempt before
@ -47,10 +47,10 @@ export class StateManager {
// Sent as telemetry information and useful to know
// how many projects are able to configure out of the box.
get ranConfigureInCodebaseLifetime(): boolean {
return this._get<boolean>('ranConfigureInCodebaseLifetime') || false;
return this._get<boolean>("ranConfigureInCodebaseLifetime") || false;
}
set ranConfigureInCodebaseLifetime(v: boolean) {
this._update('ranConfigureInCodebaseLifetime', v);
this._update("ranConfigureInCodebaseLifetime", v);
}
// Whether this project had any --dry-run specific configure attempt before
@ -59,10 +59,10 @@ export class StateManager {
// that some makefile code could still execute even in --dry-run mode.
// Once the user decides 'Yes(don't show again)' the popup is not shown.
get ranDryRunInCodebaseLifetime(): boolean {
return this._get<boolean>('ranDryRunInCodebaseLifetime') || false;
return this._get<boolean>("ranDryRunInCodebaseLifetime") || false;
}
set ranDryRunInCodebaseLifetime(v: boolean) {
this._update('ranDryRunInCodebaseLifetime', v);
this._update("ranDryRunInCodebaseLifetime", v);
}
// If the project needs a clean configure as a result
@ -70,15 +70,15 @@ export class StateManager {
// (makefile configuration change, build target change,
// settings or makefiles edits)
get configureDirty(): boolean {
let dirty: boolean | undefined = this._get<boolean>('configureDirty');
let dirty: boolean | undefined = this._get<boolean>("configureDirty");
if (dirty === undefined) {
dirty = true;
dirty = true;
}
return dirty;
}
set configureDirty(v: boolean) {
this._update('configureDirty', v);
this._update("configureDirty", v);
}
// Reset all the variables saved in the workspace state.
@ -91,7 +91,7 @@ export class StateManager {
this.configureDirty = false;
if (reloadWindow) {
vscode.commands.executeCommand('workbench.action.reloadWindow');
vscode.commands.executeCommand("workbench.action.reloadWindow");
}
}
}

Просмотреть файл

@ -3,109 +3,123 @@
// Telemetry.ts
import * as configuration from './configuration';
import * as logger from './logger';
import * as util from './util';
import TelemetryReporter from '@vscode/extension-telemetry';
import * as configuration from "./configuration";
import * as logger from "./logger";
import * as util from "./util";
import TelemetryReporter from "@vscode/extension-telemetry";
import * as vscode from "vscode";
export type Properties = { [key: string]: string };
export type Measures = { [key: string]: number };
interface IPackageInfo {
name: string;
version: string;
aiKey: string;
name: string;
version: string;
aiKey: string;
}
let telemetryReporter: TelemetryReporter | null;
export function activate(): void {
try {
// Don't create the telemetry object (which will result in no information being sent)
// when running Makefile Tools tests.
if (process.env['MAKEFILE_TOOLS_TESTING'] !== '1') {
telemetryReporter = createReporter();
}
} catch (e) {
// can't really do much about this
try {
// Don't create the telemetry object (which will result in no information being sent)
// when running Makefile Tools tests.
if (process.env["MAKEFILE_TOOLS_TESTING"] !== "1") {
telemetryReporter = createReporter();
}
} catch (e) {
// can't really do much about this
}
}
export async function deactivate(): Promise<void> {
if (telemetryReporter) {
await telemetryReporter.dispose();
}
if (telemetryReporter) {
await telemetryReporter.dispose();
}
}
export function telemetryLogger(str: string, loggingLevel?: string) {
if (vscode.env.isTelemetryEnabled) {
logger.message(str, loggingLevel);
}
if (vscode.env.isTelemetryEnabled) {
logger.message(str, loggingLevel);
}
}
export function logEvent(eventName: string, properties?: Properties, measures?: Measures): void {
// We don't want to log telemetry in testing.
if (telemetryReporter && process.env["MAKEFILE_TOOLS_TESTING"] !== "1") {
try {
telemetryReporter.sendTelemetryEvent(eventName, properties, measures);
} catch (e) {
telemetryLogger(e.message);
}
telemetryLogger(`Sending telemetry: eventName = ${eventName}`, "Debug");
if (properties) {
telemetryLogger(`properties: ${Object.getOwnPropertyNames(properties).map(k => `${k} = "${properties[k]}"`).concat()}`, "Debug");
}
if (measures) {
telemetryLogger(`measures: ${Object.getOwnPropertyNames(measures).map(k => `${k} = "${measures[k]}"`).concat()}`, "Debug");
}
export function logEvent(
eventName: string,
properties?: Properties,
measures?: Measures
): void {
// We don't want to log telemetry in testing.
if (telemetryReporter && process.env["MAKEFILE_TOOLS_TESTING"] !== "1") {
try {
telemetryReporter.sendTelemetryEvent(eventName, properties, measures);
} catch (e) {
telemetryLogger(e.message);
}
telemetryLogger(`Sending telemetry: eventName = ${eventName}`, "Debug");
if (properties) {
telemetryLogger(
`properties: ${Object.getOwnPropertyNames(properties)
.map((k) => `${k} = "${properties[k]}"`)
.concat()}`,
"Debug"
);
}
if (measures) {
telemetryLogger(
`measures: ${Object.getOwnPropertyNames(measures)
.map((k) => `${k} = "${measures[k]}"`)
.concat()}`,
"Debug"
);
}
}
}
// Allow-lists for various settings.
function filterSetting(value: any, key: string, defaultValue: string) : string {
if (key === "makefile.dryrunSwitches") {
let dryrunSwitches: string[] = value;
let filteredSwitches: string[] | undefined = dryrunSwitches.map(sw => {
switch (sw) {
case "--dry-run":
case "-n":
case "--just-print":
case "--recon":
function filterSetting(value: any, key: string, defaultValue: string): string {
if (key === "makefile.dryrunSwitches") {
let dryrunSwitches: string[] = value;
let filteredSwitches: string[] | undefined = dryrunSwitches.map((sw) => {
switch (sw) {
case "--dry-run":
case "-n":
case "--just-print":
case "--recon":
case "--keep-going":
case "-k":
case "--keep-going":
case "-k":
case "--always-make":
case "-B":
case "--always-make":
case "-B":
case "--print-data-base":
case "-p":
case "--print-data-base":
case "-p":
case "--print-directory":
case "-w":
return sw;
default:
return "...";
}
});
case "--print-directory":
case "-w":
return sw;
default:
return "...";
}
});
return filteredSwitches.join(";");
}
return filteredSwitches.join(";");
}
// Even if the key represents a setting that shouldn't share its value,
// we can still record if it is undefined by the user (removed from settings.json)
// or equal to the default we set in package.json.
if (!value) {
return "undefined";
} else if (value === defaultValue) {
return "default";
}
// Even if the key represents a setting that shouldn't share its value,
// we can still record if it is undefined by the user (removed from settings.json)
// or equal to the default we set in package.json.
if (!value) {
return "undefined";
} else if (value === defaultValue) {
return "default";
}
return "...";
return "...";
}
// Detect which item from the given array setting is relevant for telemetry.
@ -116,34 +130,47 @@ function filterSetting(value: any, key: string, defaultValue: string) : string {
// Example: don't report telemetry for all launch configurations but only for
// the current launch configuration.
function activeArrayItem(setting: string, key: string): number {
if (key === "makefile.configurations") {
let makefileConfigurations: configuration.MakefileConfiguration[] = configuration.getMakefileConfigurations();
let currentMakefileConfigurationName: string | undefined = configuration.getCurrentMakefileConfiguration();
if (!currentMakefileConfigurationName) {
return -1;
}
let currentMakefileConfiguration: configuration.MakefileConfiguration | undefined = makefileConfigurations.find(config => {
if (config.name === currentMakefileConfigurationName) {
return config;
}
});
return currentMakefileConfiguration ? makefileConfigurations.indexOf(currentMakefileConfiguration) : -1;
if (key === "makefile.configurations") {
let makefileConfigurations: configuration.MakefileConfiguration[] =
configuration.getMakefileConfigurations();
let currentMakefileConfigurationName: string | undefined =
configuration.getCurrentMakefileConfiguration();
if (!currentMakefileConfigurationName) {
return -1;
}
if (key === "makefile.launchConfigurations") {
let launchConfigurations: configuration.LaunchConfiguration[] = configuration.getLaunchConfigurations();
let currentLaunchConfiguration: configuration.LaunchConfiguration | undefined = launchConfigurations.find(config => {
if (util.areEqual(config, configuration.getCurrentLaunchConfiguration())) {
return config;
}
});
let currentMakefileConfiguration:
| configuration.MakefileConfiguration
| undefined = makefileConfigurations.find((config) => {
if (config.name === currentMakefileConfigurationName) {
return config;
}
});
return currentLaunchConfiguration ? launchConfigurations.indexOf(currentLaunchConfiguration) : -1;
}
return currentMakefileConfiguration
? makefileConfigurations.indexOf(currentMakefileConfiguration)
: -1;
}
return -1;
if (key === "makefile.launchConfigurations") {
let launchConfigurations: configuration.LaunchConfiguration[] =
configuration.getLaunchConfigurations();
let currentLaunchConfiguration:
| configuration.LaunchConfiguration
| undefined = launchConfigurations.find((config) => {
if (
util.areEqual(config, configuration.getCurrentLaunchConfiguration())
) {
return config;
}
});
return currentLaunchConfiguration
? launchConfigurations.indexOf(currentLaunchConfiguration)
: -1;
}
return -1;
}
// Filter the array item indexes from the key since for now, when we analyze an array,
@ -160,18 +187,18 @@ function activeArrayItem(setting: string, key: string): number {
// This helper should be called when a property is ready to be collected for telemetry.
// Calling this earlier would result in different dot patterns.
function filterKey(key: string): string {
let filteredKey: string = key;
let lastDot: number = key.lastIndexOf(".");
let beforeLastDot: number = key.lastIndexOf(".", lastDot - 1);
if (lastDot !== -1 && beforeLastDot !== -1) {
let lastProp: any = key.substring(beforeLastDot + 1, lastDot);
let numericalProp: number = Number.parseInt(lastProp);
if (!Number.isNaN(numericalProp)) {
filteredKey = filteredKey.replace(`${numericalProp}.`, "");
}
let filteredKey: string = key;
let lastDot: number = key.lastIndexOf(".");
let beforeLastDot: number = key.lastIndexOf(".", lastDot - 1);
if (lastDot !== -1 && beforeLastDot !== -1) {
let lastProp: any = key.substring(beforeLastDot + 1, lastDot);
let numericalProp: number = Number.parseInt(lastProp);
if (!Number.isNaN(numericalProp)) {
filteredKey = filteredKey.replace(`${numericalProp}.`, "");
}
}
return filteredKey;
return filteredKey;
}
// Analyze recursively all the settings for telemetry and type validation.
@ -180,165 +207,218 @@ function filterKey(key: string): string {
// If analyzeSettings gets called before a configure (or after an unsuccesful one), it is possible to have
// inaccurate or incomplete telemetry information for makefile and launch configurations.
// This is not very critical since any of their state changes will update telemetry for them.
export async function analyzeSettings(setting: any, key: string, propSchema: any, ignoreDefault: boolean, telemetryProperties: Properties | null): Promise<Properties | null> {
// type can be undefined if setting is null,
// which happens when the user removes that setting.
let type : string | undefined = setting ? typeof (setting) : undefined;
let jsonType : string | undefined = propSchema.type ? propSchema.type : undefined;
export async function analyzeSettings(
setting: any,
key: string,
propSchema: any,
ignoreDefault: boolean,
telemetryProperties: Properties | null
): Promise<Properties | null> {
// type can be undefined if setting is null,
// which happens when the user removes that setting.
let type: string | undefined = setting ? typeof setting : undefined;
let jsonType: string | undefined = propSchema.type
? propSchema.type
: undefined;
// Skip anything else if the current setting represents a function.
if (type === "function") {
return telemetryProperties;
}
// Skip anything else if the current setting represents a function.
if (type === "function") {
return telemetryProperties;
}
// Interested to continue only for properties that are different than their defaults,
// unless ignoreDefault requests we report those too (useful when the user is changing
// from a non default value back to default, usually via removing/undefining a setting).
if (util.areEqual(propSchema.default, setting) && ignoreDefault) {
return telemetryProperties;
}
// Interested to continue only for properties that are different than their defaults,
// unless ignoreDefault requests we report those too (useful when the user is changing
// from a non default value back to default, usually via removing/undefining a setting).
if (util.areEqual(propSchema.default, setting) && ignoreDefault) {
return telemetryProperties;
}
// The type "array" defined in package.json is seen as object by the workspace setting type.
// Not all package.json constructs have a type (example: configuration properties list)
// but the workspace setting type sees them as object.
if (jsonType !== type &&
jsonType !== undefined && type !== undefined &&
(type !== "object" || jsonType !== "array")) {
telemetryLogger(`Settings versus package.json type mismatch for "${key}".`);
}
// The type "array" defined in package.json is seen as object by the workspace setting type.
// Not all package.json constructs have a type (example: configuration properties list)
// but the workspace setting type sees them as object.
if (
jsonType !== type &&
jsonType !== undefined &&
type !== undefined &&
(type !== "object" || jsonType !== "array")
) {
telemetryLogger(`Settings versus package.json type mismatch for "${key}".`);
}
// Enum values always safe to report.
// Validate the allowed values against the expanded variable.
let enumValues: any[] = propSchema.enum;
if (enumValues && enumValues.length > 0) {
const regexp: RegExp = /(makefile\.)(.+)/mg;
const res: RegExpExecArray | null = regexp.exec(key);
let expandedSetting: string = res ? await util.getExpandedSetting<string>(res[2]) : setting;
if (!enumValues.includes(expandedSetting)) {
telemetryLogger(`Invalid value "${expandedSetting}" for enum "${key}". Only "${enumValues.join(";")}" values are allowed."`);
if (telemetryProperties) {
telemetryProperties[filterKey(key)] = "invalid";
}
} else if (telemetryProperties) {
telemetryProperties[filterKey(key)] = expandedSetting;
}
return telemetryProperties;
}
// When propSchema does not have a type defined (for example at the root scope)
// use the setting type. We use the setting type second because it sees array as object.
switch (jsonType || type) {
// Report numbers and booleans since there is no private information in such types.
case "boolean": /* falls through */
case "number":
if (telemetryProperties) {
telemetryProperties[filterKey(key)] = setting;
}
break;
// Apply allow-lists for strings.
case "string":
if (telemetryProperties) {
telemetryProperties[filterKey(key)] = filterSetting(setting, key, propSchema.default);
}
break;
case "array":
// We are interested in logging arrays of basic types
if (telemetryProperties && propSchema.items.type !== "object" && propSchema.items.type !== "array") {
telemetryProperties[filterKey(key)] = filterSetting(setting, key, propSchema.default);
break;
}
/* falls through */
case "object":
let settingsProps: string[] = Object.getOwnPropertyNames(setting);
let index: number = -1;
let active: number = 0;
if (jsonType === "array") {
active = activeArrayItem(setting, key);
}
settingsProps.forEach(async (prop) => {
index++;
let jsonProps: any;
let newPropObj: any = setting[prop];
if (jsonType === "array") {
jsonProps = propSchema.items.properties || propSchema.items;
} else {
// For a setting like "makefile.name1.name2.name3",
// when we need to query for its schema we should use the whole name as index
// but when we query for the workspace value, we have to use each sub object name:
// setting[name1][name2][name3].
// Otherwise we will not read anything useful about such a setting and we will also
// report a schema mismatch, even if it is written correctly.
let newProp: string = prop;
let newFullProp: string = (key === "makefile") ? key + "." : "";
while (jsonProps === undefined && newProp !== "") {
newFullProp = newFullProp + newProp;
if (propSchema.properties) {
jsonProps = Object.getOwnPropertyNames(propSchema.properties).includes(newFullProp) ?
propSchema.properties[newFullProp] : undefined;
} else {
jsonProps = Object.getOwnPropertyNames(propSchema).includes(newFullProp) ?
propSchema[newFullProp] : undefined;
}
if (jsonProps === undefined && typeof(newPropObj) === "object") {
newProp = Object.getOwnPropertyNames(newPropObj)[0];
newPropObj = newPropObj[newProp];
newProp = "." + newProp;
} else {
newProp = "";
}
}
}
// The user defined a setting property wrong (example miMode instead of MIMode).
// Exceptions are 'has', 'get', 'update' and 'inspect' for the makefile root.
// They are functions and we can use this type to make the exclusion..
if (jsonProps === undefined) {
if (typeof (setting[prop]) !== "function") {
telemetryLogger(`Schema mismatch between settings and package.json for property "${key}.${prop}"`);
}
} else {
// Skip if the analyzed prop is a function or if it's the length of an array.
if (type !== "function" /*&& jsonType !== undefined*/ &&
(jsonType !== "array" || prop !== "length")) {
let newTelemetryProperties: Properties | null = {};
newTelemetryProperties = await analyzeSettings(newPropObj, key + "." + prop, jsonProps, ignoreDefault,
((jsonType !== "array" || index === active)) ? newTelemetryProperties : null);
// If telemetryProperties is null, it means we're not interested in reporting any telemetry for this subtree
if (telemetryProperties) {
telemetryProperties = util.mergeProperties(telemetryProperties, newTelemetryProperties);
}
}
}
});
break;
default:
break;
// Enum values always safe to report.
// Validate the allowed values against the expanded variable.
let enumValues: any[] = propSchema.enum;
if (enumValues && enumValues.length > 0) {
const regexp: RegExp = /(makefile\.)(.+)/gm;
const res: RegExpExecArray | null = regexp.exec(key);
let expandedSetting: string = res
? await util.getExpandedSetting<string>(res[2])
: setting;
if (!enumValues.includes(expandedSetting)) {
telemetryLogger(
`Invalid value "${expandedSetting}" for enum "${key}". Only "${enumValues.join(
";"
)}" values are allowed."`
);
if (telemetryProperties) {
telemetryProperties[filterKey(key)] = "invalid";
}
} else if (telemetryProperties) {
telemetryProperties[filterKey(key)] = expandedSetting;
}
return telemetryProperties;
}
// When propSchema does not have a type defined (for example at the root scope)
// use the setting type. We use the setting type second because it sees array as object.
switch (jsonType || type) {
// Report numbers and booleans since there is no private information in such types.
case "boolean": /* falls through */
case "number":
if (telemetryProperties) {
telemetryProperties[filterKey(key)] = setting;
}
break;
// Apply allow-lists for strings.
case "string":
if (telemetryProperties) {
telemetryProperties[filterKey(key)] = filterSetting(
setting,
key,
propSchema.default
);
}
break;
case "array":
// We are interested in logging arrays of basic types
if (
telemetryProperties &&
propSchema.items.type !== "object" &&
propSchema.items.type !== "array"
) {
telemetryProperties[filterKey(key)] = filterSetting(
setting,
key,
propSchema.default
);
break;
}
/* falls through */
case "object":
let settingsProps: string[] = Object.getOwnPropertyNames(setting);
let index: number = -1;
let active: number = 0;
if (jsonType === "array") {
active = activeArrayItem(setting, key);
}
settingsProps.forEach(async (prop) => {
index++;
let jsonProps: any;
let newPropObj: any = setting[prop];
if (jsonType === "array") {
jsonProps = propSchema.items.properties || propSchema.items;
} else {
// For a setting like "makefile.name1.name2.name3",
// when we need to query for its schema we should use the whole name as index
// but when we query for the workspace value, we have to use each sub object name:
// setting[name1][name2][name3].
// Otherwise we will not read anything useful about such a setting and we will also
// report a schema mismatch, even if it is written correctly.
let newProp: string = prop;
let newFullProp: string = key === "makefile" ? key + "." : "";
while (jsonProps === undefined && newProp !== "") {
newFullProp = newFullProp + newProp;
if (propSchema.properties) {
jsonProps = Object.getOwnPropertyNames(
propSchema.properties
).includes(newFullProp)
? propSchema.properties[newFullProp]
: undefined;
} else {
jsonProps = Object.getOwnPropertyNames(propSchema).includes(
newFullProp
)
? propSchema[newFullProp]
: undefined;
}
if (jsonProps === undefined && typeof newPropObj === "object") {
newProp = Object.getOwnPropertyNames(newPropObj)[0];
newPropObj = newPropObj[newProp];
newProp = "." + newProp;
} else {
newProp = "";
}
}
}
// The user defined a setting property wrong (example miMode instead of MIMode).
// Exceptions are 'has', 'get', 'update' and 'inspect' for the makefile root.
// They are functions and we can use this type to make the exclusion..
if (jsonProps === undefined) {
if (typeof setting[prop] !== "function") {
telemetryLogger(
`Schema mismatch between settings and package.json for property "${key}.${prop}"`
);
}
} else {
// Skip if the analyzed prop is a function or if it's the length of an array.
if (
type !== "function" /*&& jsonType !== undefined*/ &&
(jsonType !== "array" || prop !== "length")
) {
let newTelemetryProperties: Properties | null = {};
newTelemetryProperties = await analyzeSettings(
newPropObj,
key + "." + prop,
jsonProps,
ignoreDefault,
jsonType !== "array" || index === active
? newTelemetryProperties
: null
);
// If telemetryProperties is null, it means we're not interested in reporting any telemetry for this subtree
if (telemetryProperties) {
telemetryProperties = util.mergeProperties(
telemetryProperties,
newTelemetryProperties
);
}
}
}
});
break;
default:
break;
}
return telemetryProperties;
}
function createReporter(): TelemetryReporter | null {
const packageInfo: IPackageInfo = getPackageInfo();
if (packageInfo && packageInfo.aiKey) {
return new TelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
}
return null;
const packageInfo: IPackageInfo = getPackageInfo();
if (packageInfo && packageInfo.aiKey) {
return new TelemetryReporter(
packageInfo.name,
packageInfo.version,
packageInfo.aiKey
);
}
return null;
}
function getPackageInfo(): IPackageInfo {
const packageJSON: util.PackageJSON = util.thisExtensionPackage();
return {
name: `${packageJSON.publisher}.${packageJSON.name}`,
version: packageJSON.version,
aiKey: "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217"
};
const packageJSON: util.PackageJSON = util.thisExtensionPackage();
return {
name: `${packageJSON.publisher}.${packageJSON.name}`,
version: packageJSON.version,
aiKey: "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
};
}

Просмотреть файл

@ -1,7 +1,7 @@
[
{
"command": "MyOwnFakeCompiler -I'd:\\Proj/src/test/fakeSuite/repros/\\'folder with space\\'/subfolder/' '-Id:\\Proj/src/test/fakeSuite/repros/folder' -I'..' -I'd:\\Proj/src/test/fakeSuite/repros/folder/' -I '../folder with space/' \"myfile.cpp\" -I 'd:\\Proj/src/test/fakeSuite/repros/\\\"folder1 with space\\\"/\\`folder2 with space\\`/subfolder/' /std:c++17\r",
"directory": "d:\\Proj\\vscode-makefile-tools\\src\\test\\fakeSuite\\Repros",
"file": "d:\\Proj\\vscode-makefile-tools\\src\\test\\fakeSuite\\Repros\\myfile.cpp"
}
]
{
"command": "MyOwnFakeCompiler -I'd:\\Proj/src/test/fakeSuite/repros/\\'folder with space\\'/subfolder/' '-Id:\\Proj/src/test/fakeSuite/repros/folder' -I'..' -I'd:\\Proj/src/test/fakeSuite/repros/folder/' -I '../folder with space/' \"myfile.cpp\" -I 'd:\\Proj/src/test/fakeSuite/repros/\\\"folder1 with space\\\"/\\`folder2 with space\\`/subfolder/' /std:c++17\r",
"directory": "d:\\Proj\\vscode-makefile-tools\\src\\test\\fakeSuite\\Repros",
"file": "d:\\Proj\\vscode-makefile-tools\\src\\test\\fakeSuite\\Repros\\myfile.cpp"
}
]

Просмотреть файл

@ -1,85 +1,85 @@
{
"C_Cpp.default.configurationProvider": "ms-vscode.makefile-tools",
"makefile.buildLog": "./dummy_dryrun.log",
"makefile.extensionOutputFolder": "./.vscode",
"makefile.extensionLog": "./.vscode/Makefile.out",
"makefile.makePath": "c:/some/other/fake/path",
"makefile.buildBeforeLaunch": false,
"makefile.loggingLevel": "Debug",
"makefile.additionalCompilerNames": ["MyOwnFakeCompiler"],
"makefile.compileCommandsPath": "./.vscode/compile_commands.json",
"makefile.panel.visibility": {
"debug": true
"C_Cpp.default.configurationProvider": "ms-vscode.makefile-tools",
"makefile.buildLog": "./dummy_dryrun.log",
"makefile.extensionOutputFolder": "./.vscode",
"makefile.extensionLog": "./.vscode/Makefile.out",
"makefile.makePath": "c:/some/other/fake/path",
"makefile.buildBeforeLaunch": false,
"makefile.loggingLevel": "Debug",
"makefile.additionalCompilerNames": ["MyOwnFakeCompiler"],
"makefile.compileCommandsPath": "./.vscode/compile_commands.json",
"makefile.panel.visibility": {
"debug": true
},
"makefile.configureOnOpen": false,
"makefile.configureOnEdit": true,
"makefile.configureAfterCommand": true,
"makefile.configurations": [
{
"name": "varexp"
},
"makefile.configureOnOpen": false,
"makefile.configureOnEdit": true,
"makefile.configureAfterCommand": true,
"makefile.configurations": [
{
"name": "varexp",
},
{
"name": "test-make-f",
"makePath": "./doesnt/exist/make",
"buildLog": "./doesnt_exist.log",
"makeArgs": ["-f", "./SubDir/makefile with space"]
},
{
"name": "test-make-C",
"makePath": "./doesnt/exist/make",
"buildLog": "./doesnt_exist.log",
"makeArgs": ["-C", "./SubDir with space/"]
},
{
"name": "complex_escaped_quotes",
"buildLog": "./complex_escaped_quotes_dryrun.log"
},
{
"name": "complex_escaped_quotes_winOnly",
"buildLog": "./complex_escaped_quotes_winOnly_dryrun.log"
},
{
"name": "InterestingSmallMakefile_windows_configDebug",
"buildLog": "./InterestingSmallMakefile_windows_dryrunDebug.log"
},
{
"name": "InterestingSmallMakefile_windows_configRelSize",
"makePath": "make",
"makeArgs": ["OPT=RelSize"],
"buildLog": "./InterestingSmallMakefile_windows_dryrunRelSize.log"
},
{
"name": "InterestingSmallMakefile_windows_configRelSpeed",
"makePath": "c:/fake/path/make.exe",
"makeArgs": ["OPT=RelSpeed"]
},
{
"name": "8cc_linux",
"buildLog": "./8cc_linux_dryrun.log"
},
{
"name": "8cc_mingw",
"buildLog": "./8cc_mingw_dryrun.log"
},
{
"name": "Fido_linux",
"buildLog": "./Fido_linux_dryrun.log"
},
{
"name": "Fido_mingw",
"buildLog": "./Fido_mingw_dryrun.log"
},
{
"name": "tinyvm_linux_pedantic",
"buildLog": "./tinyvm_linux_dryrunPedantic.log",
"makePath": "make",
"makeArgs": ["PEDANTIC=yes"]
},
{
"name": "tinyvm_mingw_pedantic",
"buildLog": "./tinyvm_mingw_dryrunPedantic.log",
"makePath": "make",
"makeArgs": ["PEDANTIC=yes"]
}
]
}
{
"name": "test-make-f",
"makePath": "./doesnt/exist/make",
"buildLog": "./doesnt_exist.log",
"makeArgs": ["-f", "./SubDir/makefile with space"]
},
{
"name": "test-make-C",
"makePath": "./doesnt/exist/make",
"buildLog": "./doesnt_exist.log",
"makeArgs": ["-C", "./SubDir with space/"]
},
{
"name": "complex_escaped_quotes",
"buildLog": "./complex_escaped_quotes_dryrun.log"
},
{
"name": "complex_escaped_quotes_winOnly",
"buildLog": "./complex_escaped_quotes_winOnly_dryrun.log"
},
{
"name": "InterestingSmallMakefile_windows_configDebug",
"buildLog": "./InterestingSmallMakefile_windows_dryrunDebug.log"
},
{
"name": "InterestingSmallMakefile_windows_configRelSize",
"makePath": "make",
"makeArgs": ["OPT=RelSize"],
"buildLog": "./InterestingSmallMakefile_windows_dryrunRelSize.log"
},
{
"name": "InterestingSmallMakefile_windows_configRelSpeed",
"makePath": "c:/fake/path/make.exe",
"makeArgs": ["OPT=RelSpeed"]
},
{
"name": "8cc_linux",
"buildLog": "./8cc_linux_dryrun.log"
},
{
"name": "8cc_mingw",
"buildLog": "./8cc_mingw_dryrun.log"
},
{
"name": "Fido_linux",
"buildLog": "./Fido_linux_dryrun.log"
},
{
"name": "Fido_mingw",
"buildLog": "./Fido_mingw_dryrun.log"
},
{
"name": "tinyvm_linux_pedantic",
"buildLog": "./tinyvm_linux_dryrunPedantic.log",
"makePath": "make",
"makeArgs": ["PEDANTIC=yes"]
},
{
"name": "tinyvm_mingw_pedantic",
"buildLog": "./tinyvm_mingw_dryrunPedantic.log",
"makePath": "make",
"makeArgs": ["PEDANTIC=yes"]
}
]
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -2,42 +2,42 @@
// Licensed under the MIT license.
// index.ts
import * as path from 'path';
import * as Mocha from 'mocha';
import * as glob from 'glob';
import * as path from "path";
import * as Mocha from "mocha";
import * as glob from "glob";
export function run(): Promise<void> {
// Create the mocha test
const mocha : Mocha = new Mocha({
ui: 'tdd',
timeout: 100000000,
color: true
});
// Create the mocha test
const mocha: Mocha = new Mocha({
ui: "tdd",
timeout: 100000000,
color: true,
});
const testsRoot : string = path.resolve(__dirname, '..');
const testsRoot: string = path.resolve(__dirname, "..");
return new Promise((c, e) => {
glob('**/**.test.js', { cwd: testsRoot }, (err, files) => {
if (err) {
return e(err);
}
return new Promise((c, e) => {
glob("**/**.test.js", { cwd: testsRoot }, (err, files) => {
if (err) {
return e(err);
}
// Add files to the test suite
files.forEach(f => mocha.addFile(path.resolve(testsRoot, f)));
// Add files to the test suite
files.forEach((f) => mocha.addFile(path.resolve(testsRoot, f)));
try {
// Run the mocha test
mocha.run(failures => {
if (failures > 0) {
e(new Error(`${failures} tests failed.`));
} else {
c();
}
});
} catch (err) {
console.error(err);
e(err);
}
try {
// Run the mocha test
mocha.run((failures) => {
if (failures > 0) {
e(new Error(`${failures} tests failed.`));
} else {
c();
}
});
} catch (err) {
console.error(err);
e(err);
}
});
});
}

Просмотреть файл

@ -2,44 +2,53 @@
// Licensed under the MIT license.
// Makefile Tools Tests
import * as path from 'path';
import * as path from "path";
//import { runTests } from 'vscode-test';
//import * as tests from 'vscode-test';
import * as testRunner from '@vscode/test-electron/out/runTest';
import * as testRunner from "@vscode/test-electron/out/runTest";
async function main(): Promise<void> {
try {
// The folder containing the Extension Manifest package.json
// Passed to `--extensionDevelopmentPath`
const extensionDevelopmentPath : string = path.resolve(__dirname, '../../../');
try {
// The folder containing the Extension Manifest package.json
// Passed to `--extensionDevelopmentPath`
const extensionDevelopmentPath: string = path.resolve(
__dirname,
"../../../"
);
// The path to the extension test script
// Passed to --extensionTestsPath
const extensionTestsPath : string = path.resolve(__dirname, './fakeSuite/index');
// The path to the extension test script
// Passed to --extensionTestsPath
const extensionTestsPath: string = path.resolve(
__dirname,
"./fakeSuite/index"
);
// The path to the makefile repro (containing the root makefile and .vscode folder)
const reproRootPath : string = path.resolve(extensionDevelopmentPath, "./src/test/fakeSuite/Repros/");
// The path to the makefile repro (containing the root makefile and .vscode folder)
const reproRootPath: string = path.resolve(
extensionDevelopmentPath,
"./src/test/fakeSuite/Repros/"
);
// Download VS Code, unzip it and run the integration test
let myOpt: testRunner.TestOptions = {
extensionDevelopmentPath: extensionDevelopmentPath,
launchArgs: [
"--disable-workspace-trust",
"--disable-extensions",
reproRootPath,
],
extensionTestsPath: extensionTestsPath,
extensionTestsEnv: {
MAKEFILE_TOOLS_TESTING: "1",
WindowsSDKVersion: "12.3.45678.9\\",
},
};
await testRunner.runTests(myOpt);
} catch (err) {
console.error('Failed to run tests');
process.exit(1);
}
// Download VS Code, unzip it and run the integration test
let myOpt: testRunner.TestOptions = {
extensionDevelopmentPath: extensionDevelopmentPath,
launchArgs: [
"--disable-workspace-trust",
"--disable-extensions",
reproRootPath,
],
extensionTestsPath: extensionTestsPath,
extensionTestsEnv: {
MAKEFILE_TOOLS_TESTING: "1",
WindowsSDKVersion: "12.3.45678.9\\",
},
};
await testRunner.runTests(myOpt);
} catch (err) {
console.error("Failed to run tests");
process.exit(1);
}
}
main();

Просмотреть файл

@ -3,377 +3,497 @@
// Tree.ts
import * as configuration from './configuration';
import * as path from 'path';
import * as util from './util';
import * as vscode from 'vscode';
import * as configuration from "./configuration";
import * as path from "path";
import * as util from "./util";
import * as vscode from "vscode";
import * as nls from 'vscode-nls';
import { extension } from './extension';
nls.config({ messageFormat: nls.MessageFormat.bundle, bundleFormat: nls.BundleFormat.standalone })();
import * as nls from "vscode-nls";
import { extension } from "./extension";
nls.config({
messageFormat: nls.MessageFormat.bundle,
bundleFormat: nls.BundleFormat.standalone,
})();
const localize: nls.LocalizeFunc = nls.loadMessageBundle();
interface NamedItem {
name: string;
name: string;
}
abstract class BaseNode {
constructor(public readonly id: string) { }
abstract getTreeItem(): vscode.TreeItem;
abstract getChildren(): BaseNode[];
constructor(public readonly id: string) {}
abstract getTreeItem(): vscode.TreeItem;
abstract getChildren(): BaseNode[];
}
export class BuildTargetNode extends BaseNode {
constructor(targetName: string) {
super(`buildTarget:${targetName}`);
this._name = targetName;
constructor(targetName: string) {
super(`buildTarget:${targetName}`);
this._name = targetName;
}
_name: string;
update(targetName: string): void {
this._name = localize(
"tree.build.target",
"Build target: {0}",
`[${targetName}]`
);
}
getChildren(): BaseNode[] {
return [];
}
getTreeItem(): vscode.TreeItem {
try {
const item: vscode.TreeItem = new vscode.TreeItem(this._name);
item.collapsibleState = vscode.TreeItemCollapsibleState.None;
item.tooltip = localize(
"makefile.target.currently.selected.for.build",
"The makefile target currently selected for build."
);
item.contextValue = [`nodeType=buildTarget`].join(",");
return item;
} catch (e) {
return new vscode.TreeItem(
localize(
"issue.rendering.item",
"{0} (there was an issue rendering this item)",
this._name
)
);
}
_name: string;
update(targetName: string): void {
this._name = localize("tree.build.target", "Build target: {0}", `[${targetName}]`);
}
getChildren(): BaseNode[] {
return [];
}
getTreeItem(): vscode.TreeItem {
try {
const item: vscode.TreeItem = new vscode.TreeItem(this._name);
item.collapsibleState = vscode.TreeItemCollapsibleState.None;
item.tooltip = localize("makefile.target.currently.selected.for.build", "The makefile target currently selected for build.");
item.contextValue = [
`nodeType=buildTarget`,
].join(',');
return item;
} catch (e) {
return new vscode.TreeItem(localize("issue.rendering.item", "{0} (there was an issue rendering this item)", this._name));
}
}
}
}
export class LaunchTargetNode extends BaseNode {
_name: string;
_toolTip: string;
_name: string;
_toolTip: string;
// Keep the tree node label as short as possible.
// The binary path is the most important component of a launch target.
async getShortLaunchTargetName(completeLaunchTargetName: string): Promise<string> {
let launchConfiguration: configuration.LaunchConfiguration | undefined = await configuration.stringToLaunchConfiguration(completeLaunchTargetName);
let shortName: string;
// Keep the tree node label as short as possible.
// The binary path is the most important component of a launch target.
async getShortLaunchTargetName(
completeLaunchTargetName: string
): Promise<string> {
let launchConfiguration: configuration.LaunchConfiguration | undefined =
await configuration.stringToLaunchConfiguration(completeLaunchTargetName);
let shortName: string;
if (!launchConfiguration) {
shortName = "Unset";
} else {
if (vscode.workspace.workspaceFolders) {
// In a complete launch target string, the binary path is relative to cwd.
// In here, since we don't show cwd, make it relative to current workspace folder.
shortName = util.makeRelPath(launchConfiguration.binaryPath, vscode.workspace.workspaceFolders[0].uri.fsPath);
} else {
// Just in case, if for some reason we don't have a workspace folder, return full binary path.
shortName = launchConfiguration.binaryPath;
}
}
return localize("tree.launch.target", "Launch target: {0}", `[${shortName}]`);
if (!launchConfiguration) {
shortName = "Unset";
} else {
if (vscode.workspace.workspaceFolders) {
// In a complete launch target string, the binary path is relative to cwd.
// In here, since we don't show cwd, make it relative to current workspace folder.
shortName = util.makeRelPath(
launchConfiguration.binaryPath,
vscode.workspace.workspaceFolders[0].uri.fsPath
);
} else {
// Just in case, if for some reason we don't have a workspace folder, return full binary path.
shortName = launchConfiguration.binaryPath;
}
}
constructor(targetName: string) {
super(`launchTarget:${targetName}`);
return localize(
"tree.launch.target",
"Launch target: {0}",
`[${shortName}]`
);
}
// Show the complete launch target name as tooltip and the short name as label
this._name = targetName;
this._toolTip = targetName;
constructor(targetName: string) {
super(`launchTarget:${targetName}`);
// Show the complete launch target name as tooltip and the short name as label
this._name = targetName;
this._toolTip = targetName;
}
async update(targetName: string): Promise<void> {
// Show the complete launch target name as tooltip and the short name as label
this._name = await this.getShortLaunchTargetName(targetName);
this._toolTip = targetName;
}
getChildren(): BaseNode[] {
return [];
}
getTreeItem(): vscode.TreeItem {
try {
const item: vscode.TreeItem = new vscode.TreeItem(this._name);
item.collapsibleState = vscode.TreeItemCollapsibleState.None;
item.tooltip = localize(
"launch.target.currently.selected.for.debug.run.in.terminal",
"The launch target currently selected for debug and run in terminal.\n{0}",
this._toolTip
);
// enablement in makefile.outline.setLaunchConfiguration is not
// disabling this TreeItem
item.command = {
command: "makefile.outline.setLaunchConfiguration",
title: "%makefile-tools.command.makefile.setLaunchConfiguration.title%",
};
item.contextValue = [`nodeType=launchTarget`].join(",");
return item;
} catch (e) {
return new vscode.TreeItem(
localize(
"issue.rendering.item",
"{0} (there was an issue rendering this item)",
this._name
)
);
}
async update(targetName: string): Promise<void> {
// Show the complete launch target name as tooltip and the short name as label
this._name = await this.getShortLaunchTargetName(targetName);
this._toolTip = targetName;
}
getChildren(): BaseNode[] {
return [];
}
getTreeItem(): vscode.TreeItem {
try {
const item: vscode.TreeItem = new vscode.TreeItem(this._name);
item.collapsibleState = vscode.TreeItemCollapsibleState.None;
item.tooltip = localize("launch.target.currently.selected.for.debug.run.in.terminal",
"The launch target currently selected for debug and run in terminal.\n{0}", this._toolTip);
// enablement in makefile.outline.setLaunchConfiguration is not
// disabling this TreeItem
item.command = {
command: "makefile.outline.setLaunchConfiguration",
title: "%makefile-tools.command.makefile.setLaunchConfiguration.title%"
};
item.contextValue = [
`nodeType=launchTarget`,
].join(',');
return item;
} catch (e) {
return new vscode.TreeItem(localize("issue.rendering.item", "{0} (there was an issue rendering this item)", this._name));
}
}
}
}
export class ConfigurationNode extends BaseNode {
constructor(configurationName: string) {
super(`configuration:${configurationName}`);
this._name = configurationName;
constructor(configurationName: string) {
super(`configuration:${configurationName}`);
this._name = configurationName;
}
_name: string;
update(configurationName: string): void {
this._name = localize(
"tree.configuration",
"Configuration: {0}",
`[${configurationName}]`
);
}
getChildren(): BaseNode[] {
return [];
}
getTreeItem(): vscode.TreeItem {
try {
const item: vscode.TreeItem = new vscode.TreeItem(this._name);
item.collapsibleState = vscode.TreeItemCollapsibleState.None;
item.tooltip =
"The makefile configuration currently selected from settings ('makefile.configurations').";
item.contextValue = [`nodeType=configuration`].join(",");
return item;
} catch (e) {
return new vscode.TreeItem(
localize(
"issue.rendering.item",
"{0} (there was an issue rendering this item)",
this._name
)
);
}
_name: string;
update(configurationName: string): void {
this._name = localize("tree.configuration", "Configuration: {0}", `[${configurationName}]`);
}
getChildren(): BaseNode[] {
return [];
}
getTreeItem(): vscode.TreeItem {
try {
const item: vscode.TreeItem = new vscode.TreeItem(this._name);
item.collapsibleState = vscode.TreeItemCollapsibleState.None;
item.tooltip = "The makefile configuration currently selected from settings ('makefile.configurations').";
item.contextValue = [
`nodeType=configuration`,
].join(',');
return item;
} catch (e) {
return new vscode.TreeItem(localize("issue.rendering.item", "{0} (there was an issue rendering this item)", this._name));
}
}
}
}
export class MakefilePathInfoNode extends BaseNode {
constructor(pathInSettings: string, pathDisplayed: string) {
super(pathDisplayed);
this._title = pathDisplayed;
this._tooltip = pathInSettings;
}
constructor(pathInSettings: string, pathDisplayed: string) {
super(pathDisplayed);
this._title = pathDisplayed;
this._tooltip = pathInSettings;
}
_title: string;
_tooltip: string;
_title: string;
_tooltip: string;
update(pathInSettings: string, pathDisplayed: string): void {
this._title = localize("tree.makefile.path.info", "{0}", `${pathDisplayed}`);
this._tooltip = pathInSettings;
}
update(pathInSettings: string, pathDisplayed: string): void {
this._title = localize(
"tree.makefile.path.info",
"{0}",
`${pathDisplayed}`
);
this._tooltip = pathInSettings;
}
getChildren(): BaseNode[] {
return [];
}
getChildren(): BaseNode[] {
return [];
}
getTreeItem(): vscode.TreeItem {
try {
const item: vscode.TreeItem = new vscode.TreeItem(this._title);
item.collapsibleState = vscode.TreeItemCollapsibleState.None;
item.tooltip = this._tooltip;
item.contextValue = [
`nodeType=makefilePathInfo`,
].join(',');
return item;
} catch (e) {
return new vscode.TreeItem(localize("issue.rendering.item", "{0} (there was an issue rendering this item)", this._title));
}
}
getTreeItem(): vscode.TreeItem {
try {
const item: vscode.TreeItem = new vscode.TreeItem(this._title);
item.collapsibleState = vscode.TreeItemCollapsibleState.None;
item.tooltip = this._tooltip;
item.contextValue = [`nodeType=makefilePathInfo`].join(",");
return item;
} catch (e) {
return new vscode.TreeItem(
localize(
"issue.rendering.item",
"{0} (there was an issue rendering this item)",
this._title
)
);
}
}
}
export class MakePathInfoNode extends BaseNode {
constructor(pathInSettings: string, pathDisplayed: string) {
super(pathDisplayed);
this._title = pathDisplayed;
this._tooltip = pathInSettings;
}
constructor(pathInSettings: string, pathDisplayed: string) {
super(pathDisplayed);
this._title = pathDisplayed;
this._tooltip = pathInSettings;
}
_title: string;
_tooltip: string;
_title: string;
_tooltip: string;
update(pathInSettings: string, pathDisplayed: string): void {
this._title = localize("tree.make.path.info", "{0}", `${pathDisplayed}`);
this._tooltip = pathInSettings;
}
update(pathInSettings: string, pathDisplayed: string): void {
this._title = localize("tree.make.path.info", "{0}", `${pathDisplayed}`);
this._tooltip = pathInSettings;
}
getChildren(): BaseNode[] {
return [];
}
getChildren(): BaseNode[] {
return [];
}
getTreeItem(): vscode.TreeItem {
try {
const item: vscode.TreeItem = new vscode.TreeItem(this._title);
item.collapsibleState = vscode.TreeItemCollapsibleState.None;
item.tooltip = this._tooltip;
item.contextValue = [
`nodeType=makePathInfo`,
].join(',');
return item;
} catch (e) {
return new vscode.TreeItem(localize("issue.rendering.item", "{0} (there was an issue rendering this item)", this._title));
}
}
getTreeItem(): vscode.TreeItem {
try {
const item: vscode.TreeItem = new vscode.TreeItem(this._title);
item.collapsibleState = vscode.TreeItemCollapsibleState.None;
item.tooltip = this._tooltip;
item.contextValue = [`nodeType=makePathInfo`].join(",");
return item;
} catch (e) {
return new vscode.TreeItem(
localize(
"issue.rendering.item",
"{0} (there was an issue rendering this item)",
this._title
)
);
}
}
}
export class BuildLogPathInfoNode extends BaseNode {
constructor(pathInSettings: string, pathDisplayed: string) {
super(pathDisplayed);
this._title = pathDisplayed;
this._tooltip = pathInSettings;
}
constructor(pathInSettings: string, pathDisplayed: string) {
super(pathDisplayed);
this._title = pathDisplayed;
this._tooltip = pathInSettings;
}
_title: string;
_tooltip: string;
_title: string;
_tooltip: string;
update(pathInSettings: string, pathDisplayed: string): void {
this._title = localize("tree.build.log.path.info", "{0}", `${pathDisplayed}`);
this._tooltip = pathInSettings;
}
update(pathInSettings: string, pathDisplayed: string): void {
this._title = localize(
"tree.build.log.path.info",
"{0}",
`${pathDisplayed}`
);
this._tooltip = pathInSettings;
}
getChildren(): BaseNode[] {
return [];
}
getChildren(): BaseNode[] {
return [];
}
getTreeItem(): vscode.TreeItem {
try {
const item: vscode.TreeItem = new vscode.TreeItem(this._title);
item.collapsibleState = vscode.TreeItemCollapsibleState.None;
item.tooltip = this._tooltip;
item.contextValue = [
`nodeType=buildLogPathInfo`,
].join(',');
return item;
} catch (e) {
return new vscode.TreeItem(localize("issue.rendering.item", "{0} (there was an issue rendering this item)", this._title));
}
}
getTreeItem(): vscode.TreeItem {
try {
const item: vscode.TreeItem = new vscode.TreeItem(this._title);
item.collapsibleState = vscode.TreeItemCollapsibleState.None;
item.tooltip = this._tooltip;
item.contextValue = [`nodeType=buildLogPathInfo`].join(",");
return item;
} catch (e) {
return new vscode.TreeItem(
localize(
"issue.rendering.item",
"{0} (there was an issue rendering this item)",
this._title
)
);
}
}
}
export class ProjectOutlineProvider implements vscode.TreeDataProvider<BaseNode> {
private readonly _changeEvent = new vscode.EventEmitter<BaseNode | null>();
private readonly _unsetString = localize("Unset", "Unset");
export class ProjectOutlineProvider
implements vscode.TreeDataProvider<BaseNode>
{
private readonly _changeEvent = new vscode.EventEmitter<BaseNode | null>();
private readonly _unsetString = localize("Unset", "Unset");
constructor() {
this._currentConfigurationItem = new ConfigurationNode(this._unsetString);
this._currentBuildTargetItem = new BuildTargetNode(this._unsetString);
this._currentLaunchTargetItem = new LaunchTargetNode(this._unsetString);
this._currentMakefilePathInfoItem = new MakefilePathInfoNode(this._unsetString, "");
this._currentMakePathInfoItem = new MakePathInfoNode(this._unsetString, "");
this._currentBuildLogPathInfoItem = new BuildLogPathInfoNode(this._unsetString, "");
constructor() {
this._currentConfigurationItem = new ConfigurationNode(this._unsetString);
this._currentBuildTargetItem = new BuildTargetNode(this._unsetString);
this._currentLaunchTargetItem = new LaunchTargetNode(this._unsetString);
this._currentMakefilePathInfoItem = new MakefilePathInfoNode(
this._unsetString,
""
);
this._currentMakePathInfoItem = new MakePathInfoNode(this._unsetString, "");
this._currentBuildLogPathInfoItem = new BuildLogPathInfoNode(
this._unsetString,
""
);
}
private _currentConfigurationItem: ConfigurationNode;
private _currentBuildTargetItem: BuildTargetNode;
private _currentLaunchTargetItem: LaunchTargetNode;
private _currentMakefilePathInfoItem: MakefilePathInfoNode;
private _currentMakePathInfoItem: MakePathInfoNode;
private _currentBuildLogPathInfoItem: BuildLogPathInfoNode;
get onDidChangeTreeData(): any {
return this._changeEvent.event;
}
async getTreeItem(node: BaseNode): Promise<vscode.TreeItem> {
return node.getTreeItem();
}
getChildren(node?: BaseNode): BaseNode[] {
if (node) {
return node.getChildren();
}
if (
configuration.isOptionalFeatureEnabled("debug") ||
configuration.isOptionalFeatureEnabled("run")
) {
return [
this._currentConfigurationItem,
this._currentBuildTargetItem,
this._currentLaunchTargetItem,
this._currentMakefilePathInfoItem,
this._currentMakePathInfoItem,
this._currentBuildLogPathInfoItem,
];
} else {
return [
this._currentConfigurationItem,
this._currentBuildTargetItem,
this._currentMakefilePathInfoItem,
this._currentMakePathInfoItem,
this._currentBuildLogPathInfoItem,
];
}
}
pathDisplayed(
pathInSettings: string | undefined,
kind: string,
searchInPath: boolean,
makeRelative: boolean
): string {
if (!pathInSettings) {
if (kind === "Build Log") {
extension.updateBuildLogPresent(false);
} else if (kind === "Makefile") {
extension.updateMakefileFilePresent(false);
}
return `${kind}: [Unset]`;
}
private _currentConfigurationItem: ConfigurationNode;
private _currentBuildTargetItem: BuildTargetNode;
private _currentLaunchTargetItem: LaunchTargetNode;
private _currentMakefilePathInfoItem: MakefilePathInfoNode;
private _currentMakePathInfoItem: MakePathInfoNode;
private _currentBuildLogPathInfoItem: BuildLogPathInfoNode;
const pathInSettingsToTest: string | undefined =
process.platform === "win32" &&
!pathInSettings?.endsWith(".exe") &&
kind === "Make"
? pathInSettings?.concat(".exe")
: pathInSettings;
const pathBase: string | undefined =
searchInPath && path.parse(pathInSettingsToTest).dir === ""
? path.parse(pathInSettingsToTest).base
: undefined;
const pathInEnv: string | undefined = pathBase
? path.join(util.toolPathInEnv(pathBase) || "", pathBase)
: undefined;
const finalPath: string = pathInEnv || pathInSettingsToTest;
const checkFileExists = util.checkFileExistsSync(finalPath);
get onDidChangeTreeData(): any {
return this._changeEvent.event;
}
async getTreeItem(node: BaseNode): Promise<vscode.TreeItem> {
return node.getTreeItem();
}
getChildren(node?: BaseNode): BaseNode[] {
if (node) {
return node.getChildren();
}
if (configuration.isOptionalFeatureEnabled("debug") || configuration.isOptionalFeatureEnabled("run")) {
return [this._currentConfigurationItem,
this._currentBuildTargetItem,
this._currentLaunchTargetItem,
this._currentMakefilePathInfoItem,
this._currentMakePathInfoItem,
this._currentBuildLogPathInfoItem];
} else {
return [this._currentConfigurationItem,
this._currentBuildTargetItem,
this._currentMakefilePathInfoItem,
this._currentMakePathInfoItem,
this._currentBuildLogPathInfoItem];
}
}
pathDisplayed(pathInSettings: string | undefined, kind: string, searchInPath: boolean, makeRelative: boolean): string {
if (!pathInSettings) {
if (kind === "Build Log") {
extension.updateBuildLogPresent(false);
} else if (kind === "Makefile") {
extension.updateMakefileFilePresent(false);
}
return `${kind}: [Unset]`;
}
const pathInSettingsToTest: string | undefined = process.platform === "win32" && !pathInSettings?.endsWith(".exe") && kind === "Make" ? pathInSettings?.concat(".exe") : pathInSettings;
const pathBase: string | undefined = (searchInPath && path.parse(pathInSettingsToTest).dir === "") ? path.parse(pathInSettingsToTest).base : undefined;
const pathInEnv: string | undefined = pathBase ? (path.join(util.toolPathInEnv(pathBase) || "", pathBase)) : undefined;
const finalPath: string = pathInEnv || pathInSettingsToTest;
const checkFileExists = util.checkFileExistsSync(finalPath);
if (kind === "Build Log") {
extension.updateBuildLogPresent(checkFileExists);
} else if (kind === "Makefile") {
extension.updateMakefileFilePresent(checkFileExists);
}
return (!checkFileExists ? `${kind} (not found)` : `${kind}`) + `: [${makeRelative ? util.makeRelPath(finalPath, util.getWorkspaceRoot()) : finalPath}]`;
if (kind === "Build Log") {
extension.updateBuildLogPresent(checkFileExists);
} else if (kind === "Makefile") {
extension.updateMakefileFilePresent(checkFileExists);
}
async update(configuration: string | undefined,
buildTarget: string | undefined,
launchTarget: string | undefined,
makefilePathInfo: string | undefined,
makePathInfo: string | undefined,
buildLogInfo: string | undefined): Promise<void> {
this._currentConfigurationItem.update(configuration || this._unsetString);
this._currentBuildTargetItem.update(buildTarget || this._unsetString);
await this._currentLaunchTargetItem.update(launchTarget || this._unsetString);
this._currentMakefilePathInfoItem.update(makefilePathInfo || this._unsetString, this.pathDisplayed(makefilePathInfo, "Makefile", false, false));
this._currentMakePathInfoItem.update(makePathInfo || this._unsetString, this.pathDisplayed(makePathInfo, "Make", true, false));
this._currentBuildLogPathInfoItem.update(buildLogInfo || this._unsetString, this.pathDisplayed(buildLogInfo, "Build Log", false, false));
return (
(!checkFileExists ? `${kind} (not found)` : `${kind}`) +
`: [${
makeRelative
? util.makeRelPath(finalPath, util.getWorkspaceRoot())
: finalPath
}]`
);
}
this.updateTree();
}
async update(
configuration: string | undefined,
buildTarget: string | undefined,
launchTarget: string | undefined,
makefilePathInfo: string | undefined,
makePathInfo: string | undefined,
buildLogInfo: string | undefined
): Promise<void> {
this._currentConfigurationItem.update(configuration || this._unsetString);
this._currentBuildTargetItem.update(buildTarget || this._unsetString);
await this._currentLaunchTargetItem.update(
launchTarget || this._unsetString
);
this._currentMakefilePathInfoItem.update(
makefilePathInfo || this._unsetString,
this.pathDisplayed(makefilePathInfo, "Makefile", false, false)
);
this._currentMakePathInfoItem.update(
makePathInfo || this._unsetString,
this.pathDisplayed(makePathInfo, "Make", true, false)
);
this._currentBuildLogPathInfoItem.update(
buildLogInfo || this._unsetString,
this.pathDisplayed(buildLogInfo, "Build Log", false, false)
);
updateConfiguration(configuration: string): void {
this._currentConfigurationItem.update(configuration);
this.updateTree();
}
this.updateTree();
}
updateBuildTarget(buildTarget: string): void {
this._currentBuildTargetItem.update(buildTarget);
this.updateTree();
}
updateConfiguration(configuration: string): void {
this._currentConfigurationItem.update(configuration);
this.updateTree();
}
async updateLaunchTarget(launchTarget: string): Promise<void> {
await this._currentLaunchTargetItem.update(launchTarget);
this.updateTree();
}
updateBuildTarget(buildTarget: string): void {
this._currentBuildTargetItem.update(buildTarget);
this.updateTree();
}
async updateMakefilePathInfo(makefilePathInfo: string | undefined): Promise<void> {
this._currentMakefilePathInfoItem.update(makefilePathInfo || this._unsetString, this.pathDisplayed(makefilePathInfo, "Makefile", false, true));
this.updateTree();
}
async updateLaunchTarget(launchTarget: string): Promise<void> {
await this._currentLaunchTargetItem.update(launchTarget);
this.updateTree();
}
async updateMakePathInfo(makePathInfo: string | undefined): Promise<void> {
this._currentMakePathInfoItem.update(makePathInfo || this._unsetString, this.pathDisplayed(makePathInfo, "Make", true, false));
this.updateTree();
}
async updateMakefilePathInfo(
makefilePathInfo: string | undefined
): Promise<void> {
this._currentMakefilePathInfoItem.update(
makefilePathInfo || this._unsetString,
this.pathDisplayed(makefilePathInfo, "Makefile", false, true)
);
this.updateTree();
}
async updateBuildLogPathInfo(buildLogPathInfo: string | undefined): Promise<void> {
this._currentBuildLogPathInfoItem.update(buildLogPathInfo || this._unsetString, this.pathDisplayed(buildLogPathInfo, "Build Log", false, true));
this.updateTree();
}
async updateMakePathInfo(makePathInfo: string | undefined): Promise<void> {
this._currentMakePathInfoItem.update(
makePathInfo || this._unsetString,
this.pathDisplayed(makePathInfo, "Make", true, false)
);
this.updateTree();
}
updateTree(): void {
this._changeEvent.fire(null);
}
async updateBuildLogPathInfo(
buildLogPathInfo: string | undefined
): Promise<void> {
this._currentBuildLogPathInfoItem.update(
buildLogPathInfo || this._unsetString,
this.pathDisplayed(buildLogPathInfo, "Build Log", false, true)
);
this.updateTree();
}
updateTree(): void {
this._changeEvent.fire(null);
}
}

153
src/ui.ts
Просмотреть файл

@ -5,86 +5,109 @@
// Replaced by makefile.outline view in the left side bar.
// To be removed, hidden for now.
import * as vscode from 'vscode';
import * as vscode from "vscode";
let ui: UI;
export class UI {
private configurationButton: vscode.StatusBarItem;
private targetButton: vscode.StatusBarItem;
private launchConfigurationButton: vscode.StatusBarItem;
private buildButton: vscode.StatusBarItem;
private debugButton: vscode.StatusBarItem;
private runButton: vscode.StatusBarItem;
private configurationButton: vscode.StatusBarItem;
private targetButton: vscode.StatusBarItem;
private launchConfigurationButton: vscode.StatusBarItem;
private buildButton: vscode.StatusBarItem;
private debugButton: vscode.StatusBarItem;
private runButton: vscode.StatusBarItem;
public setConfiguration(configuration: string): void {
this.configurationButton.text = "$(settings) Build configuration: " + configuration;
public setConfiguration(configuration: string): void {
this.configurationButton.text =
"$(settings) Build configuration: " + configuration;
}
public setTarget(target: string): void {
this.targetButton.text = "$(tag) Target to build: " + target;
}
public setLaunchConfiguration(
launchConfigurationStr: string | undefined
): void {
if (launchConfigurationStr) {
this.launchConfigurationButton.text = "$(rocket) Launch configuration: ";
this.launchConfigurationButton.text += "[";
this.launchConfigurationButton.text += launchConfigurationStr;
this.launchConfigurationButton.text += "]";
} else {
this.launchConfigurationButton.text = "No launch configuration set";
}
}
public setTarget(target: string): void {
this.targetButton.text = "$(tag) Target to build: " + target;
}
public constructor() {
this.configurationButton = vscode.window.createStatusBarItem(
vscode.StatusBarAlignment.Left,
4.6
);
this.configurationButton.command = "makefile.setBuildConfiguration";
this.configurationButton.tooltip =
"Click to select the workspace make configuration";
this.configurationButton.hide();
public setLaunchConfiguration(launchConfigurationStr: string | undefined): void {
if (launchConfigurationStr) {
this.launchConfigurationButton.text = "$(rocket) Launch configuration: ";
this.launchConfigurationButton.text += "[";
this.launchConfigurationButton.text += launchConfigurationStr;
this.launchConfigurationButton.text += "]";
} else {
this.launchConfigurationButton.text = "No launch configuration set";
}
}
this.targetButton = vscode.window.createStatusBarItem(
vscode.StatusBarAlignment.Left,
4.5
);
this.targetButton.command = "makefile.setBuildTarget";
this.targetButton.tooltip = "Click to select the target to be run by make";
this.targetButton.hide();
public constructor() {
this.configurationButton = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 4.6);
this.configurationButton.command = "makefile.setBuildConfiguration";
this.configurationButton.tooltip = "Click to select the workspace make configuration";
this.configurationButton.hide();
this.buildButton = vscode.window.createStatusBarItem(
vscode.StatusBarAlignment.Left,
4.4
);
this.buildButton.command = "makefile.buildTarget";
this.buildButton.tooltip = "Click to build the selected target";
this.buildButton.text = "$(gear) Build";
this.buildButton.hide();
this.targetButton = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 4.5);
this.targetButton.command = "makefile.setBuildTarget";
this.targetButton.tooltip = "Click to select the target to be run by make";
this.targetButton.hide();
this.launchConfigurationButton = vscode.window.createStatusBarItem(
vscode.StatusBarAlignment.Left,
4.3
);
this.launchConfigurationButton.command = "makefile.setLaunchConfiguration";
this.launchConfigurationButton.tooltip =
"Click to select the make launch configuration (binary, args and current path)";
this.launchConfigurationButton.hide();
this.buildButton = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 4.4);
this.buildButton.command = "makefile.buildTarget";
this.buildButton.tooltip = "Click to build the selected target";
this.buildButton.text = "$(gear) Build";
this.buildButton.hide();
this.debugButton = vscode.window.createStatusBarItem(
vscode.StatusBarAlignment.Left,
4.2
);
this.debugButton.command = "makefile.launchDebug";
this.debugButton.tooltip = "Click to debug the selected executable";
this.debugButton.text = "$(bug) Debug";
this.debugButton.hide();
this.launchConfigurationButton = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 4.3);
this.launchConfigurationButton.command = "makefile.setLaunchConfiguration";
this.launchConfigurationButton.tooltip = "Click to select the make launch configuration (binary, args and current path)";
this.launchConfigurationButton.hide();
this.runButton = vscode.window.createStatusBarItem(
vscode.StatusBarAlignment.Left,
4.1
);
this.runButton.command = "makefile.launchRun";
this.runButton.tooltip = "Click to launch the selected executable";
this.runButton.text = "$(terminal) Run";
this.runButton.hide();
}
this.debugButton = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 4.2);
this.debugButton.command = "makefile.launchDebug";
this.debugButton.tooltip = "Click to debug the selected executable";
this.debugButton.text = "$(bug) Debug";
this.debugButton.hide();
this.runButton = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left, 4.1);
this.runButton.command = "makefile.launchRun";
this.runButton.tooltip = "Click to launch the selected executable";
this.runButton.text = "$(terminal) Run";
this.runButton.hide();
}
public dispose(): void {
this.configurationButton.dispose();
this.targetButton.dispose();
this.launchConfigurationButton.dispose();
this.buildButton.dispose();
this.debugButton.dispose();
this.runButton.dispose();
}
public dispose(): void {
this.configurationButton.dispose();
this.targetButton.dispose();
this.launchConfigurationButton.dispose();
this.buildButton.dispose();
this.debugButton.dispose();
this.runButton.dispose();
}
}
export function getUI(): UI {
if (ui === undefined) {
ui = new UI();
}
if (ui === undefined) {
ui = new UI();
}
return ui;
return ui;
}

Разница между файлами не показана из-за своего большого размера Загрузить разницу

Просмотреть файл

@ -1,15 +1,15 @@
'use strict'
"use strict";
const fs = require("fs-extra");
const cp = require("child_process");
const Octokit = require('@octokit/rest')
const path = require('path');
const parseGitConfig = require('parse-git-config');
const Octokit = require("@octokit/rest");
const path = require("path");
const parseGitConfig = require("parse-git-config");
const branchName = 'localization';
const mergeTo = 'main';
const commitComment = 'Localization - Translated Strings';
const pullRequestTitle = '[Auto] Localization - Translated Strings';
const branchName = "localization";
const mergeTo = "main";
const commitComment = "Localization - Translated Strings";
const pullRequestTitle = "[Auto] Localization - Translated Strings";
let repoOwner = process.argv[2];
let repoName = process.argv[3];
@ -20,17 +20,44 @@ let userEmail = process.argv[7];
let locRootPath = process.argv[8];
let locSubPath = process.argv[9];
if (!repoOwner || !repoName || !authUser || !authToken || !userFullName || !userEmail || !locRootPath || !locSubPath) {
console.error(`ERROR: Usage: ${path.parse(process.argv[0]).base} ${path.parse(process.argv[1]).base} repo_owner repo_name auth_token user_full_name user_email loc_root_path loc_sub_path`);
console.error(` repo_owner - The owner of the repo on GitHub. i.e. microsoft`);
console.error(` repo_name - The name of the repo on GitHub. i.e. vscode-makefile-tools`);
console.error(` auth_user - User account wiith permission to post a pull request against the GitHub repo.`);
console.error(` auth_token - A PAT associated with auth_user.`);
console.error(` user_full_name - A full name to associate with a git commit. (This is replaced by the PR account if commit is squashed.)`);
console.error(` user_email - An email to associate with a git commit. (This is replaced by the PR account if commit is squashed.)`);
console.error(` loc_root_path - The path to the folder with language-specific directories (containing localized xlf files).`);
console.error(` loc_sub_path - A sub-path after the language-specific directory, where the xlf to import is located. This should not include the name of the xlf file to import.)`);
return;
if (
!repoOwner ||
!repoName ||
!authUser ||
!authToken ||
!userFullName ||
!userEmail ||
!locRootPath ||
!locSubPath
) {
console.error(
`ERROR: Usage: ${path.parse(process.argv[0]).base} ${
path.parse(process.argv[1]).base
} repo_owner repo_name auth_token user_full_name user_email loc_root_path loc_sub_path`
);
console.error(
` repo_owner - The owner of the repo on GitHub. i.e. microsoft`
);
console.error(
` repo_name - The name of the repo on GitHub. i.e. vscode-makefile-tools`
);
console.error(
` auth_user - User account wiith permission to post a pull request against the GitHub repo.`
);
console.error(` auth_token - A PAT associated with auth_user.`);
console.error(
` user_full_name - A full name to associate with a git commit. (This is replaced by the PR account if commit is squashed.)`
);
console.error(
` user_email - An email to associate with a git commit. (This is replaced by the PR account if commit is squashed.)`
);
console.error(
` loc_root_path - The path to the folder with language-specific directories (containing localized xlf files).`
);
console.error(
` loc_sub_path - A sub-path after the language-specific directory, where the xlf to import is located. This should not include the name of the xlf file to import.)`
);
return;
}
console.log(`repoOwner=${repoOwner}`);
@ -42,86 +69,112 @@ console.log(`locRootPath=${locRootPath}`);
console.log(`locSubPath=${locSubPath}`);
function hasBranch(branchName) {
console.log(`Checking for existence of branch "${branchName}" (git branch --list ${branchName})`);
let output = cp.execSync(`git branch --list ${branchName}`);
let lines = output.toString().split("\n");
let found = false;
lines.forEach(line => {
found = found || (line === ` ${branchName}`);
});
console.log(
`Checking for existence of branch "${branchName}" (git branch --list ${branchName})`
);
let output = cp.execSync(`git branch --list ${branchName}`);
let lines = output.toString().split("\n");
let found = false;
lines.forEach((line) => {
found = found || line === ` ${branchName}`;
});
return found;
return found;
}
function hasAnyChanges() {
console.log("Checking if any files have changed (git status --porcelain)");
let output = cp.execSync('git status --porcelain');
let lines = output.toString().split("\n");
let anyChanges = false;
lines.forEach(line => {
if (line != '') {
console.log("Change detected: " + line);
anyChanges = true;
}
});
console.log("Checking if any files have changed (git status --porcelain)");
let output = cp.execSync("git status --porcelain");
let lines = output.toString().split("\n");
let anyChanges = false;
lines.forEach((line) => {
if (line != "") {
console.log("Change detected: " + line);
anyChanges = true;
}
});
return anyChanges;
return anyChanges;
}
// When invoked on build server, we should already be in a repo freshly synced to the mergeTo branch
if (hasAnyChanges()) {
console.log(`Changes already present in this repo! This script is intended to be run against a freshly synced ${mergeTo} branch!`);
return;
console.log(
`Changes already present in this repo! This script is intended to be run against a freshly synced ${mergeTo} branch!`
);
return;
}
function sleep(ms) {
var unixtime_ms = new Date().getTime();
while(new Date().getTime() < unixtime_ms + ms) {}
var unixtime_ms = new Date().getTime();
while (new Date().getTime() < unixtime_ms + ms) {}
}
console.log("This script is potentially DESTRUCTIVE! Cancel now, or it will proceed in 10 seconds.");
console.log(
"This script is potentially DESTRUCTIVE! Cancel now, or it will proceed in 10 seconds."
);
sleep(10000);
let directories = [ "cs", "de", "es", "fr", "it", "ja", "ko", "pl", "pt-BR", "ru", "tr", "zh-Hans", "zh-Hant" ];
directories.forEach(languageId => {
let sourcePath = `${locRootPath}\\${languageId}\\${locSubPath}\\${repoName}.${languageId}.xlf`;
let destinationPath = `./vscode-translations-import/${languageId}/vscode-extensions/${repoName}.xlf`;
console.log(`Copying "${sourcePath}" to "${destinationPath}"`);
fs.copySync(sourcePath, destinationPath);
let directories = [
"cs",
"de",
"es",
"fr",
"it",
"ja",
"ko",
"pl",
"pt-BR",
"ru",
"tr",
"zh-Hans",
"zh-Hant",
];
directories.forEach((languageId) => {
let sourcePath = `${locRootPath}\\${languageId}\\${locSubPath}\\${repoName}.${languageId}.xlf`;
let destinationPath = `./vscode-translations-import/${languageId}/vscode-extensions/${repoName}.xlf`;
console.log(`Copying "${sourcePath}" to "${destinationPath}"`);
fs.copySync(sourcePath, destinationPath);
});
console.log("Import translations into i18n directory");
cp.execSync("npm run translations-import");
if (!hasAnyChanges()) {
console.log("No changes detected");
return;
console.log("No changes detected");
return;
}
console.log("Changes detected");
console.log(`Ensure main ref is up to date locally (git fetch)`);
cp.execSync('git fetch');
cp.execSync("git fetch");
// Remove old localization branch, if any
if (hasBranch("localization")) {
console.log(`Remove old localization branch, if any (git branch -D localization)`);
cp.execSync('git branch -D localization');
console.log(
`Remove old localization branch, if any (git branch -D localization)`
);
cp.execSync("git branch -D localization");
}
// Check out local branch
console.log(`Creating local branch for changes (git checkout -b ${branchName})`);
cp.execSync('git checkout -b localization');
console.log(
`Creating local branch for changes (git checkout -b ${branchName})`
);
cp.execSync("git checkout -b localization");
// Add changed files.
console.log("Adding changed file (git add .)");
cp.execSync('git add .');
cp.execSync("git add .");
// git add may have resolves CR/LF's and there may not be anything to commit
if (!hasAnyChanges()) {
console.log("No changes detected. The only changes must have been due to CR/LF's, and have been corrected.");
return;
console.log(
"No changes detected. The only changes must have been due to CR/LF's, and have been corrected."
);
return;
}
// Set up user and permissions
@ -129,24 +182,24 @@ if (!hasAnyChanges()) {
// Save existing user name and email, in case already set.
var existingUserName;
var existingUserEmail;
var gitConfigPath = path.resolve(process.cwd(), './.git/config');
var gitConfigPath = path.resolve(process.cwd(), "./.git/config");
var config = parseGitConfig.sync({ path: gitConfigPath });
if (typeof config === 'object' && config.hasOwnProperty('user')) {
existingUserName = config.user.name;
existingUserEmail = config.user.email;
if (typeof config === "object" && config.hasOwnProperty("user")) {
existingUserName = config.user.name;
existingUserEmail = config.user.email;
}
if (existingUserName === undefined) {
console.log(`Existing user name: undefined`);
console.log(`Existing user name: undefined`);
} else {
console.log(`Existing user name: "${existingUserName}"`);
cp.execSync(`git config --local --unset user.name`);
console.log(`Existing user name: "${existingUserName}"`);
cp.execSync(`git config --local --unset user.name`);
}
if (existingUserEmail === undefined) {
console.log(`Existing user email: undefined`);
console.log(`Existing user email: undefined`);
} else {
console.log(`Existing user email: "${existingUserEmail}"`);
cp.execSync(`git config --local --unset user.email`);
console.log(`Existing user email: "${existingUserEmail}"`);
cp.execSync(`git config --local --unset user.email`);
}
console.log(`Setting local user name to: "${userFullName}"`);
@ -155,61 +208,75 @@ cp.execSync(`git config --local user.name "${userFullName}"`);
console.log(`Setting local user email to: "${userEmail}"`);
cp.execSync(`git config --local user.email "${userEmail}"`);
console.log(`Configuring git with permission to push and to create pull requests (git remote remove origin && git remote add origin https://${authUser}:${authToken}@github.com/${repoOwner}/${repoName}.git`);
cp.execSync('git remote remove origin');
cp.execSync(`git remote add origin https://${authUser}:${authToken}@github.com/${repoOwner}/${repoName}.git`);
console.log(
`Configuring git with permission to push and to create pull requests (git remote remove origin && git remote add origin https://${authUser}:${authToken}@github.com/${repoOwner}/${repoName}.git`
);
cp.execSync("git remote remove origin");
cp.execSync(
`git remote add origin https://${authUser}:${authToken}@github.com/${repoOwner}/${repoName}.git`
);
// Commit changed files.
console.log(`Commiting changes (git commit -m "${commitComment}")`);
cp.execSync(`git commit -m "${commitComment}"`);
if (existingUserName === undefined) {
console.log(`Restoring original user name: undefined`);
cp.execSync(`git config --local --unset user.name`);
console.log(`Restoring original user name: undefined`);
cp.execSync(`git config --local --unset user.name`);
} else {
console.log(`Restoring original user name: "${existingUserName}"`);
cp.execSync(`git config --local user.name "${existingUserName}"`);
console.log(`Restoring original user name: "${existingUserName}"`);
cp.execSync(`git config --local user.name "${existingUserName}"`);
}
if (existingUserEmail === undefined) {
console.log(`Restoring original user email: undefined`);
cp.execSync(`git config --local --unset user.email`);
console.log(`Restoring original user email: undefined`);
cp.execSync(`git config --local --unset user.email`);
} else {
console.log(`Restoring original user email: "${existingUserEmail}"`);
cp.execSync(`git config --local user.email "${existingUserEmail}"`);
console.log(`Restoring original user email: "${existingUserEmail}"`);
cp.execSync(`git config --local user.email "${existingUserEmail}"`);
}
console.log(`pushing to remove branch (git push -f origin ${branchName})`);
cp.execSync(`git push -f origin ${branchName}`);
console.log("Checking if there is already a pull request...");
const octokit = new Octokit.Octokit({auth: authToken});
octokit.pulls.list({ owner: repoOwner, repo: repoName }).then(({data}) => {
let alreadyHasPullRequest = false;
if (data) {
data.forEach((pr) => {
alreadyHasPullRequest = alreadyHasPullRequest || (pr.title === pullRequestTitle);
});
}
const octokit = new Octokit.Octokit({ auth: authToken });
octokit.pulls.list({ owner: repoOwner, repo: repoName }).then(({ data }) => {
let alreadyHasPullRequest = false;
if (data) {
data.forEach((pr) => {
alreadyHasPullRequest =
alreadyHasPullRequest || pr.title === pullRequestTitle;
});
}
// If not already present, create a PR against our remote branch.
if (!alreadyHasPullRequest) {
console.log("There is not already a pull request. Creating one.");
octokit.pulls.create({ body:"", owner: repoOwner, repo: repoName, title: pullRequestTitle, head: branchName, base: mergeTo });
} else {
console.log("There is already a pull request.");
}
// If not already present, create a PR against our remote branch.
if (!alreadyHasPullRequest) {
console.log("There is not already a pull request. Creating one.");
octokit.pulls.create({
body: "",
owner: repoOwner,
repo: repoName,
title: pullRequestTitle,
head: branchName,
base: mergeTo,
});
} else {
console.log("There is already a pull request.");
}
console.log(`Restoring default git permissions`);
cp.execSync('git remote remove origin');
cp.execSync(`git remote add origin https://github.com/${repoOwner}/${repoName}.git`);
console.log(`Restoring default git permissions`);
cp.execSync("git remote remove origin");
cp.execSync(
`git remote add origin https://github.com/${repoOwner}/${repoName}.git`
);
console.log(`Run 'git fetch' against updated remote`);
cp.execSync('git fetch');
console.log(`Run 'git fetch' against updated remote`);
cp.execSync("git fetch");
console.log(`Switching back to ${mergeTo} (git checkout ${mergeTo})`);
cp.execSync(`git checkout ${mergeTo}`);
console.log(`Switching back to ${mergeTo} (git checkout ${mergeTo})`);
cp.execSync(`git checkout ${mergeTo}`);
console.log(`Remove localization branch (git branch -D localization)`);
cp.execSync('git branch -D localization');
console.log(`Remove localization branch (git branch -D localization)`);
cp.execSync("git branch -D localization");
});

Просмотреть файл

@ -1,28 +1,21 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es2019",
"outDir": "out",
"alwaysStrict":true,
"baseUrl": "./",
"lib": [
"es2019",
],
"sourceMap": true,
"rootDir": ".",
"useUnknownInCatchVariables": false,
"strict": true, /* enable all strict type-checking options */
"forceConsistentCasingInFileNames": true
/* Additional Checks */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */,
},
"exclude": [
"node_modules",
".vscode-test"
],
"include": [
"**/*.ts",
]
"compilerOptions": {
"module": "commonjs",
"target": "es2019",
"outDir": "out",
"alwaysStrict": true,
"baseUrl": "./",
"lib": ["es2019"],
"sourceMap": true,
"rootDir": ".",
"useUnknownInCatchVariables": false,
"strict": true /* enable all strict type-checking options */,
"forceConsistentCasingInFileNames": true
/* Additional Checks */
// "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
// "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
// "noUnusedParameters": true, /* Report errors on unused parameters. */,
},
"exclude": ["node_modules", ".vscode-test"],
"include": ["**/*.ts"]
}

Просмотреть файл

@ -1,121 +1,100 @@
{
"rules": {
"adjacent-overload-signatures": true,
"align": true,
"array-type": [true, "array"],
"arrow-return-shorthand": true,
"ban-comma-operator": true,
"binary-expression-operand-order": true,
"callable-types": true,
"class-name": true,
"comment-format": true,
"curly": true,
"encoding": true,
"eofline": true,
"ext-variable-name": [
true,
[
"class",
"pascal"
],
[
"function",
"camel"
]
],
"file-header": [
true,
".*"
],
"import-spacing": true,
"indent": [
true,
"spaces",
4
],
"label-position": true,
"match-default-export-name": true,
"member-ordering": true,
"new-parens": true,
"no-arg": true,
"no-bitwise": true,
"no-boolean-literal-compare": true,
"no-conditional-assignment": true,
"no-consecutive-blank-lines": true,
"no-construct": true,
"no-debugger": true,
"no-default-export": true,
"no-duplicate-imports": true,
"no-duplicate-super": true,
"no-duplicate-switch-case": true,
"no-duplicate-variable": true,
"no-unused-expression-chai": true,
"no-eval": true,
"no-import-side-effect": true,
"no-internal-module": true,
"no-invalid-this": true,
"no-irregular-whitespace": true,
"no-mergeable-namespace": true,
"no-misused-new": true,
"no-namespace": true,
"no-non-null-assertion": true,
"no-redundant-jsdoc": true,
"no-reference": true,
"no-reference-import": true,
"no-return-await": true,
"no-sparse-arrays": true,
"no-switch-case-fall-through": true,
"no-this-assignment": true,
"no-trailing-whitespace": true,
"no-unnecessary-callback-wrapper": true,
"no-unnecessary-initializer": true,
"no-unnecessary-qualifier": true,
"no-unsafe-finally": true,
"no-unused-expression": true,
"no-unused-variable": true,
"no-var-keyword": true,
"no-var-requires": true,
"number-literal-format": true,
"one-line": [
true,
"check-catch",
"check-finally",
"check-else",
"check-open-brace",
"check-whitespace"
],
"one-variable-per-declaration": true,
"no-floating-promises": [true, "PromisedAssertion"],
"prefer-method-signature": true,
"prefer-object-spread": true,
"prefer-while": true,
"promise-must-complete": true,
"semicolon": true,
"space-within-parens": true,
"trailing-comma": true,
"triple-equals": true,
"type-literal-delimiter": true,
"typedef": [
true,
"variable-declaration",
"call-signature"
],
"typedef-whitespace": true,
"unified-signatures": true,
"use-default-type-parameter": true,
"use-isnan": true,
"whitespace": [
true,
"check-branch",
"check-operator",
"check-separator",
"check-preblock",
"check-type"
]
},
"rulesDirectory": [
"node_modules/tslint-microsoft-contrib",
"node_modules/tslint-no-unused-expression-chai/rules",
"node_modules/vrsource-tslint-rules/rules"
"rules": {
"adjacent-overload-signatures": true,
"align": true,
"array-type": [true, "array"],
"arrow-return-shorthand": true,
"ban-comma-operator": true,
"binary-expression-operand-order": true,
"callable-types": true,
"class-name": true,
"comment-format": true,
"curly": true,
"encoding": true,
"eofline": true,
"ext-variable-name": [true, ["class", "pascal"], ["function", "camel"]],
"file-header": [true, ".*"],
"import-spacing": true,
"indent": [true, "spaces", 4],
"label-position": true,
"match-default-export-name": true,
"member-ordering": true,
"new-parens": true,
"no-arg": true,
"no-bitwise": true,
"no-boolean-literal-compare": true,
"no-conditional-assignment": true,
"no-consecutive-blank-lines": true,
"no-construct": true,
"no-debugger": true,
"no-default-export": true,
"no-duplicate-imports": true,
"no-duplicate-super": true,
"no-duplicate-switch-case": true,
"no-duplicate-variable": true,
"no-unused-expression-chai": true,
"no-eval": true,
"no-import-side-effect": true,
"no-internal-module": true,
"no-invalid-this": true,
"no-irregular-whitespace": true,
"no-mergeable-namespace": true,
"no-misused-new": true,
"no-namespace": true,
"no-non-null-assertion": true,
"no-redundant-jsdoc": true,
"no-reference": true,
"no-reference-import": true,
"no-return-await": true,
"no-sparse-arrays": true,
"no-switch-case-fall-through": true,
"no-this-assignment": true,
"no-trailing-whitespace": true,
"no-unnecessary-callback-wrapper": true,
"no-unnecessary-initializer": true,
"no-unnecessary-qualifier": true,
"no-unsafe-finally": true,
"no-unused-expression": true,
"no-unused-variable": true,
"no-var-keyword": true,
"no-var-requires": true,
"number-literal-format": true,
"one-line": [
true,
"check-catch",
"check-finally",
"check-else",
"check-open-brace",
"check-whitespace"
],
"one-variable-per-declaration": true,
"no-floating-promises": [true, "PromisedAssertion"],
"prefer-method-signature": true,
"prefer-object-spread": true,
"prefer-while": true,
"promise-must-complete": true,
"semicolon": true,
"space-within-parens": true,
"trailing-comma": true,
"triple-equals": true,
"type-literal-delimiter": true,
"typedef": [true, "variable-declaration", "call-signature"],
"typedef-whitespace": true,
"unified-signatures": true,
"use-default-type-parameter": true,
"use-isnan": true,
"whitespace": [
true,
"check-branch",
"check-operator",
"check-separator",
"check-preblock",
"check-type"
]
}
},
"rulesDirectory": [
"node_modules/tslint-microsoft-contrib",
"node_modules/tslint-no-unused-expression-chai/rules",
"node_modules/vrsource-tslint-rules/rules"
]
}

Просмотреть файл

@ -5,70 +5,77 @@
//@ts-check
'use strict';
"use strict";
const path = require('path');
const path = require("path");
/**@type {import('webpack').Configuration}*/
const config = {
target: 'node', // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/
target: "node", // vscode extensions run in a Node.js-context 📖 -> https://webpack.js.org/configuration/node/
entry: './src/extension.ts', // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/
output: { // the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/
path: path.resolve(__dirname, 'dist'),
filename: 'main.js',
libraryTarget: "commonjs2",
devtoolModuleFilenameTemplate: "../[resource-path]",
},
node: {
__dirname: false,
},
devtool: 'source-map',
externals: {
vscode: "commonjs vscode" // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/
},
resolve: { // support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader
extensions: ['.ts', '.js'],
mainFields: ['main', 'module']
},
module: {
rules: [{
test: /\.ts$/,
exclude: /node_modules/,
use: [{
// configure TypeScript loader:
// * enable sources maps for end-to-end source maps
loader: 'ts-loader',
options: {
compilerOptions: {
"sourceMap": true,
}
}
}]
},{
test: /.node$/,
loader: 'node-loader',
}]
},
optimization: {
minimize: false
},
stats: {
warnings: false
}
}
entry: "./src/extension.ts", // the entry point of this extension, 📖 -> https://webpack.js.org/configuration/entry-context/
output: {
// the bundle is stored in the 'dist' folder (check package.json), 📖 -> https://webpack.js.org/configuration/output/
path: path.resolve(__dirname, "dist"),
filename: "main.js",
libraryTarget: "commonjs2",
devtoolModuleFilenameTemplate: "../[resource-path]",
},
node: {
__dirname: false,
},
devtool: "source-map",
externals: {
vscode: "commonjs vscode", // the vscode-module is created on-the-fly and must be excluded. Add other modules that cannot be webpack'ed, 📖 -> https://webpack.js.org/configuration/externals/
},
resolve: {
// support reading TypeScript and JavaScript files, 📖 -> https://github.com/TypeStrong/ts-loader
extensions: [".ts", ".js"],
mainFields: ["main", "module"],
},
module: {
rules: [
{
test: /\.ts$/,
exclude: /node_modules/,
use: [
{
// configure TypeScript loader:
// * enable sources maps for end-to-end source maps
loader: "ts-loader",
options: {
compilerOptions: {
sourceMap: true,
},
},
},
],
},
{
test: /.node$/,
loader: "node-loader",
},
],
},
optimization: {
minimize: false,
},
stats: {
warnings: false,
},
};
module.exports = (env) => {
if (env.BUILD_VSCODE_NLS) {
// rewrite nls call when being asked for
// @ts-ignore
config.module.rules.unshift({
loader: 'vscode-nls-dev/lib/webpack-loader',
options: {
base: __dirname
}
})
}
if (env.BUILD_VSCODE_NLS) {
// rewrite nls call when being asked for
// @ts-ignore
config.module.rules.unshift({
loader: "vscode-nls-dev/lib/webpack-loader",
options: {
base: __dirname,
},
});
}
return config;
return config;
};