Skip to content

Instantly share code, notes, and snippets.

@lynchbomb
Created July 12, 2023 13:52
Show Gist options
  • Save lynchbomb/84115ee2f11731dbb2fa9aa08d681191 to your computer and use it in GitHub Desktop.
Save lynchbomb/84115ee2f11731dbb2fa9aa08d681191 to your computer and use it in GitHub Desktop.
Get Missing Types
import { execaSync } from 'execa';
import { readFileSync, unlinkSync, readdirSync, writeFileSync } from 'node:fs';
import { join } from 'node:path';
const rehearsalBinary = join('../rehearsal-js/packages/cli/bin/rehearsal.js');
interface EdgeEntry {
packageName: string;
hasTypes: boolean;
fileName: string;
missing: boolean;
}
interface FileEntry {
name: string;
hasTypes: boolean;
edges: EdgeEntry[];
}
interface GraphEntry {
name: string;
external: boolean;
files: FileEntry[];
}
interface GraphReturn {
missingTypes: string[];
packageName: string;
}
function runGraph(packagePath: string): GraphReturn {
console.log(`Running rehearsal graph on ${packagePath}`);
execaSync(
rehearsalBinary,
[
'graph',
packagePath,
'-o',
'graph.json',
'-x',
],
{ stdio: 'ignore' }
);
const graph = readFileSync(join('./graph.json'));
const graphEntries = JSON.parse(graph.toString());
const entries: string[] = [];
graphEntries.forEach((entry: GraphEntry) => {
if (entry) {
let isTyped = true;
const { files } = entry;
files.forEach((file) => {
// make sure we're only dealing with external deps
if (file.name.includes('node_modules')) {
if (!file.hasTypes) {
isTyped = false;
}
}
});
if (!isTyped) {
entries.push(entry.name);
}
}
});
// delete the graph.json file
unlinkSync('./graph.json');
return {
missingTypes: entries,
packageName: packagePath,
}
}
function execOnAddon(packageAddons: string[]): Set<string> {
const missingTypesSet: Set<string> = new Set();
// run rehearsal graph over each package, read the graph.json file, and parse it
// into a GraphEntry object
packageAddons.forEach((packagePath) => {
try {
const { missingTypes, packageName } = runGraph(packagePath);
// add the missing types to the missingTypes set
missingTypes.forEach((entry) => {
missingTypesSet.add(entry);
});
// if missingTypes is not empty
if (missingTypes.length > 0) {
// append packageName and missingTypes into a text file
writeFileSync('./missingTypes.txt', `addon-name: ${packageName}\n${missingTypes.join('\n')}\n\n\n`, { flag: 'a' });
}
} catch (error) {
//
}
});
return missingTypesSet;
}
function getMissingTypes(): void {
const packageAddons: string[] = [];
// open a file to write the missing types to
writeFileSync('./missingTypes.txt', '');
// loop over all internal packages at './packages/addons' and push the absolute path
// to the packageAddons array
readdirSync('./packages/addons').forEach((packageDir: string) => {
packageAddons.push(join('./packages/addons', packageDir));
});
const missingTypes = execOnAddon(packageAddons);
// print out the missing types
missingTypes.forEach((missingType) => {
console.log(missingType);
});
}
getMissingTypes();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment