-
Notifications
You must be signed in to change notification settings - Fork 6
/
introspection.ts
63 lines (53 loc) · 1.68 KB
/
introspection.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
import { log } from "../../deps.ts";
import { context } from "../plugin/mod.ts";
import { introspectors, ProjectData } from "../../plugins/stack/mod.ts";
export type Stack = Record<string, ProjectData>;
/**
* Run the detect function for each introspector and filter
* the ones which detected the stack in the analyzed project.
*
* Returns the relevant introspectors for the analyzed project
*/
async function detected() {
const detected = await Promise.all(
introspectors
.map((introspector) => introspector.detect(context)),
);
return introspectors.filter((_, i) => detected[i]);
}
type Maybe<T> = T | undefined;
// Type predicate to filter undefined values
function isDefined<T>(v: Maybe<T>): v is T {
return v !== undefined;
}
/**
* Introspect each stack detected in the project and returns an object
* with the stack as a key and the introspected data as the value
*
* Example:
* ```ts
* { javascript: { runtime: { name: "deno" }, packageManager: null } }
* ```
*/
export async function introspect() {
const logger = log.getLogger("main");
logger.info("Detecting stack...");
const stack = await detected();
const stackNames = stack.map((t) => t.name).sort().join(", ");
logger.info(`Detected stack: ${stackNames}`);
const introspected = (await Promise.all(
stack.map<Promise<Maybe<ProjectData>>>((introspector) =>
introspector.introspect(context)
),
));
const data = stack
.reduce((obj, introspector, i) => {
const data = introspected[i];
if (isDefined(data)) {
obj[introspector.name] = data;
}
return obj;
}, {} as Stack);
logger.debug(`Introspected data: ${JSON.stringify(data)}`);
return data;
}