This repository has been archived by the owner on Jan 8, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 9
/
Copy pathgendeps2.ts
129 lines (109 loc) · 3.97 KB
/
gendeps2.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import { readFile, readdir } from "fs/promises";
import { join, sep } from "path";
import { parse } from "./parse";
type TypeInformation = {
fullType: string;
complexTypes: string[];
msgDefinitionString: string;
};
async function main() {
if (process.argv.length !== 4) {
console.error("Usage: gendeps <msgdefs-dir> <msg-file>");
process.exit(1);
}
const rootPath = process.argv[2]!;
const filename = process.argv[3]!;
const fullTypeName = getFullTypeFromFilename(filename, rootPath);
const res = await loadType(fullTypeName, rootPath, getPackageName(fullTypeName));
console.log(res.msgDefinitionString);
const complexTypes = res.complexTypes;
const seenTypes = new Set<string>();
seenTypes.add(res.fullType);
while (complexTypes.length > 0) {
const complexType = complexTypes.shift()!;
const curRes = await loadType(complexType, rootPath, getPackageName(complexType));
console.log("================================================================================");
console.log(`MSG: ${curRes.fullType}`);
console.log(curRes.msgDefinitionString);
for (const complexSubType of curRes.complexTypes) {
if (!seenTypes.has(complexSubType)) {
complexTypes.push(complexSubType);
seenTypes.add(complexSubType);
}
}
}
}
function getFullType(typeName: string, currentPackage: string | undefined): string {
if (typeName.includes("/")) {
return typeName;
}
if (!currentPackage) {
throw new Error(`Cannot resolve relative type name ${typeName}`);
}
return `${currentPackage}/${typeName}`;
}
function getPackageName(typeName: string): string {
return typeName.split("/")[0]!;
}
function getBaseType(typeName: string): string {
return typeName.split("/").pop()!;
}
async function loadType(
typeName: string,
rootPath: string,
currentPackage: string,
): Promise<TypeInformation> {
const fullType = getFullType(typeName, currentPackage);
const packageName = getPackageName(fullType);
const baseType = getBaseType(typeName);
const msgDefinitionString = await readFileFromBaseDir(
`${baseType}.msg`,
join(rootPath, packageName),
);
if (msgDefinitionString == undefined) {
throw new Error(
`Failed to load definition for type ${typeName} (current package: ${currentPackage})`,
);
}
const complexTypes: string[] = [];
const msgDefinitions = parse(msgDefinitionString, { ros2: true, skipTypeFixup: true });
for (const msgdef of msgDefinitions) {
for (const definition of msgdef.definitions) {
if (definition.isComplex === true && !complexTypes.includes(definition.type)) {
complexTypes.push(getFullType(definition.type, currentPackage));
}
}
}
return { fullType, complexTypes, msgDefinitionString };
}
function getFullTypeFromFilename(filename: string, rootPath: string): string {
const pathParts = rootPath.split(sep);
const filenameParts = filename.replace(/\.msg$/, "").split(sep);
// Remove pathParts from msgFileParts
for (const pathPart of pathParts) {
if (pathPart !== filenameParts[0]) {
console.log(`${pathPart} !== ${filenameParts[0]!}`);
throw new Error(`<msg-file> "${filename}" must be under <msgdefs-dir> "${rootPath}"`);
}
filenameParts.shift();
}
const packageName = filenameParts.shift()!;
const baseType = filenameParts[filenameParts.length - 1]!;
return `${packageName}/${baseType}`;
}
// Recursively search inside a directory for a file with a given name
async function readFileFromBaseDir(filename: string, baseDir: string): Promise<string | undefined> {
const files = await readdir(baseDir, { withFileTypes: true });
for (const file of files) {
if (file.isDirectory()) {
const contents = await readFileFromBaseDir(filename, join(baseDir, file.name));
if (contents != undefined) {
return contents;
}
} else if (file.isFile() && file.name === filename) {
return await readFile(join(baseDir, file.name), { encoding: "utf8" });
}
}
return undefined;
}
void main();