@groma/scanner-go 0.1.0 → 0.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/darwin-arm64/worker +0 -0
- package/dist/linux-arm64/worker +0 -0
- package/dist/linux-x64/worker +0 -0
- package/dist/win32-arm64/worker.exe +0 -0
- package/dist/win32-x64/worker.exe +0 -0
- package/package.json +4 -7
- package/src/index.js +113 -11
package/dist/darwin-arm64/worker
CHANGED
|
Binary file
|
package/dist/linux-arm64/worker
CHANGED
|
Binary file
|
package/dist/linux-x64/worker
CHANGED
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@groma/scanner-go",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "Go project evidence through Go language tooling.",
|
|
5
5
|
"private": false,
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"os": [
|
|
9
|
-
"win32",
|
|
10
9
|
"linux",
|
|
11
|
-
"darwin"
|
|
10
|
+
"darwin",
|
|
11
|
+
"win32"
|
|
12
12
|
],
|
|
13
13
|
"cpu": [
|
|
14
14
|
"arm64",
|
|
@@ -35,10 +35,7 @@
|
|
|
35
35
|
}
|
|
36
36
|
],
|
|
37
37
|
"compatibility": {
|
|
38
|
-
"groma": "^0.3.0"
|
|
39
|
-
"technologyVersions": {
|
|
40
|
-
"go": "1.20.0"
|
|
41
|
-
}
|
|
38
|
+
"groma": "^0.3.0"
|
|
42
39
|
}
|
|
43
40
|
}
|
|
44
41
|
}
|
package/src/index.js
CHANGED
|
@@ -1,9 +1,39 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
// plugins/scanners/go/src/
|
|
2
|
+
// plugins/scanners/go/src/index.ts
|
|
3
|
+
import path5 from "path";
|
|
4
|
+
|
|
5
|
+
// plugins/scanners/projects.ts
|
|
3
6
|
import { execFile } from "child_process";
|
|
4
|
-
import {
|
|
7
|
+
import { existsSync } from "fs";
|
|
5
8
|
import path from "path";
|
|
6
|
-
import {
|
|
9
|
+
import { promisify } from "util";
|
|
10
|
+
var execute = promisify(execFile);
|
|
11
|
+
var excluded = new Set([
|
|
12
|
+
".git",
|
|
13
|
+
"node_modules",
|
|
14
|
+
"vendor",
|
|
15
|
+
"target",
|
|
16
|
+
"dist",
|
|
17
|
+
"build",
|
|
18
|
+
"bin",
|
|
19
|
+
"obj",
|
|
20
|
+
".gradle",
|
|
21
|
+
".angular",
|
|
22
|
+
"coverage",
|
|
23
|
+
"generated",
|
|
24
|
+
"groma",
|
|
25
|
+
".groma"
|
|
26
|
+
]);
|
|
27
|
+
async function projectFiles(root, matches) {
|
|
28
|
+
const { stdout } = await execute("git", ["-C", root, "ls-files", "-z", "--cached", "--others", "--exclude-standard"], { maxBuffer: 64 * 1024 * 1024 });
|
|
29
|
+
return [...new Set(stdout.split("\x00").filter((file) => file && matches(file) && !file.split("/").some((part) => excluded.has(part)) && existsSync(path.join(root, file))))].sort();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// plugins/scanners/project-scanner.ts
|
|
33
|
+
import path3 from "path";
|
|
34
|
+
|
|
35
|
+
// plugins/scanners/observations.ts
|
|
36
|
+
import path2 from "path";
|
|
7
37
|
|
|
8
38
|
// packages/scanner/src/index.ts
|
|
9
39
|
function compare(...values) {
|
|
@@ -259,11 +289,85 @@ function sourcePosition(position) {
|
|
|
259
289
|
return { position: Number(position) };
|
|
260
290
|
}
|
|
261
291
|
|
|
292
|
+
// plugins/scanners/observations.ts
|
|
293
|
+
function relocateObservation(observation, directory) {
|
|
294
|
+
const file = (value) => path2.posix.normalize(path2.posix.join(directory, value));
|
|
295
|
+
return {
|
|
296
|
+
...observation,
|
|
297
|
+
roots: observation.roots.map((root) => ({ ...root, ...root.file ? { file: file(root.file) } : {} })),
|
|
298
|
+
files: observation.files.map((source) => ({ ...source, file: file(source.file) })),
|
|
299
|
+
operations: observation.operations?.map((operation) => ({ ...operation, file: file(operation.file) })),
|
|
300
|
+
invocations: observation.invocations?.map((call) => ({
|
|
301
|
+
...call,
|
|
302
|
+
...call.binding ? { binding: { ...call.binding, file: file(call.binding.file) } } : {}
|
|
303
|
+
})),
|
|
304
|
+
diagnostics: observation.diagnostics.map((item) => ({ ...item, ...item.file ? { file: file(item.file) } : {} }))
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
function combineObservations(parts) {
|
|
308
|
+
if (!parts.length)
|
|
309
|
+
return;
|
|
310
|
+
const roots = [];
|
|
311
|
+
const files = new Map;
|
|
312
|
+
const operations = [];
|
|
313
|
+
const invocations = [];
|
|
314
|
+
const diagnostics = [];
|
|
315
|
+
for (const { key, observation } of parts) {
|
|
316
|
+
const id = (value) => JSON.stringify([key, value]);
|
|
317
|
+
roots.push(...observation.roots.map((root) => ({ ...root, id: id(root.id), ...root.parent ? { parent: id(root.parent) } : {} })));
|
|
318
|
+
for (const source of observation.files) {
|
|
319
|
+
const combined = files.get(source.file) ?? { file: source.file, roots: [], symbols: [] };
|
|
320
|
+
combined.roots.push(...source.roots.map(id));
|
|
321
|
+
combined.symbols.push(...source.symbols.map((symbol) => ({ ...symbol, id: id(symbol.id) })));
|
|
322
|
+
files.set(source.file, combined);
|
|
323
|
+
}
|
|
324
|
+
operations.push(...(observation.operations ?? []).map((operation) => ({ ...operation, id: id(operation.id) })));
|
|
325
|
+
invocations.push(...(observation.invocations ?? []).map((call) => ({ ...call, source: id(call.source), targets: call.targets.map(id) })));
|
|
326
|
+
diagnostics.push(...observation.diagnostics);
|
|
327
|
+
}
|
|
328
|
+
return createScanObservation({
|
|
329
|
+
scanner: parts[0].observation.scanner,
|
|
330
|
+
roots,
|
|
331
|
+
files: [...files.values()],
|
|
332
|
+
operations,
|
|
333
|
+
invocations,
|
|
334
|
+
diagnostics
|
|
335
|
+
});
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// plugins/scanners/project-scanner.ts
|
|
339
|
+
function projectScanner(scanner, select) {
|
|
340
|
+
return {
|
|
341
|
+
...scanner,
|
|
342
|
+
checkReadiness: async (root, settings = {}) => {
|
|
343
|
+
const projects = await select(root, settings);
|
|
344
|
+
if (!projects.length)
|
|
345
|
+
throw new Error(`${scanner.id}: No supported project declaration was found.`);
|
|
346
|
+
for (const project of projects)
|
|
347
|
+
await scanner.checkReadiness?.(project, settings);
|
|
348
|
+
},
|
|
349
|
+
scan: async (root, settings = {}) => {
|
|
350
|
+
const parts = [];
|
|
351
|
+
for (const project of await select(root, settings)) {
|
|
352
|
+
const observation = await scanner.scan(project, settings);
|
|
353
|
+
const key = path3.relative(root, project).split(path3.sep).join("/");
|
|
354
|
+
if (observation)
|
|
355
|
+
parts.push({ key, observation: relocateObservation(observation, key) });
|
|
356
|
+
}
|
|
357
|
+
return combineObservations(parts);
|
|
358
|
+
}
|
|
359
|
+
};
|
|
360
|
+
}
|
|
361
|
+
|
|
262
362
|
// plugins/scanners/go/src/adapter.ts
|
|
363
|
+
import { execFile as execFile2 } from "child_process";
|
|
364
|
+
import { access, realpath } from "fs/promises";
|
|
365
|
+
import path4 from "path";
|
|
366
|
+
import { fileURLToPath } from "url";
|
|
263
367
|
var packagedWorker = fileURLToPath(new URL(`../dist/${process.platform}-${process.arch}/worker${process.platform === "win32" ? ".exe" : ""}`, import.meta.url));
|
|
264
368
|
function run(command, args, root, env = process.env) {
|
|
265
369
|
return new Promise((resolve, reject) => {
|
|
266
|
-
|
|
370
|
+
execFile2(command, args, {
|
|
267
371
|
cwd: root,
|
|
268
372
|
env,
|
|
269
373
|
encoding: "utf8",
|
|
@@ -293,13 +397,10 @@ async function checkGoReadiness(repositoryRoot, options = {}) {
|
|
|
293
397
|
} catch (error) {
|
|
294
398
|
throw new Error(`GO_TOOLCHAIN_MISSING: Install the project's Go toolchain and add its bin directory to PATH (Go 1.27.1 for the qualified example). ${error}`);
|
|
295
399
|
}
|
|
296
|
-
if (context.
|
|
297
|
-
throw new Error("GO_PROJECT_SCOPE:
|
|
298
|
-
}
|
|
299
|
-
if (context.GOMOD !== path.join(root, "go.mod")) {
|
|
300
|
-
throw new Error("GO_PROJECT_SCOPE: Run Groma at the supported Go module root containing go.mod.");
|
|
400
|
+
if (context.GOMOD !== path4.join(root, "go.mod")) {
|
|
401
|
+
throw new Error("GO_PROJECT_SCOPE: The selected project must contain go.mod.");
|
|
301
402
|
}
|
|
302
|
-
env.PATH = `${
|
|
403
|
+
env.PATH = `${path4.join(context.GOROOT, "bin")}${path4.delimiter}${process.env.PATH ?? ""}`;
|
|
303
404
|
try {
|
|
304
405
|
await run(options.go ?? "go", ["list", "-mod=readonly", "-deps", "./..."], root, env);
|
|
305
406
|
} catch (error) {
|
|
@@ -317,7 +418,7 @@ async function scanGoSource(repositoryRoot, options = {}) {
|
|
|
317
418
|
}
|
|
318
419
|
|
|
319
420
|
// plugins/scanners/go/src/index.ts
|
|
320
|
-
var
|
|
421
|
+
var scanner = {
|
|
321
422
|
id: "go",
|
|
322
423
|
watch: { include: ["**/*.go", "**/go.mod", "**/go.sum", "**/go.work"], exclude: [] },
|
|
323
424
|
checkReadiness: async (root) => {
|
|
@@ -325,6 +426,7 @@ var src_default = {
|
|
|
325
426
|
},
|
|
326
427
|
scan: scanGoSource
|
|
327
428
|
};
|
|
429
|
+
var src_default = projectScanner(scanner, async (root) => (await projectFiles(root, (file) => path5.posix.basename(file) === "go.mod")).map((file) => path5.dirname(path5.join(root, file))));
|
|
328
430
|
export {
|
|
329
431
|
src_default as default
|
|
330
432
|
};
|