Skip to content

Commit

Permalink
Move graph.dot file to the top-level 'repo' directory (#1079)
Browse files Browse the repository at this point in the history
  • Loading branch information
tiagobento authored Jul 11, 2022
1 parent 233f709 commit 9564799
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 176 deletions.
4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@
},
"scripts": {
"install-dependencies": "pnpm install --strict-peer-dependencies=false",
"bootstrap": "pnpm install-dependencies && node ./scripts/link_packages_with_self.js",
"link-packages-with-self": "node ./scripts/link_packages_with_self.js",
"generate-packages-graph": "node ./scripts/generate_packages_graph.js ./repo",
"bootstrap": "pnpm install-dependencies && pnpm link-packages-with-self && pnpm generate-packages-graph",
"build-env": "node packages/build-env/cli.js",
"env:print": "pnpm build-env --print-env",
"env:vars": "pnpm build-env --print-vars",
Expand Down
2 changes: 1 addition & 1 deletion packages/build-env/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This package contains the tooling to handle environment variables and other buil

#### Packages dependency graph

![KIE Tools packages dependency graph](https://g.gravizo.com/source/svg?https%3A%2F%2Fraw.githubusercontent.com%2Fkiegroup%2Fkie-tools%2Fmain%2Fpackages%2Fbuild-env%2Fgraph.dot)
![KIE Tools packages dependency graph](https://g.gravizo.com/source/svg?https%3A%2F%2Fraw.githubusercontent.com%2Fkiegroup%2Fkie-tools%2Fmain%2Frepo%2Fgraph.dot)

Nodes:

Expand Down
108 changes: 0 additions & 108 deletions packages/build-env/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@
*/

const buildEnv = require("./index");
const graphviz = require("graphviz");
const { getPackagesSync } = require("@lerna/project");
const fs = require("fs");
const path = require("path");
const { spawnSync } = require("child_process");

async function main() {
Expand All @@ -40,110 +36,6 @@ async function main() {
process.exit(0);
}

if (opt === "--build-graph") {
const packages = getPackagesSync();
const packageMap = new Map(packages.map((p) => [p.name, p]));
const packageNames = new Set(packages.map((p) => p.name));

const adjMatrix = {};
for (const pkg of packages) {
adjMatrix[pkg.name] = adjMatrix[pkg.name] ?? {};
const dependencies = Object.keys(pkg.dependencies ?? {}).sort();
for (const depName of dependencies) {
if (packageNames.has(depName)) {
adjMatrix[pkg.name][depName] = "dependency";
}
}
const devDependencies = Object.keys(pkg.devDependencies ?? {}).sort();
for (const depName of devDependencies) {
if (packageNames.has(depName)) {
adjMatrix[pkg.name][depName] = "devDependency";
}
}
}

// transitive reduction
const trMatrix = JSON.parse(JSON.stringify(adjMatrix));
for (const s in trMatrix)
for (const u in trMatrix)
if (trMatrix[u][s] === "dependency" || trMatrix[u][s] === "devDependency" || trMatrix[u][s] === "transitive")
for (const v in trMatrix)
if (
trMatrix[s][v] === "dependency" ||
trMatrix[s][v] === "devDependency" ||
trMatrix[s][v] === "transitive"
) {
trMatrix[u][v] = "transitive";
}

const resMatrix = trMatrix;

// print graph
const g = graphviz.digraph("G");

g.use = "dot";
g.set("ranksep", "2");
g.set("splines", "polyline");
g.set("rankdir", "TB");
g.set("ordering", "out");

g.setNodeAttribut("shape", "box");

g.setEdgeAttribut("headport", "n");
g.setEdgeAttribut("tailport", "s");
g.setEdgeAttribut("arrowhead", "dot");
g.setEdgeAttribut("arrowsize", "0.5");

const root = g.addNode("kiegroup/kie-tools");
root.set("shape", "folder");

for (const pkgName in resMatrix) {
const displayPkgName = pkgName;

const pkgProperties = (() => {
if (pkgName.startsWith("@kie-tools-examples") || pkgName.startsWith("kie-tools-examples-")) {
return { color: "orange", nodeStyle: "dashed, rounded" };
} else if (packageMap.get(pkgName)?.private) {
return { color: "black", nodeStyle: "dashed, rounded" };
} else if (pkgName.startsWith("@kie-tools-core")) {
return { color: "purple", nodeStyle: "rounded" };
} else {
return { color: "blue", nodeStyle: "rounded" };
}
})();

const node = g.addNode(displayPkgName);
node.set("color", pkgProperties.color);
node.set("fontcolor", pkgProperties.color);
node.set("style", pkgProperties.nodeStyle);

if (Object.keys(resMatrix[pkgName]).length === 0) {
g.addEdge(displayPkgName, root, {});
}

for (const depName in resMatrix[pkgName]) {
const displayDepName = depName;
if (resMatrix[pkgName][depName] === "dependency") {
const edge = g.addEdge(displayPkgName, displayDepName, {});
edge.set("style", "solid");
edge.set("color", pkgProperties.color);
} else if (resMatrix[pkgName][depName] === "devDependency") {
const edge = g.addEdge(displayPkgName, displayDepName, {});
edge.set("style", "dashed");
edge.set("color", pkgProperties.color);
} else if (resMatrix[pkgName][depName] === "transitive") {
// ignore
}
}
}

const outputFilePath = path.resolve(__dirname, "graph.dot");
fs.writeFileSync(outputFilePath, g.to_dot());

console.info(`[build-env] Wrote dependency graph to '${outputFilePath}'`);
process.exit(0);
}

if (opt === "--print-env") {
const result = {};
const vars = buildEnv.vars().ENV_VARS;
Expand Down
2 changes: 1 addition & 1 deletion packages/build-env/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"url": "https://github.com/kiegroup/kie-tools.git"
},
"scripts": {
"print-build-env": "rimraf dist && node ./cli.js --print-cli-tools-check && node ./cli.js --print-env && node ./cli.js --print-config && node ./cli.js --build-graph",
"print-build-env": "rimraf dist && node ./cli.js --print-cli-tools-check && node ./cli.js --print-env && node ./cli.js --print-config",
"build:dev": "pnpm print-build-env",
"build:prod": "pnpm print-build-env"
},
Expand Down
File renamed without changes.
137 changes: 137 additions & 0 deletions scripts/generate_packages_graph.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* Copyright 2022 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

const graphviz = require("graphviz");
const { getPackagesSync } = require("@lerna/project");
const fs = require("fs");
const path = require("path");

const targetDir = process.argv[2];

function main() {
if (!targetDir) {
console.error("Please specify the path where the graph.dot file will be written to.");
process.exit(1);
}

const packages = getPackagesSync();
const packageMap = new Map(packages.map((p) => [p.name, p]));
const packageNames = new Set(packages.map((p) => p.name));

const adjMatrix = {};
for (const pkg of packages) {
adjMatrix[pkg.name] = adjMatrix[pkg.name] ?? {};
const dependencies = Object.keys(pkg.dependencies ?? {}).sort();
for (const depName of dependencies) {
if (packageNames.has(depName)) {
adjMatrix[pkg.name][depName] = "dependency";
}
}
const devDependencies = Object.keys(pkg.devDependencies ?? {}).sort();
for (const depName of devDependencies) {
if (packageNames.has(depName)) {
adjMatrix[pkg.name][depName] = "devDependency";
}
}
}

// transitive reduction
const trMatrix = JSON.parse(JSON.stringify(adjMatrix));
for (const s in trMatrix)
for (const u in trMatrix)
if (trMatrix[u][s] === "dependency" || trMatrix[u][s] === "devDependency" || trMatrix[u][s] === "transitive")
for (const v in trMatrix)
if (
trMatrix[s][v] === "dependency" ||
trMatrix[s][v] === "devDependency" ||
trMatrix[s][v] === "transitive"
) {
trMatrix[u][v] = "transitive";
}

const resMatrix = trMatrix;

// print graph
const g = graphviz.digraph("G");

g.use = "dot";
g.set("ranksep", "2");
g.set("splines", "polyline");
g.set("rankdir", "TB");
g.set("ordering", "out");

g.setNodeAttribut("shape", "box");

g.setEdgeAttribut("headport", "n");
g.setEdgeAttribut("tailport", "s");
g.setEdgeAttribut("arrowhead", "dot");
g.setEdgeAttribut("arrowsize", "0.5");

const root = g.addNode("kiegroup/kie-tools");
root.set("shape", "folder");

for (const pkgName in resMatrix) {
const displayPkgName = pkgName;

const pkgProperties = (() => {
if (pkgName.startsWith("@kie-tools-examples") || pkgName.startsWith("kie-tools-examples-")) {
return { color: "orange", nodeStyle: "dashed, rounded" };
} else if (packageMap.get(pkgName)?.private) {
return { color: "black", nodeStyle: "dashed, rounded" };
} else if (pkgName.startsWith("@kie-tools-core")) {
return { color: "purple", nodeStyle: "rounded" };
} else {
return { color: "blue", nodeStyle: "rounded" };
}
})();

const node = g.addNode(displayPkgName);
node.set("color", pkgProperties.color);
node.set("fontcolor", pkgProperties.color);
node.set("style", pkgProperties.nodeStyle);

if (Object.keys(resMatrix[pkgName]).length === 0) {
g.addEdge(displayPkgName, root, {});
}

for (const depName in resMatrix[pkgName]) {
const displayDepName = depName;
if (resMatrix[pkgName][depName] === "dependency") {
const edge = g.addEdge(displayPkgName, displayDepName, {});
edge.set("style", "solid");
edge.set("color", pkgProperties.color);
} else if (resMatrix[pkgName][depName] === "devDependency") {
const edge = g.addEdge(displayPkgName, displayDepName, {});
edge.set("style", "dashed");
edge.set("color", pkgProperties.color);
} else if (resMatrix[pkgName][depName] === "transitive") {
// ignore
}
}
}

if (!fs.existsSync(path.resolve(targetDir))) {
fs.mkdirSync(path.resolve(targetDir));
}
const outputFilePath = path.join(targetDir, "graph.dot");
fs.writeFileSync(outputFilePath, g.to_dot());

console.info(`[generate-packages-graph] Wrote packages graph to '${outputFilePath}'`);
console.info(`[generate-packages-graph] Done.`);
process.exit(0);
}

main();
50 changes: 37 additions & 13 deletions scripts/link_packages_with_self.js
Original file line number Diff line number Diff line change
@@ -1,27 +1,51 @@
/*
* Copyright 2022 Red Hat, Inc. and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

const { getPackagesSync } = require("@lerna/project");
const fs = require("fs");
const path = require("path");

getPackagesSync().forEach((pkg) => {
const isScopedPackage = pkg.name.includes("@");
function main() {
getPackagesSync().forEach((pkg) => {
const isScopedPackage = pkg.name.includes("@");

if (isScopedPackage) {
const [pkgScope, pkgSimpleName] = pkg.name.split("/");
fs.mkdirSync(path.join(pkg.location, "node_modules", pkgScope), { recursive: true });
const selfLinkPath = path.join(pkg.location, "node_modules", pkgScope, pkgSimpleName);
selfLink(pkg, selfLinkPath);
return;
}
if (isScopedPackage) {
const [pkgScope, pkgSimpleName] = pkg.name.split("/");
fs.mkdirSync(path.join(pkg.location, "node_modules", pkgScope), { recursive: true });
const selfLinkPath = path.join(pkg.location, "node_modules", pkgScope, pkgSimpleName);
selfLink(pkg, selfLinkPath);
return;
}

const selfLinkPath = path.join(pkg.location, "node_modules", pkg.name);
selfLink(pkg, selfLinkPath);
});
const selfLinkPath = path.join(pkg.location, "node_modules", pkg.name);
selfLink(pkg, selfLinkPath);
});
console.info(`[link-packages-with-self] Done.`);
process.exit(0);
}

function selfLink(pkg, selfLinkPath) {
const relTargetPath = path.relative(path.dirname(selfLinkPath), pkg.location);
if (fs.existsSync(selfLinkPath)) {
fs.unlinkSync(selfLinkPath);
}
fs.symlinkSync(relTargetPath, selfLinkPath);
console.info(`Self-linking '${pkg.name}'. ${path.relative(pkg.location, selfLinkPath)} -> ${relTargetPath}`);
console.info(
`[link-packages-with-self] Linking '${pkg.name}'. ${path.relative(pkg.location, selfLinkPath)} -> ${relTargetPath}`
);
}

main();
Loading

0 comments on commit 9564799

Please sign in to comment.