Родитель
8e48036003
Коммит
889d4fff56
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
"recommendations": [
|
||||
"dbaeumer.vscode-eslint",
|
||||
"esbenp.prettier-vscode",
|
||||
"redhat.vscode-yaml"
|
||||
]
|
||||
}
|
|
@ -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
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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"]
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
456
gulpfile.js
456
gulpfile.js
|
@ -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())
|
||||
);
|
||||
});
|
||||
|
||||
|
|
122
jobs/cg.yml
122
jobs/cg.yml
|
@ -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
|
||||
|
|
1832
package.json
1832
package.json
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
140
package.nls.json
140
package.nls.json
|
@ -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"
|
||||
}
|
||||
|
|
3209
src/configuration.ts
3209
src/configuration.ts
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
372
src/cpptools.ts
372
src/cpptools.ts
|
@ -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);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
1090
src/extension.ts
1090
src/extension.ts
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
739
src/launch.ts
739
src/launch.ts
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
2868
src/make.ts
2868
src/make.ts
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
2997
src/parser.ts
2997
src/parser.ts
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
30
src/state.ts
30
src/state.ts
|
@ -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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
588
src/telemetry.ts
588
src/telemetry.ts
|
@ -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();
|
||||
|
|
744
src/tree.ts
744
src/tree.ts
|
@ -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
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;
|
||||
}
|
||||
|
|
1472
src/util.ts
1472
src/util.ts
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -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"]
|
||||
}
|
||||
|
|
217
tslint.json
217
tslint.json
|
@ -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;
|
||||
};
|
||||
|
|
Загрузка…
Ссылка в новой задаче