Skip to content

Commit

Permalink
Improve reference correctness check
Browse files Browse the repository at this point in the history
  • Loading branch information
SebastienGllmt committed Sep 29, 2023
1 parent 02208e4 commit e21d32c
Show file tree
Hide file tree
Showing 14 changed files with 139 additions and 49 deletions.
8 changes: 7 additions & 1 deletion packages/batcher/address-validator/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,11 @@
"outDir": "build"
},
"include": ["src/**/*"],
"references": [{ "path": "../utils" }]
"references": [
{ "path": "../utils" },
{ "path": "../db" },
{ "path": "../../paima-sdk/paima-concise/tsconfig.build.json" },
{ "path": "../../paima-sdk/paima-crypto/tsconfig.build.json" },
{ "path": "../../paima-sdk/paima-utils/tsconfig.build.json" },
]
}
5 changes: 4 additions & 1 deletion packages/batcher/batcher-standalone/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,8 @@
"outDir": "build",
"resolveJsonModule": true
},
"include": ["src/**/*", "src/**/*.json"]
"include": ["src/**/*", "src/**/*.json"],
"references": [
{ "path": "../runtime" },
]
}
8 changes: 7 additions & 1 deletion packages/batcher/batcher-transaction-poster/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,11 @@
"outDir": "build"
},
"include": ["src/**/*"],
"references": [{ "path": "../utils" }]
"references": [
{ "path": "../utils" },
{ "path": "../db" },
{ "path": "../../paima-sdk/paima-providers/tsconfig.build.json" },
{ "path": "../../paima-sdk/paima-concise/tsconfig.build.json" },
{ "path": "../../paima-sdk/paima-utils/tsconfig.build.json" },
]
}
7 changes: 6 additions & 1 deletion packages/batcher/game-input-validator/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,10 @@
"outDir": "build"
},
"include": ["src/**/*"],
"references": [{ "path": "../utils" }, { "path": "../db" }]
"references": [
{ "path": "../utils" },
{ "path": "../db" },
{ "path": "../../paima-sdk/paima-concise/tsconfig.build.json" },
{ "path": "../../paima-sdk/paima-utils/tsconfig.build.json" },
]
}
3 changes: 2 additions & 1 deletion packages/batcher/runtime/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
{ "path": "../webserver/" },
{ "path": "../game-input-validator/" },
{ "path": "../utils" },
{ "path": "../batcher-transaction-poster" }
{ "path": "../batcher-transaction-poster" },
{ "path": "../../paima-sdk/paima-providers/tsconfig.build.json" },
]
}
6 changes: 5 additions & 1 deletion packages/batcher/utils/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
"rootDir": "src",
"outDir": "build"
},
"include": ["src/**/*"]
"include": ["src/**/*"],
"references": [
{ "path": "../../paima-sdk/paima-utils/tsconfig.build.json" },
{ "path": "../../paima-sdk/paima-providers/tsconfig.build.json" },
]
}
5 changes: 4 additions & 1 deletion packages/batcher/webserver/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
"references": [
{ "path": "../address-validator/" },
{ "path": "../db/" },
{ "path": "../utils" }
{ "path": "../utils" },
{ "path": "../../paima-sdk/paima-providers/tsconfig.build.json" },
{ "path": "../../paima-sdk/paima-concise/tsconfig.build.json" },
{ "path": "../../paima-sdk/paima-utils/tsconfig.build.json" },
]
}
11 changes: 10 additions & 1 deletion packages/engine/paima-funnel/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,14 @@
"rootDir": "src",
"outDir": "build"
},
"include": ["src/**/*"]
"include": ["src/**/*"],
"references": [
{ "path": "../../paima-sdk/paima-utils/tsconfig.build.json" },
{ "path": "../paima-runtime" },
{ "path": "../../paima-sdk/paima-prando" },
{ "path": "../../paima-sdk/paima-db" },
{ "path": "../../paima-sdk/paima-utils-backend" },
{ "path": "../../paima-sdk/paima-crypto/tsconfig.build.json" },
{ "path": "../../paima-sdk/paima-concise/tsconfig.build.json" },
]
}
6 changes: 5 additions & 1 deletion packages/engine/paima-runtime/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,9 @@
"rootDir": "src",
"outDir": "build"
},
"include": ["src/**/*"]
"include": ["src/**/*"],
"references": [
{ "path": "../../paima-sdk/paima-utils/tsconfig.build.json" },
{ "path": "../../paima-sdk/paima-db" },
]
}
8 changes: 8 additions & 0 deletions packages/engine/paima-sm/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,12 @@
"outDir": "build"
},
"include": ["src/**/*"],
"references": [
{ "path": "../../paima-sdk/paima-utils/tsconfig.build.json" },
{ "path": "../paima-runtime" },
{ "path": "../../paima-sdk/paima-db" },
{ "path": "../../paima-sdk/paima-prando" },
{ "path": "../../paima-sdk/paima-concise/tsconfig.build.json" },
{ "path": "../../paima-sdk/paima-utils-backend" },
]
}
9 changes: 8 additions & 1 deletion packages/engine/paima-standalone/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,12 @@
"outDir": "build",
"resolveJsonModule": true
},
"include": ["src/**/*", "src/**/*.json"]
"include": ["src/**/*", "src/**/*.json"],
"references": [
{ "path": "../../batcher/batcher-standalone/tsconfig.build.json" },
{ "path": "../paima-runtime" },
{ "path": "../paima-sm" },
{ "path": "../../paima-sdk/paima-utils/tsconfig.build.json" },
{ "path": "../paima-funnel" },
]
}
2 changes: 1 addition & 1 deletion packages/paima-sdk/paima-db/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
"src/**/*.json"
],
"references": [
{ "path": "../paima-utils" }
{ "path": "../paima-utils/tsconfig.build.json" }
]
}
5 changes: 4 additions & 1 deletion packages/paima-sdk/paima-utils-backend/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,8 @@
"resolveJsonModule": true
},
"include": ["src/**/*"],
"references": [{ "path": "../utils" }, { "path": "../db" }]
"references": [
{ "path": "../utils/tsconfig.build.json" },
{ "path": "../db" }
]
}
105 changes: 68 additions & 37 deletions tools/scripts/check-implicit-dependencies.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
const { createProjectGraphAsync } = require('@nx/workspace/src/core/project-graph');
const fs = require('fs');
const JSON5 = require('json5');
const path = require('path');
const { createProjectGraphAsync } =
require('@nx/workspace/src/core/project-graph') as typeof import('@nx/workspace/src/core/project-graph');
const fs = require('fs') as typeof import('fs');
const JSON5 = require('json5') as typeof import('json5');
const path = require('path') as typeof import('path');

/**
* NPM requires us that all packages properly references each other in package.json
Expand All @@ -23,8 +24,20 @@ type DepAndPath = {
dep: string;
};

const libFolders = ['paima-sdk'];
const packageFolders = fs
.readdirSync('./packages', { withFileTypes: true })
.filter(dirent => dirent.isDirectory())
.map(dirent => dirent.name);
function isPackage(path: string): boolean {
for (const pkg of packageFolders) {
if (path.includes(`packages/${pkg}`)) {
return true;
}
}
return false;
}

const libFolders = ['paima-sdk'];
function isLib(path: string): boolean {
for (const lib of libFolders) {
if (path.includes(`packages/${lib}`)) {
Expand All @@ -38,7 +51,7 @@ let hasError = false;
async function main() {
const graph = await createProjectGraphAsync();

const ownPkgs = Object.keys(graph.nodes).filter(key => isLib(graph.nodes[key].data.root));
const ownPkgs = Object.keys(graph.nodes).filter(key => isPackage(graph.nodes[key].data.root));
const ownPkgSet = new Set(ownPkgs);

// cache the content of each package so we can look it up faster later
Expand All @@ -55,6 +68,7 @@ async function main() {

for (const pkg of ownPkgs) {
const pkgJson = packageContent[pkg];
const ownRoot = graph.nodes[pkg].data.root;

const analyzedDeps = new Set(
(graph.dependencies[pkg] as Dep[]).map(dep => dep.target).filter(dep => ownPkgSet.has(dep))
Expand Down Expand Up @@ -85,26 +99,31 @@ async function main() {
}
if (mismatches.length > 0) {
hasError = true;
console.error(`Package ${pkg} has some version mismatches`);
console.error(
`Package ${purpleText(`${ownRoot}/package.json`)} has some version mismatches`
);
for (const mismatch of mismatches) {
console.log(`- "${mismatch.name}": ${mismatch.used}"`);
console.log(`+ "${mismatch.name}": ${mismatch.expected}"`);
console.log(redText(`- "${mismatch.name}": ${mismatch.used}"`));
console.log(greenText(`+ "${mismatch.name}": ${mismatch.expected}"`));
}
console.log();
}
}

// 2) Check that packages are present
{
// Note: adding to package.json is only required if this is a lib we intend to publish
if (isLib(pkg)) {
const remainingDeps = new Set(analyzedDeps);
for (const declaredDep of Object.keys(declaredDeps)) {
remainingDeps.delete(declaredDep);
}
if (remainingDeps.size > 0) {
hasError = true;
console.error(`Package ${pkg} is missing some dependencies`);
console.error(
`Package ${purpleText(`${ownRoot}/package.json`)} is missing some dependencies`
);
for (const dep of Array.from(remainingDeps)) {
console.error(`"${dep}": "${packageContent[dep].version}",`);
console.error(greenText(`"${dep}": "${packageContent[dep].version}",`));
}
console.log();
}
Expand All @@ -117,23 +136,28 @@ async function main() {
dep,
}));

// console.log(`=== ${pkg} ===`);
// console.log(depAndPaths);

const extra: string[] = []; // references that aren't necessary
const wrongPath: { pkg: string; path: string }[] = [];

// allow require to support trailing commas (used in tsconfig.json)
const jsonString = fs.readFileSync(`./${graph.nodes[pkg].data.root}/tsconfig.json`, 'utf-8');
const jsonString = fs.readFileSync(`./${ownRoot}/tsconfig.json`, 'utf-8');
const tsconfigJson = JSON5.parse(jsonString);
for (const ref of tsconfigJson['references'] ?? []) {
const { path } = ref;
const folder = getMeaningfulPartOfPath(path);
const indexOfMatch = depAndPaths.findIndex(depthAndPath =>
depthAndPath.path.endsWith(folder)
);
// console.log(folder, indexOfMatch);
if (indexOfMatch === -1) {
extra.push(folder);
} else {
const fileRef = getFilenameFromPath(path);
if (hasBuildConfig[pkg]) {
// console.log(fileRef, pkg, hasBuildConfig[depAndPaths[indexOfMatch].dep]);
if (hasBuildConfig[depAndPaths[indexOfMatch].dep]) {
if (fileRef !== 'tsconfig.build.json') {
wrongPath.push({ pkg, path: path });
hasError = true;
Expand All @@ -144,25 +168,39 @@ async function main() {
}
if (wrongPath.length > 0) {
hasError = true;
console.error(`Package ${pkg} tsconfig.json has some incorrect references`);
console.error(
`Package ${purpleText(`${ownRoot}/tsconfig.json`)} has some incorrect references`
);
for (const path of wrongPath) {
console.error(`${path.path}${path.path}/tsconfig.build.json`);
console.error(`${redText(path.path)}${greenText(`${path.path}/tsconfig.build.json`)}`);
}
console.log();
}
if (extra.length > 0) {
hasError = true;
console.error(`Package ${pkg} tsconfig.json has unnecessary references`);
console.error(
`Package ${purpleText(`${ownRoot}/tsconfig.json`)} has unnecessary references`
);
for (const ref of extra) {
console.error(ref);
console.error(redText(ref));
}
console.log();
}
if (depAndPaths.length > 0) {
hasError = true;
console.error(`Package ${pkg} tsconfig.json is missing some references`);
for (const dep of depAndPaths) {
console.error(dep.dep);
console.error(
`Package ${purpleText(`${ownRoot}/tsconfig.json`)} is missing some references`
);
for (const depAndPath of depAndPaths) {
const basePath = path.relative(ownRoot, depAndPath.path);
hasBuildConfig[depAndPath.dep];
console.error(
greenText(
`{ "path": "${
hasBuildConfig[depAndPath.dep] ? `${basePath}/tsconfig.build.json` : basePath
}" },`
)
);
}
console.log();
}
Expand All @@ -189,24 +227,13 @@ function getMeaningfulPartOfPath(inputPath: string) {
pathParts.pop();
}

return pathParts.join(path.sep);
}

function getFileForPath(inputPath: string) {
const normalizedPath = path.normalize(inputPath);
const pathParts = normalizedPath.split(path.sep);

// Remove '..' and '.' from the beginning
while (pathParts.length && (pathParts[0] === '..' || pathParts[0] === '.')) {
pathParts.shift();
}
const result = pathParts.join(path.sep);

// Remove the filename
if (pathParts.length && path.extname(pathParts[pathParts.length - 1]) !== '') {
pathParts.pop();
// normalize by removing any trailing slash
if (result.endsWith('/')) {
return result.slice(0, -1);
}

return pathParts.join(path.sep);
return result;
}

function getFilenameFromPath(filePath: string): string | null {
Expand All @@ -216,4 +243,8 @@ function getFilenameFromPath(filePath: string): string | null {
return baseName && baseName.includes('.') ? baseName : null;
}

const greenText = (text: string) => `\x1b[32m${text}\x1b[0m`;
const redText = (text: string) => `\x1b[31m${text}\x1b[0m`;
const purpleText = (text: string) => `\x1b[35m${text}\x1b[0m`;

void main();

0 comments on commit e21d32c

Please sign in to comment.