Switch to accessibility insights's version of these tools (#603)
* Switch to accessibility insights's version of these tools * auto-add files meeting strict checks
This commit is contained in:
parent
88f5e7485a
commit
dc5679ffd3
|
@ -200,8 +200,8 @@
|
||||||
"format:check": "prettier --check \"{src,test}/**/*.{ts,tsx,html}\" \"*.{js,html}\"",
|
"format:check": "prettier --check \"{src,test}/**/*.{ts,tsx,html}\" \"*.{js,html}\"",
|
||||||
"lint": "tslint --project tsconfig.json && eslint \"**/*.{ts,tsx}\"",
|
"lint": "tslint --project tsconfig.json && eslint \"**/*.{ts,tsx}\"",
|
||||||
"build:contracts": "npm run compile:contracts",
|
"build:contracts": "npm run compile:contracts",
|
||||||
"strictEligibleFiles": "node ./strict-migration-tools/index.js",
|
"strict:find": "node ./strict-null-checks/find.js",
|
||||||
"autoAddStrictEligibleFiles": "node ./strict-migration-tools/autoAdd.js",
|
"strict:add": "node ./strict-null-checks/auto-add.js",
|
||||||
"compile:fullStrict": "tsc -p ./tsconfig.json --strictNullChecks",
|
"compile:fullStrict": "tsc -p ./tsconfig.json --strictNullChecks",
|
||||||
"generateARMClients": "ts-node --compiler-options '{\"module\":\"commonjs\"}' utils/armClientGenerator/generator.ts"
|
"generateARMClients": "ts-node --compiler-options '{\"module\":\"commonjs\"}' utils/armClientGenerator/generator.ts"
|
||||||
},
|
},
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
node_modules
|
|
|
@ -1,25 +0,0 @@
|
||||||
Borrowed from https://github.com/mjbvz/vscode-strict-null-check-migration-tools/tree/f1da7c12fe6e93618a310cb3662e2ade808be0c4
|
|
||||||
|
|
||||||
Scripts to help [migrate VS Code to use strict null checks](https://github.com/Microsoft/vscode/issues/60565)
|
|
||||||
|
|
||||||
## Usage
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ npm install
|
|
||||||
```
|
|
||||||
|
|
||||||
**index.js**
|
|
||||||
|
|
||||||
The main script prints of list of files that are eligible for strict null checks. This includes all files that only import files thare are already strict null checked.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ node index.js /path/to/vscode
|
|
||||||
```
|
|
||||||
|
|
||||||
**autoAdd.js**
|
|
||||||
|
|
||||||
Very simple script that tries to auto add any eligible file to the `tsconfig.strictNullChecks.json`. This iteratively compiles the `tsconfig` project with just that file added. If there are no errors, it is added to the `tsconfig`
|
|
||||||
|
|
||||||
```bash
|
|
||||||
$ node autoAdd.js /path/to/vscode
|
|
||||||
```
|
|
|
@ -1,55 +0,0 @@
|
||||||
// @ts-check
|
|
||||||
const path = require("path");
|
|
||||||
const fs = require("fs");
|
|
||||||
const child_process = require("child_process");
|
|
||||||
const config = require("./src/config");
|
|
||||||
const { forStrictNullCheckEligibleFiles } = require("./src/getStrictNullCheckEligibleFiles");
|
|
||||||
|
|
||||||
const vscodeRoot = path.join(process.cwd());
|
|
||||||
const srcRoot = path.join(vscodeRoot, "src");
|
|
||||||
|
|
||||||
const buildCompletePattern = /Found (\d+) errors?\. Watching for file changes\./gi;
|
|
||||||
|
|
||||||
forStrictNullCheckEligibleFiles(vscodeRoot, () => {}).then(async files => {
|
|
||||||
const tsconfigPath = path.join(srcRoot, config.targetTsconfig);
|
|
||||||
|
|
||||||
const child = child_process.spawn("tsc", ["-p", tsconfigPath, "--watch"]);
|
|
||||||
for (const file of files) {
|
|
||||||
await tryAutoAddStrictNulls(child, tsconfigPath, file);
|
|
||||||
}
|
|
||||||
child.kill();
|
|
||||||
});
|
|
||||||
|
|
||||||
function tryAutoAddStrictNulls(child, tsconfigPath, file) {
|
|
||||||
return new Promise(resolve => {
|
|
||||||
const relativeFilePath = path.relative(srcRoot, file);
|
|
||||||
console.log(`Trying to auto add ./src/${relativeFilePath}`);
|
|
||||||
|
|
||||||
const originalConifg = JSON.parse(fs.readFileSync(tsconfigPath).toString());
|
|
||||||
originalConifg.files = Array.from(new Set(originalConifg.files.sort()));
|
|
||||||
|
|
||||||
// Config on accept
|
|
||||||
const newConfig = Object.assign({}, originalConifg);
|
|
||||||
newConfig.files = Array.from(new Set(originalConifg.files.concat("./src/" + relativeFilePath).sort()));
|
|
||||||
|
|
||||||
fs.writeFileSync(tsconfigPath, JSON.stringify(newConfig, null, "\t"));
|
|
||||||
|
|
||||||
const listener = data => {
|
|
||||||
const textOut = data.toString();
|
|
||||||
const match = buildCompletePattern.exec(textOut);
|
|
||||||
if (match) {
|
|
||||||
const errorCount = +match[1];
|
|
||||||
if (errorCount === 0) {
|
|
||||||
console.log(`👍`);
|
|
||||||
fs.writeFileSync(tsconfigPath, JSON.stringify(newConfig, null, "\t"));
|
|
||||||
} else {
|
|
||||||
console.log(`💥 - ${errorCount}`);
|
|
||||||
fs.writeFileSync(tsconfigPath, JSON.stringify(originalConifg, null, "\t"));
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
child.stdout.removeListener("data", listener);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
child.stdout.on("data", listener);
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
// @ts-check
|
|
||||||
const path = require("path");
|
|
||||||
const glob = require("glob");
|
|
||||||
const { forStrictNullCheckEligibleFiles, forEachFileInSrc } = require("./src/getStrictNullCheckEligibleFiles");
|
|
||||||
const { getImportsForFile } = require("./src/tsHelper");
|
|
||||||
|
|
||||||
const projectRoot = path.join(process.cwd());
|
|
||||||
const srcRoot = path.join(projectRoot, "src");
|
|
||||||
|
|
||||||
let sort = true;
|
|
||||||
let filter;
|
|
||||||
let printDependedOnCount = true;
|
|
||||||
let includeTests = false;
|
|
||||||
|
|
||||||
// if (false) {
|
|
||||||
// // Generate test files listing
|
|
||||||
// sort = false;
|
|
||||||
// filter = x => x.endsWith(".test.ts");
|
|
||||||
// printDependedOnCount = false;
|
|
||||||
// includeTests = true;
|
|
||||||
// }
|
|
||||||
|
|
||||||
forStrictNullCheckEligibleFiles(projectRoot, () => {}, { includeTests }).then(async eligibleFiles => {
|
|
||||||
console.log(eligibleFiles);
|
|
||||||
// const eligibleSet = new Set(eligibleFiles);
|
|
||||||
// const dependedOnCount = new Map(eligibleFiles.map(file => [file, 0]));
|
|
||||||
// for (const file of await forEachFileInSrc(srcRoot)) {
|
|
||||||
// if (eligibleSet.has(file)) {
|
|
||||||
// // Already added
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
// for (const imp of getImportsForFile(file, srcRoot)) {
|
|
||||||
// if (dependedOnCount.has(imp)) {
|
|
||||||
// dependedOnCount.set(imp, dependedOnCount.get(imp) + 1);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// let out = Array.from(dependedOnCount.entries());
|
|
||||||
// if (filter) {
|
|
||||||
// out = out.filter(x => filter(x[0]));
|
|
||||||
// }
|
|
||||||
// if (sort) {
|
|
||||||
// out = out.sort((a, b) => b[1] - a[1]);
|
|
||||||
// }
|
|
||||||
// for (const pair of out) {
|
|
||||||
// console.log(toFormattedFilePath(pair[0]) + (printDependedOnCount ? ` — Depended on by **${pair[1]}** files` : ""));
|
|
||||||
// }
|
|
||||||
});
|
|
||||||
|
|
||||||
// function toFormattedFilePath(file) {
|
|
||||||
// // return `"./${path.relative(srcRoot, file)}",`;
|
|
||||||
// return `- [ ] \`"./${path.relative(srcRoot, file)}"\``;
|
|
||||||
// }
|
|
|
@ -1,90 +0,0 @@
|
||||||
{
|
|
||||||
"name": "vscode-strict-null-tools",
|
|
||||||
"version": "1.0.0",
|
|
||||||
"lockfileVersion": 1,
|
|
||||||
"requires": true,
|
|
||||||
"dependencies": {
|
|
||||||
"balanced-match": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
|
||||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
|
|
||||||
},
|
|
||||||
"brace-expansion": {
|
|
||||||
"version": "1.1.11",
|
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
|
||||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
|
||||||
"requires": {
|
|
||||||
"balanced-match": "^1.0.0",
|
|
||||||
"concat-map": "0.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"concat-map": {
|
|
||||||
"version": "0.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
|
||||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
|
|
||||||
},
|
|
||||||
"fs.realpath": {
|
|
||||||
"version": "1.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
|
||||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
|
|
||||||
},
|
|
||||||
"glob": {
|
|
||||||
"version": "7.1.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
|
|
||||||
"integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
|
|
||||||
"requires": {
|
|
||||||
"fs.realpath": "^1.0.0",
|
|
||||||
"inflight": "^1.0.4",
|
|
||||||
"inherits": "2",
|
|
||||||
"minimatch": "^3.0.4",
|
|
||||||
"once": "^1.3.0",
|
|
||||||
"path-is-absolute": "^1.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"inflight": {
|
|
||||||
"version": "1.0.6",
|
|
||||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
|
||||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
|
||||||
"requires": {
|
|
||||||
"once": "^1.3.0",
|
|
||||||
"wrappy": "1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"inherits": {
|
|
||||||
"version": "2.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
|
||||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
|
|
||||||
},
|
|
||||||
"minimatch": {
|
|
||||||
"version": "3.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
|
||||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
|
||||||
"requires": {
|
|
||||||
"brace-expansion": "^1.1.7"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"once": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
|
||||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
|
||||||
"requires": {
|
|
||||||
"wrappy": "1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"path-is-absolute": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
|
||||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
|
|
||||||
},
|
|
||||||
"typescript": {
|
|
||||||
"version": "3.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.2.tgz",
|
|
||||||
"integrity": "sha512-gOoGJWbNnFAfP9FlrSV63LYD5DJqYJHG5ky1kOXSl3pCImn4rqWy/flyq1BRd4iChQsoCqjbQaqtmXO4yCVPCA=="
|
|
||||||
},
|
|
||||||
"wrappy": {
|
|
||||||
"version": "1.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
|
||||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
{
|
|
||||||
"name": "vscode-strict-null-tools",
|
|
||||||
"private": true,
|
|
||||||
"version": "1.0.0",
|
|
||||||
"description": "",
|
|
||||||
"main": "index.js",
|
|
||||||
"scripts": {
|
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
|
||||||
},
|
|
||||||
"keywords": [],
|
|
||||||
"author": "Matt Bierner",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"typescript": "3.1.2",
|
|
||||||
"glob": "^7.1.3"
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,3 +0,0 @@
|
||||||
module.exports.targetTsconfig = "../tsconfig.strict.json";
|
|
||||||
|
|
||||||
module.exports.skippedFiles = new Set([]);
|
|
|
@ -1,94 +0,0 @@
|
||||||
// @ts-check
|
|
||||||
const path = require("path");
|
|
||||||
const fs = require("fs");
|
|
||||||
const { getImportsForFile } = require("./tsHelper");
|
|
||||||
const glob = require("glob");
|
|
||||||
const config = require("./config");
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} srcRoot
|
|
||||||
* @param {{ includeTests: boolean }} [options]
|
|
||||||
*/
|
|
||||||
const forEachFileInSrc = (srcRoot, options) => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
glob(`${srcRoot}/**/*.ts`, (err, files) => {
|
|
||||||
if (err) {
|
|
||||||
return reject(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
return resolve(
|
|
||||||
files.filter(
|
|
||||||
file => !file.endsWith(".d.ts") && (options && options.includeTests ? true : !file.endsWith(".test.ts"))
|
|
||||||
)
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
};
|
|
||||||
module.exports.forEachFileInSrc = forEachFileInSrc;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param {string} vscodeRoot
|
|
||||||
* @param {(file: string) => void} forEach
|
|
||||||
* @param {{ includeTests: boolean }} [options]
|
|
||||||
*/
|
|
||||||
module.exports.forStrictNullCheckEligibleFiles = async (vscodeRoot, forEach, options) => {
|
|
||||||
const srcRoot = path.join(vscodeRoot, "src");
|
|
||||||
|
|
||||||
const tsconfig = JSON.parse(fs.readFileSync(path.join(srcRoot, config.targetTsconfig)).toString());
|
|
||||||
const checkedFiles = await getCheckedFiles(tsconfig, vscodeRoot);
|
|
||||||
|
|
||||||
const imports = new Map();
|
|
||||||
const getMemoizedImportsForFile = (file, srcRoot) => {
|
|
||||||
if (imports.has(file)) {
|
|
||||||
return imports.get(file);
|
|
||||||
}
|
|
||||||
const importList = getImportsForFile(file, srcRoot);
|
|
||||||
imports.set(file, importList);
|
|
||||||
return importList;
|
|
||||||
};
|
|
||||||
|
|
||||||
const files = await forEachFileInSrc(srcRoot, options);
|
|
||||||
return files
|
|
||||||
.filter(file => !checkedFiles.has(file))
|
|
||||||
.filter(file => !config.skippedFiles.has(path.relative(srcRoot, file)))
|
|
||||||
.filter(file => {
|
|
||||||
const allProjImports = getMemoizedImportsForFile(file, srcRoot);
|
|
||||||
|
|
||||||
const nonCheckedImports = allProjImports
|
|
||||||
.filter(x => x !== file)
|
|
||||||
.filter(imp => {
|
|
||||||
if (checkedFiles.has(imp)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Don't treat cycles as blocking
|
|
||||||
const impImports = getMemoizedImportsForFile(imp, srcRoot);
|
|
||||||
return impImports.filter(x => x !== file).filter(x => !checkedFiles.has(x)).length !== 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
const isEdge = nonCheckedImports.length === 0;
|
|
||||||
if (isEdge) {
|
|
||||||
forEach(file);
|
|
||||||
}
|
|
||||||
return isEdge;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
async function getCheckedFiles(tsconfig, srcRoot) {
|
|
||||||
const set = new Set(tsconfig.files.map(include => path.join(srcRoot, include)));
|
|
||||||
const includes = tsconfig.include.map(include => {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
glob(path.join(srcRoot, include), (err, files) => {
|
|
||||||
if (err) {
|
|
||||||
return reject(err);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const file of files) {
|
|
||||||
set.add(file);
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
});
|
|
||||||
await Promise.all(includes);
|
|
||||||
return set;
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
// @ts-check
|
|
||||||
const path = require("path");
|
|
||||||
const ts = require("typescript");
|
|
||||||
const fs = require("fs");
|
|
||||||
|
|
||||||
module.exports.getImportsForFile = function getImportsForFile(file, srcRoot) {
|
|
||||||
const fileInfo = ts.preProcessFile(fs.readFileSync(file).toString());
|
|
||||||
return fileInfo.importedFiles
|
|
||||||
.map(importedFile => importedFile.fileName)
|
|
||||||
.filter(fileName => !/svg|gif|png|html|less|json|externals|css|ico/.test(fileName)) // remove image imports
|
|
||||||
.filter(x => /\//.test(x)) // remove node modules (the import must contain '/')
|
|
||||||
.filter(x => !/\@/.test(x)) // remove @ scoped modules
|
|
||||||
.filter(
|
|
||||||
x =>
|
|
||||||
!/url-polyfill|office-ui-fabric|rxjs|\@nteract|bootstrap|promise-polyfill|abort-controller|es6-object-assign|es6-symbol|webcrypto-liner|promise.prototype.finally|object.entries/.test(
|
|
||||||
x
|
|
||||||
)
|
|
||||||
) // remove other modules
|
|
||||||
.filter(x => !/worker-loader/.test(x)) // remove other modules
|
|
||||||
.map(fileName => {
|
|
||||||
if (/(^\.\/)|(^\.\.\/)/.test(fileName)) {
|
|
||||||
return path.join(path.dirname(file), fileName);
|
|
||||||
}
|
|
||||||
if (/^vs/.test(fileName)) {
|
|
||||||
return path.join(srcRoot, fileName);
|
|
||||||
}
|
|
||||||
return fileName;
|
|
||||||
})
|
|
||||||
.map(fileName => {
|
|
||||||
if (fs.existsSync(`${fileName}.ts`)) {
|
|
||||||
return `${fileName}.ts`;
|
|
||||||
}
|
|
||||||
if (fs.existsSync(`${fileName}.js`)) {
|
|
||||||
return `${fileName}.js`;
|
|
||||||
}
|
|
||||||
if (fs.existsSync(`${fileName}.d.ts`)) {
|
|
||||||
return `${fileName}.d.ts`;
|
|
||||||
}
|
|
||||||
if (fs.existsSync(`${fileName}.tsx`)) {
|
|
||||||
return `${fileName}.tsx`;
|
|
||||||
}
|
|
||||||
throw new Error(`Unresolved import ${fileName} in ${file}`);
|
|
||||||
});
|
|
||||||
};
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
<!--
|
||||||
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
Licensed under the MIT License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
Scripts to help migrate to use strict null checks.
|
||||||
|
|
||||||
|
Modified from [strict-null-checks](https://github.com/microsoft/accessibility-insights-web/tree/f2ec74cc5f09d41a4b617b0eb941b6da332a4343/tools/strict-null-checks)
|
|
@ -0,0 +1,100 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
// @ts-check
|
||||||
|
const child_process = require("child_process");
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const { collapseCompletedDirectories } = require("./collapse-completed-directories");
|
||||||
|
const config = require("./config");
|
||||||
|
const { getUncheckedLeafFiles } = require("./eligible-file-finder");
|
||||||
|
const { writeTsconfigSync } = require("./write-tsconfig");
|
||||||
|
|
||||||
|
const repoRoot = config.repoRoot;
|
||||||
|
const tscPath = path.join(repoRoot, "node_modules", "typescript", "bin", "tsc");
|
||||||
|
const tsconfigPath = path.join(repoRoot, config.targetTsconfig);
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
console.log("## Initializing tsc --watch process...");
|
||||||
|
const tscWatchProcess = child_process.spawn("node", [tscPath, "-p", tsconfigPath, "--watch"]);
|
||||||
|
await waitForBuildComplete(tscWatchProcess);
|
||||||
|
|
||||||
|
const alreadyAttempted = new Set();
|
||||||
|
|
||||||
|
for (let pass = 1; ; pass += 1) {
|
||||||
|
let successesThisPass = 0;
|
||||||
|
const uncheckedLeafFiles = await getUncheckedLeafFiles();
|
||||||
|
const candidateFiles = uncheckedLeafFiles.filter((f) => !alreadyAttempted.has(f));
|
||||||
|
const candidateCount = candidateFiles.length;
|
||||||
|
console.log(`## Starting pass ${pass} with ${candidateCount} candidate files`);
|
||||||
|
|
||||||
|
for (const file of candidateFiles) {
|
||||||
|
alreadyAttempted.add(file);
|
||||||
|
if (await tryAutoAddStrictNulls(tscWatchProcess, tsconfigPath, file)) {
|
||||||
|
successesThisPass += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`### Finished pass ${pass} (added ${successesThisPass}/${candidateCount})`);
|
||||||
|
if (successesThisPass === 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("## Stopping tsc --watch process...");
|
||||||
|
tscWatchProcess.kill();
|
||||||
|
|
||||||
|
console.log('## Collapsing fully null-checked directories into "include" patterns...');
|
||||||
|
collapseCompletedDirectories(tsconfigPath);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function tryAutoAddStrictNulls(child, tsconfigPath, file) {
|
||||||
|
const relativeFilePath = path.relative(repoRoot, file).replace(/\\/g, "/");
|
||||||
|
const originalConfig = JSON.parse(fs.readFileSync(tsconfigPath).toString());
|
||||||
|
originalConfig.files = Array.from(new Set(originalConfig.files.sort()));
|
||||||
|
|
||||||
|
// Config on accept
|
||||||
|
const newConfig = Object.assign({}, originalConfig);
|
||||||
|
newConfig.files = Array.from(new Set(originalConfig.files.concat("./" + relativeFilePath).sort()));
|
||||||
|
|
||||||
|
const buildCompetePromise = waitForBuildComplete(child);
|
||||||
|
|
||||||
|
writeTsconfigSync(tsconfigPath, newConfig);
|
||||||
|
|
||||||
|
const errorCount = await buildCompetePromise;
|
||||||
|
const success = errorCount === 0;
|
||||||
|
if (success) {
|
||||||
|
console.log(`${relativeFilePath}: added`);
|
||||||
|
} else {
|
||||||
|
console.log(`${relativeFilePath}: ${errorCount} error(s), skipped`);
|
||||||
|
writeTsconfigSync(tsconfigPath, originalConfig);
|
||||||
|
}
|
||||||
|
|
||||||
|
return success;
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildCompletePattern = /Found (\d+) errors?\. Watching for file changes\./gi;
|
||||||
|
async function waitForBuildComplete(tscWatchProcess) {
|
||||||
|
const match = await waitForStdoutMatching(tscWatchProcess, buildCompletePattern);
|
||||||
|
const errorCount = +match[1];
|
||||||
|
return errorCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function waitForStdoutMatching(child, pattern) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
const listener = (data) => {
|
||||||
|
const textOut = data.toString();
|
||||||
|
const match = pattern.exec(textOut);
|
||||||
|
if (match) {
|
||||||
|
child.stdout.removeListener("data", listener);
|
||||||
|
resolve(match);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
child.stdout.on("data", listener);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch((error) => {
|
||||||
|
console.error(error.stack);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
|
@ -0,0 +1,83 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
// @ts-check
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const config = require("./config");
|
||||||
|
const { writeTsconfigSync } = require("./write-tsconfig");
|
||||||
|
|
||||||
|
const repoRoot = config.repoRoot;
|
||||||
|
|
||||||
|
function collapseCompletedDirectories(tsconfigPath) {
|
||||||
|
const tsconfigContent = JSON.parse(fs.readFileSync(tsconfigPath).toString());
|
||||||
|
const listedFiles = Array.from(new Set(tsconfigContent.files.sort()));
|
||||||
|
const listedIncludes = Array.from(new Set(tsconfigContent.include.sort()));
|
||||||
|
const listedDirectories = listedIncludes.map(includeToDirectory);
|
||||||
|
const completedSet = new Set([...listedFiles, ...listedDirectories]);
|
||||||
|
|
||||||
|
reduceCompletedSet(completedSet, "./src");
|
||||||
|
|
||||||
|
const completedPaths = Array.from(completedSet).sort();
|
||||||
|
tsconfigContent.files = completedPaths.filter(isTsFile);
|
||||||
|
tsconfigContent.include = completedPaths.filter(isSourceDirectory).map(directoryToInclude);
|
||||||
|
|
||||||
|
writeTsconfigSync(tsconfigPath, tsconfigContent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert from src/common/styles/**/* to ./src/common/styles
|
||||||
|
function includeToDirectory(include) {
|
||||||
|
return "./" + include.replace("/**/*", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
// convert from ./src/common/styles to src/common/styles/**/*
|
||||||
|
function directoryToInclude(directory) {
|
||||||
|
return directory.substring(2) + "/**/*";
|
||||||
|
}
|
||||||
|
|
||||||
|
function reduceCompletedSet(completedSet, root) {
|
||||||
|
if (completedSet.has(root)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (!isSourceDirectory(root)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const children = listRelevantChildren(root);
|
||||||
|
let allChildrenReduced = true;
|
||||||
|
for (const child of children) {
|
||||||
|
const childReduced = reduceCompletedSet(completedSet, child);
|
||||||
|
allChildrenReduced = allChildrenReduced && childReduced;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (allChildrenReduced) {
|
||||||
|
for (const child of children) {
|
||||||
|
completedSet.delete(child);
|
||||||
|
}
|
||||||
|
completedSet.add(root);
|
||||||
|
}
|
||||||
|
return allChildrenReduced;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isSourceDirectory(relativePath) {
|
||||||
|
// this assumes directories don't have .s in their names, which isn't robust generally
|
||||||
|
// but happens to be true in our repo
|
||||||
|
const isDirectory = -1 === relativePath.indexOf(".", 1);
|
||||||
|
return isDirectory && !relativePath.includes("__snapshots__");
|
||||||
|
}
|
||||||
|
|
||||||
|
const isTsFileRegex = /\.(ts|tsx)$/;
|
||||||
|
function isTsFile(relativePath) {
|
||||||
|
return isTsFileRegex.test(relativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
function listRelevantChildren(relativePath) {
|
||||||
|
const rawReaddir = fs.readdirSync(path.join(repoRoot, relativePath));
|
||||||
|
const directories = rawReaddir.filter(isSourceDirectory);
|
||||||
|
const tsFiles = rawReaddir.filter(isTsFile);
|
||||||
|
return [...directories, ...tsFiles].map((name) => relativePath + "/" + name);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
collapseCompletedDirectories,
|
||||||
|
};
|
|
@ -0,0 +1,11 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
const path = require("path");
|
||||||
|
const repoRoot = path.join(__dirname, "../").replace(/\\/g, "/");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
repoRoot: repoRoot,
|
||||||
|
srcRoot: `${repoRoot}/src`,
|
||||||
|
targetTsconfig: "tsconfig.strict.json",
|
||||||
|
skippedFiles: new Set([]),
|
||||||
|
};
|
|
@ -0,0 +1,70 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
// @ts-check
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const glob = require("glob");
|
||||||
|
const config = require("./config");
|
||||||
|
const { getMemoizedImportsForFile } = require("./import-finder");
|
||||||
|
|
||||||
|
// "Eligible" means "a file that we might want to list in tsconfig.strictNullChecks.json"
|
||||||
|
// "Checked" means "a file that is currently listed in tsconfig.strictNullChecks.json"
|
||||||
|
// It is possible for an ineligible file to be checked (eg, a png under /src/icons/**)
|
||||||
|
|
||||||
|
const isEligibleFile = (file) => !config.skippedFiles.has(path.relative(config.srcRoot, file));
|
||||||
|
|
||||||
|
function globAsync(pattern) {
|
||||||
|
return new Promise((resolve, reject) => glob(pattern, (err, files) => (err ? reject(err) : resolve(files))));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Includes both checked and unchecked files (ie, doesn't care about inclusion in tsconfig.strictNullChecks.json)
|
||||||
|
async function getAllEligibleFiles() {
|
||||||
|
const tsFiles = await globAsync(`${config.srcRoot}/**/*.@(ts|tsx)`);
|
||||||
|
return tsFiles.filter(isEligibleFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Includes ineligible files that are listed under glob patterns in tsconfig.strictNullChecks
|
||||||
|
async function getAllCheckedFiles() {
|
||||||
|
const tsconfigPath = path.join(config.repoRoot, config.targetTsconfig);
|
||||||
|
const tsconfigContent = JSON.parse(fs.readFileSync(tsconfigPath).toString());
|
||||||
|
|
||||||
|
const set = new Set(tsconfigContent.files.map((f) => path.join(config.repoRoot, f).replace(/\\/g, "/")));
|
||||||
|
await Promise.all(
|
||||||
|
tsconfigContent.include.map(async (include) => {
|
||||||
|
const includePath = path.join(config.repoRoot, include);
|
||||||
|
const files = await globAsync(includePath);
|
||||||
|
for (const file of files) {
|
||||||
|
set.add(file);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getUncheckedLeafFiles() {
|
||||||
|
const checkedFiles = await getAllCheckedFiles();
|
||||||
|
const eligibleFiles = await getAllEligibleFiles();
|
||||||
|
const eligibleFileSet = new Set(eligibleFiles);
|
||||||
|
const allUncheckedFiles = eligibleFiles.filter((file) => !checkedFiles.has(file));
|
||||||
|
|
||||||
|
const areAllImportsChecked = (file) => {
|
||||||
|
const allImports = getMemoizedImportsForFile(file, config.srcRoot);
|
||||||
|
const uncheckedImports = allImports.filter((imp) => !checkedFiles.has(imp));
|
||||||
|
const ineligibleUncheckedImports = uncheckedImports.filter((imp) => !eligibleFileSet.has(imp));
|
||||||
|
if (ineligibleUncheckedImports.length > 0) {
|
||||||
|
console.warn(
|
||||||
|
`Eligible file ${file} with unchecked ineligible imports [${ineligibleUncheckedImports.join(", ")}]`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return uncheckedImports.length === 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
return allUncheckedFiles.filter(areAllImportsChecked);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getAllEligibleFiles,
|
||||||
|
getUncheckedLeafFiles,
|
||||||
|
getAllCheckedFiles,
|
||||||
|
};
|
|
@ -0,0 +1,63 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
// @ts-check
|
||||||
|
const path = require("path");
|
||||||
|
const process = require("process");
|
||||||
|
const { srcRoot } = require("./config");
|
||||||
|
const { getUncheckedLeafFiles, getAllEligibleFiles } = require("./eligible-file-finder");
|
||||||
|
const { getImportsForFile } = require("./import-finder");
|
||||||
|
|
||||||
|
if (process.argv.includes("--help")) {
|
||||||
|
console.log("yarn null:find [--sort=name|count] [--show-count] [--filter file_path_substring]");
|
||||||
|
process.exit(0);
|
||||||
|
}
|
||||||
|
const sortBy = process.argv.includes("--sort=name") ? "name" : "count";
|
||||||
|
const printDependedOnCount = process.argv.includes("--show-count");
|
||||||
|
const filterArgIndex = process.argv.indexOf("--filter") + 1;
|
||||||
|
const filterArg = filterArgIndex === 0 ? null : process.argv[filterArgIndex];
|
||||||
|
const filter = filterArg && ((file) => file.includes(filterArg));
|
||||||
|
|
||||||
|
async function main() {
|
||||||
|
const eligibleFiles = await getUncheckedLeafFiles();
|
||||||
|
|
||||||
|
const eligibleSet = new Set(eligibleFiles);
|
||||||
|
|
||||||
|
const dependedOnCount = new Map(eligibleFiles.map((file) => [file, 0]));
|
||||||
|
|
||||||
|
for (const file of await getAllEligibleFiles()) {
|
||||||
|
if (eligibleSet.has(file)) {
|
||||||
|
// Already added
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const imp of getImportsForFile(file, srcRoot)) {
|
||||||
|
if (dependedOnCount.has(imp)) {
|
||||||
|
dependedOnCount.set(imp, dependedOnCount.get(imp) + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let out = Array.from(dependedOnCount.entries());
|
||||||
|
if (filter) {
|
||||||
|
out = out.filter((x) => filter(x[0]));
|
||||||
|
}
|
||||||
|
if (sortBy === "count") {
|
||||||
|
out = out.sort((a, b) => b[1] - a[1]);
|
||||||
|
} else if (sortBy === "name") {
|
||||||
|
out = out.sort((a, b) => a[0].localeCompare(b[0]));
|
||||||
|
}
|
||||||
|
for (const pair of out) {
|
||||||
|
console.log(toFormattedFilePath(pair[0]) + (printDependedOnCount ? ` — Depended on by **${pair[1]}** files` : ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function toFormattedFilePath(file) {
|
||||||
|
const relativePath = path.relative(srcRoot, file).replace(/\\/g, "/");
|
||||||
|
return `"./src/${relativePath}",`;
|
||||||
|
}
|
||||||
|
|
||||||
|
main().catch((error) => {
|
||||||
|
console.error(error.stack);
|
||||||
|
process.exit(1);
|
||||||
|
});
|
|
@ -0,0 +1,34 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
|
||||||
|
// @ts-check
|
||||||
|
const fs = require("fs");
|
||||||
|
const path = require("path");
|
||||||
|
const ts = require("typescript");
|
||||||
|
|
||||||
|
const imports = new Map();
|
||||||
|
const getMemoizedImportsForFile = (file, srcRoot) => {
|
||||||
|
if (imports.has(file)) {
|
||||||
|
return imports.get(file);
|
||||||
|
}
|
||||||
|
const importList = getImportsForFile(file, srcRoot);
|
||||||
|
imports.set(file, importList);
|
||||||
|
return importList;
|
||||||
|
};
|
||||||
|
|
||||||
|
function getImportsForFile(parent, srcRoot) {
|
||||||
|
return ts
|
||||||
|
.preProcessFile(fs.readFileSync(parent).toString())
|
||||||
|
.importedFiles.map(({ fileName }) => fileName)
|
||||||
|
.filter((base) => /\//.test(base)) // remove node modules (the import must contain '/')
|
||||||
|
.map((base) => (/(^\.\/)|(^\.\.\/)/.test(base) ? path.join(path.dirname(parent), base) : path.join(srcRoot, base)))
|
||||||
|
.map((base) => (fs.existsSync(base) ? path.join(base, "index") : base))
|
||||||
|
.map((base) => base.replace(/\\/g, "/"))
|
||||||
|
.map((base) => ["ts", "tsx", "d.ts", "js", "jsx"].map((ext) => `${base}.${ext}`).find(fs.existsSync))
|
||||||
|
.filter((base) => base && base !== parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getImportsForFile,
|
||||||
|
getMemoizedImportsForFile,
|
||||||
|
};
|
|
@ -0,0 +1,12 @@
|
||||||
|
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||||
|
// Licensed under the MIT License.
|
||||||
|
const fs = require("fs");
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
writeTsconfigSync: (tsconfigPath, content) => {
|
||||||
|
let serializedContent = JSON.stringify(content, null, " ");
|
||||||
|
serializedContent += "\n";
|
||||||
|
|
||||||
|
fs.writeFileSync(tsconfigPath, serializedContent);
|
||||||
|
},
|
||||||
|
};
|
|
@ -15,107 +15,111 @@
|
||||||
"./src/Common/DocumentUtility.ts",
|
"./src/Common/DocumentUtility.ts",
|
||||||
"./src/Common/EnvironmentUtility.ts",
|
"./src/Common/EnvironmentUtility.ts",
|
||||||
"./src/Common/HashMap.ts",
|
"./src/Common/HashMap.ts",
|
||||||
|
"./src/Common/HeadersUtility.test.ts",
|
||||||
"./src/Common/HeadersUtility.ts",
|
"./src/Common/HeadersUtility.ts",
|
||||||
"./src/Common/Logger.ts",
|
"./src/Common/Logger.ts",
|
||||||
|
"./src/Common/MessageHandler.test.ts",
|
||||||
"./src/Common/MessageHandler.ts",
|
"./src/Common/MessageHandler.ts",
|
||||||
"./src/Common/MongoUtility.ts",
|
"./src/Common/MongoUtility.ts",
|
||||||
|
"./src/Common/ObjectCache.test.ts",
|
||||||
"./src/Common/ObjectCache.ts",
|
"./src/Common/ObjectCache.ts",
|
||||||
|
"./src/Common/OfferUtility.test.ts",
|
||||||
"./src/Common/OfferUtility.ts",
|
"./src/Common/OfferUtility.ts",
|
||||||
|
"./src/Common/Splitter.ts",
|
||||||
"./src/Common/ThemeUtility.ts",
|
"./src/Common/ThemeUtility.ts",
|
||||||
"./src/Common/UrlUtility.ts",
|
"./src/Common/UrlUtility.ts",
|
||||||
"./src/Common/Splitter.ts",
|
|
||||||
"./src/ConfigContext.ts",
|
"./src/ConfigContext.ts",
|
||||||
"./src/Contracts/ActionContracts.ts",
|
"./src/Contracts/ActionContracts.ts",
|
||||||
"./src/Contracts/DataModels.ts",
|
"./src/Contracts/DataModels.ts",
|
||||||
"./src/Contracts/Diagnostics.ts",
|
"./src/Contracts/Diagnostics.ts",
|
||||||
"./src/Contracts/ExplorerContracts.ts",
|
"./src/Contracts/ExplorerContracts.ts",
|
||||||
|
"./src/Contracts/SelfServeContracts.ts",
|
||||||
"./src/Contracts/SubscriptionType.ts",
|
"./src/Contracts/SubscriptionType.ts",
|
||||||
"./src/Contracts/Versions.ts",
|
"./src/Contracts/Versions.ts",
|
||||||
"./src/Controls/Heatmap/Heatmap.ts",
|
|
||||||
"./src/Controls/Heatmap/HeatmapDatatypes.ts",
|
|
||||||
"./src/DefaultAccountExperienceType.ts",
|
"./src/DefaultAccountExperienceType.ts",
|
||||||
"./src/Definitions/globals.d.ts",
|
|
||||||
"./src/Definitions/html.d.ts",
|
|
||||||
"./src/Definitions/jquery-ui.d.ts",
|
|
||||||
"./src/Definitions/jquery.d.ts",
|
|
||||||
"./src/Definitions/plotly.js-cartesian-dist.d-min.ts",
|
|
||||||
"./src/Definitions/svg.d.ts",
|
|
||||||
"./src/Explorer/Controls/ErrorDisplayComponent/ErrorDisplayComponent.ts",
|
|
||||||
"./src/Explorer/Controls/GitHub/GitHubStyleConstants.ts",
|
"./src/Explorer/Controls/GitHub/GitHubStyleConstants.ts",
|
||||||
"./src/Explorer/Controls/InputTypeahead/InputTypeahead.ts",
|
"./src/Explorer/Controls/InputTypeahead/InputTypeahead.ts",
|
||||||
"./src/Explorer/Controls/SmartUi/InputUtils.ts",
|
"./src/Explorer/Controls/SmartUi/InputUtils.ts",
|
||||||
"./src/Explorer/Graph/GraphExplorerComponent/__mocks__/GremlinClient.ts",
|
"./src/Explorer/Graph/GraphExplorerComponent/ArraysByKeyCache.test.ts",
|
||||||
"./src/Explorer/Graph/GraphExplorerComponent/ArraysByKeyCache.ts",
|
"./src/Explorer/Graph/GraphExplorerComponent/ArraysByKeyCache.ts",
|
||||||
"./src/Explorer/Graph/GraphExplorerComponent/EdgeInfoCache.ts",
|
"./src/Explorer/Graph/GraphExplorerComponent/EdgeInfoCache.ts",
|
||||||
"./src/Explorer/Graph/GraphExplorerComponent/GraphData.ts",
|
"./src/Explorer/Graph/GraphExplorerComponent/GraphData.ts",
|
||||||
"./src/Explorer/Notebook/NotebookComponent/__mocks__/rx-jupyter.ts",
|
|
||||||
"./src/Explorer/Notebook/FileSystemUtil.ts",
|
"./src/Explorer/Notebook/FileSystemUtil.ts",
|
||||||
"./src/Explorer/Notebook/NTeractUtil.ts",
|
"./src/Explorer/Notebook/NTeractUtil.ts",
|
||||||
"./src/Explorer/Notebook/NotebookComponent/actions.ts",
|
"./src/Explorer/Notebook/NotebookComponent/actions.ts",
|
||||||
"./src/Explorer/Notebook/NotebookComponent/loadTransform.ts",
|
"./src/Explorer/Notebook/NotebookComponent/loadTransform.ts",
|
||||||
"./src/Explorer/Notebook/NotebookComponent/reducers.ts",
|
"./src/Explorer/Notebook/NotebookComponent/reducers.ts",
|
||||||
"./src/Explorer/Notebook/NotebookComponent/types.ts",
|
"./src/Explorer/Notebook/NotebookComponent/types.ts",
|
||||||
|
"./src/Explorer/Notebook/NotebookContentClient.ts",
|
||||||
"./src/Explorer/Notebook/NotebookContentItem.ts",
|
"./src/Explorer/Notebook/NotebookContentItem.ts",
|
||||||
|
"./src/Explorer/Notebook/NotebookRenderer/AzureTheme.tsx",
|
||||||
|
"./src/Explorer/Notebook/NotebookRenderer/decorators/CellCreator.tsx",
|
||||||
"./src/Explorer/Notebook/NotebookUtil.ts",
|
"./src/Explorer/Notebook/NotebookUtil.ts",
|
||||||
"./src/Explorer/Tree/AccessibleVerticalList.ts",
|
|
||||||
"./src/Explorer/Panes/PaneComponents.ts",
|
"./src/Explorer/Panes/PaneComponents.ts",
|
||||||
|
"./src/Explorer/Panes/PanelFooterComponent.tsx",
|
||||||
|
"./src/Explorer/Panes/PanelLoadingScreen.tsx",
|
||||||
"./src/Explorer/Panes/Tables/Validators/EntityPropertyNameValidator.ts",
|
"./src/Explorer/Panes/Tables/Validators/EntityPropertyNameValidator.ts",
|
||||||
"./src/Explorer/Panes/Tables/Validators/EntityPropertyValidationCommon.ts",
|
"./src/Explorer/Panes/Tables/Validators/EntityPropertyValidationCommon.ts",
|
||||||
"./src/Explorer/Tables/Constants.ts",
|
"./src/Explorer/Tables/Constants.ts",
|
||||||
"./src/Explorer/Tables/CqlUtilities.ts",
|
"./src/Explorer/Tables/CqlUtilities.ts",
|
||||||
"./src/Explorer/Tables/QueryBuilder/DateTimeUtilities.ts",
|
|
||||||
"./src/Explorer/Tables/DataTable/CacheBase.ts",
|
"./src/Explorer/Tables/DataTable/CacheBase.ts",
|
||||||
"./src/Explorer/Tables/Entities.ts",
|
"./src/Explorer/Tables/Entities.ts",
|
||||||
"./src/Explorer/Notebook/NotebookComponent/__mocks__/rx-jupyter.ts",
|
"./src/Explorer/Tables/QueryBuilder/DateTimeUtilities.test.ts",
|
||||||
"./src/Explorer/Notebook/NotebookContentClient.ts",
|
"./src/Explorer/Tables/QueryBuilder/DateTimeUtilities.ts",
|
||||||
|
"./src/Explorer/Tree/AccessibleVerticalList.ts",
|
||||||
"./src/GitHub/GitHubConnector.ts",
|
"./src/GitHub/GitHubConnector.ts",
|
||||||
|
"./src/HostedExplorerChildFrame.ts",
|
||||||
"./src/Index.ts",
|
"./src/Index.ts",
|
||||||
"./src/NotebookWorkspaceManager/NotebookWorkspaceResourceProviderMockClients.ts",
|
"./src/NotebookWorkspaceManager/NotebookWorkspaceResourceProviderMockClients.ts",
|
||||||
|
"./src/Platform/Hosted/Components/SignInButton.tsx",
|
||||||
|
"./src/Platform/Hosted/extractFeatures.test.ts",
|
||||||
|
"./src/Platform/Hosted/extractFeatures.ts",
|
||||||
"./src/ReactDevTools.ts",
|
"./src/ReactDevTools.ts",
|
||||||
"./src/ResourceProvider/IResourceProviderClient.ts",
|
"./src/ResourceProvider/IResourceProviderClient.ts",
|
||||||
|
"./src/SelfServe/SelfServeStyles.tsx",
|
||||||
|
"./src/SelfServe/SqlX/SqlxTypes.ts",
|
||||||
"./src/Shared/Constants.ts",
|
"./src/Shared/Constants.ts",
|
||||||
|
"./src/Shared/DefaultExperienceUtility.ts",
|
||||||
"./src/Shared/ExplorerSettings.ts",
|
"./src/Shared/ExplorerSettings.ts",
|
||||||
"./src/Shared/PriceEstimateCalculator.ts",
|
"./src/Shared/PriceEstimateCalculator.ts",
|
||||||
|
"./src/Shared/StorageUtility.test.ts",
|
||||||
"./src/Shared/StorageUtility.ts",
|
"./src/Shared/StorageUtility.ts",
|
||||||
|
"./src/Shared/StringUtility.test.ts",
|
||||||
"./src/Shared/StringUtility.ts",
|
"./src/Shared/StringUtility.ts",
|
||||||
"./src/Shared/Telemetry/TelemetryConstants.ts",
|
|
||||||
"./src/Shared/Telemetry/TelemetryProcessor.ts",
|
|
||||||
"./src/Shared/appInsights.ts",
|
"./src/Shared/appInsights.ts",
|
||||||
"./src/Shared/DefaultExperienceUtility.ts",
|
|
||||||
"./src/Terminal/index.ts",
|
|
||||||
"./src/Terminal/JupyterLabAppFactory.ts",
|
|
||||||
"./src/UserContext.ts",
|
"./src/UserContext.ts",
|
||||||
|
"./src/Utils/AutoPilotUtils.ts",
|
||||||
|
"./src/Utils/Base64Utils.test.ts",
|
||||||
"./src/Utils/Base64Utils.ts",
|
"./src/Utils/Base64Utils.ts",
|
||||||
"./src/Utils/BlobUtils.ts",
|
"./src/Utils/BlobUtils.ts",
|
||||||
|
"./src/Utils/GitHubUtils.test.ts",
|
||||||
"./src/Utils/GitHubUtils.ts",
|
"./src/Utils/GitHubUtils.ts",
|
||||||
|
"./src/Utils/MessageValidation.test.ts",
|
||||||
"./src/Utils/MessageValidation.ts",
|
"./src/Utils/MessageValidation.ts",
|
||||||
"./src/Utils/StringUtils.ts",
|
|
||||||
"./src/Utils/WindowUtils.ts",
|
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/types.ts",
|
|
||||||
"./src/Utils/AutoPilotUtils.ts",
|
|
||||||
"./src/Utils/PricingUtils.ts",
|
"./src/Utils/PricingUtils.ts",
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/cassandraResources.ts",
|
"./src/Utils/StringUtils.ts",
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/collection.ts",
|
"./src/Utils/WindowUtils.test.ts",
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/collectionPartition.ts",
|
"./src/Utils/WindowUtils.ts",
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/collectionPartitionRegion.ts",
|
"./src/hooks/useDirectories.tsx",
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/collectionRegion.ts",
|
"./src/i18n.ts",
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/database.ts",
|
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/databaseAccountRegion.ts",
|
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/databaseAccounts.ts",
|
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/gremlinResources.ts",
|
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/mongoDBResources.ts",
|
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/operations.ts",
|
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/partitionKeyRangeId.ts",
|
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/partitionKeyRangeIdRegion.ts",
|
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/percentile.ts",
|
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/percentileSourceTarget.ts",
|
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/percentileTarget.ts",
|
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/sqlResources.ts",
|
|
||||||
"./src/Utils/arm/generatedClients/2020-04-01/tableResources.ts",
|
|
||||||
"./src/Utils/arm/request.ts",
|
|
||||||
"./src/quickstart.ts",
|
"./src/quickstart.ts",
|
||||||
"./src/setupTests.ts",
|
"./src/setupTests.ts",
|
||||||
|
"./src/userContext.test.ts",
|
||||||
"./src/workers/upload/definitions.ts"
|
"./src/workers/upload/definitions.ts"
|
||||||
],
|
],
|
||||||
"include": []
|
"include": [
|
||||||
|
"src/Controls/**/*",
|
||||||
|
"src/Definitions/**/*",
|
||||||
|
"src/Explorer/Controls/ErrorDisplayComponent/**/*",
|
||||||
|
"src/Explorer/Controls/RadioSwitchComponent/**/*",
|
||||||
|
"src/Explorer/Controls/ResizeSensorReactComponent/**/*",
|
||||||
|
"src/Explorer/Graph/GraphExplorerComponent/__mocks__/**/*",
|
||||||
|
"src/Explorer/Notebook/NotebookComponent/__mocks__/**/*",
|
||||||
|
"src/Libs/**/*",
|
||||||
|
"src/Localization/**/*",
|
||||||
|
"src/Platform/Emulator/**/*",
|
||||||
|
"src/Shared/Telemetry/**/*",
|
||||||
|
"src/Terminal/**/*",
|
||||||
|
"src/Utils/arm/**/*"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue