mirror of
https://github.com/Azure/cosmos-explorer.git
synced 2025-12-20 01:11:25 +00:00
Initial Move from Azure DevOps to GitHub
This commit is contained in:
1
strict-migration-tools/.gitignore
vendored
Normal file
1
strict-migration-tools/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
node_modules
|
||||
25
strict-migration-tools/README.md
Normal file
25
strict-migration-tools/README.md
Normal file
@@ -0,0 +1,25 @@
|
||||
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
|
||||
```
|
||||
55
strict-migration-tools/autoAdd.js
Normal file
55
strict-migration-tools/autoAdd.js
Normal file
@@ -0,0 +1,55 @@
|
||||
// @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);
|
||||
});
|
||||
}
|
||||
53
strict-migration-tools/index.js
Normal file
53
strict-migration-tools/index.js
Normal file
@@ -0,0 +1,53 @@
|
||||
// @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)}"\``;
|
||||
// }
|
||||
90
strict-migration-tools/package-lock.json
generated
Normal file
90
strict-migration-tools/package-lock.json
generated
Normal file
@@ -0,0 +1,90 @@
|
||||
{
|
||||
"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="
|
||||
}
|
||||
}
|
||||
}
|
||||
17
strict-migration-tools/package.json
Normal file
17
strict-migration-tools/package.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"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"
|
||||
}
|
||||
}
|
||||
3
strict-migration-tools/src/config.js
Normal file
3
strict-migration-tools/src/config.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports.targetTsconfig = "../tsconfig.strict.json";
|
||||
|
||||
module.exports.skippedFiles = new Set([]);
|
||||
@@ -0,0 +1,94 @@
|
||||
// @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;
|
||||
}
|
||||
44
strict-migration-tools/src/tsHelper.js
Normal file
44
strict-migration-tools/src/tsHelper.js
Normal file
@@ -0,0 +1,44 @@
|
||||
// @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}`);
|
||||
});
|
||||
};
|
||||
Reference in New Issue
Block a user