forked from nrwl/nx
-
Notifications
You must be signed in to change notification settings - Fork 0
/
project-graph-utils.ts
121 lines (104 loc) · 3.35 KB
/
project-graph-utils.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
import { normalizePath, ProjectGraph, ProjectGraphNode } from '@nrwl/devkit';
import { relative } from 'path';
import { readCachedProjectGraph } from '../core/project-graph';
export function projectHasTarget(project: ProjectGraphNode, target: string) {
return project.data && project.data.targets && project.data.targets[target];
}
export function projectHasTargetAndConfiguration(
project: ProjectGraphNode,
target: string,
configuration: string
) {
return (
projectHasTarget(project, target) &&
project.data.targets[target].configurations &&
project.data.targets[target].configurations[configuration]
);
}
export function getSourceDirOfDependentProjects(
projectName: string,
projectGraph = readCachedProjectGraph()
): string[] {
if (!projectGraph.nodes[projectName]) {
throw new Error(
`Couldn't find project "${projectName}" in this Nx workspace`
);
}
const nodeNames = findAllProjectNodeDependencies(projectName, projectGraph);
return nodeNames.map(
(nodeName) => projectGraph.nodes[nodeName].data.sourceRoot
);
}
/**
* Finds the project node name by a file that lives within it's src root
* @param projRelativeDirPath directory path relative to the workspace root
* @param projectGraph
*/
export function getProjectNameFromDirPath(
projRelativeDirPath: string,
projectGraph = readCachedProjectGraph()
) {
let parentNodeName = null;
for (const [nodeName, node] of Object.entries(projectGraph.nodes)) {
const normalizedRootPath = normalizePath(node.data.root);
const normalizedProjRelPath = normalizePath(projRelativeDirPath);
const relativePath = relative(normalizedRootPath, normalizedProjRelPath);
const isMatch = relativePath && !relativePath.startsWith('..');
if (isMatch || normalizedRootPath === normalizedProjRelPath) {
parentNodeName = nodeName;
break;
}
}
if (!parentNodeName) {
throw new Error(
`Could not find any project containing the file "${projRelativeDirPath}" among it's project files`
);
}
return parentNodeName;
}
/**
* Find all internal project dependencies.
* All the external (npm) dependencies will be filtered out
* @param {string} parentNodeName
* @param {ProjectGraph} projectGraph
* @returns {string[]}
*/
function findAllProjectNodeDependencies(
parentNodeName: string,
projectGraph = readCachedProjectGraph()
): string[] {
const dependencyNodeNames = new Set<string>();
collectDependentProjectNodesNames(
projectGraph,
dependencyNodeNames,
parentNodeName
);
return Array.from(dependencyNodeNames);
}
// Recursively get all the dependencies of the node
function collectDependentProjectNodesNames(
nxDeps: ProjectGraph,
dependencyNodeNames: Set<string>,
parentNodeName: string
) {
const dependencies = nxDeps.dependencies[parentNodeName];
if (!dependencies) {
// no dependencies for the given node, so silently return,
// as we probably wouldn't want to throw here
return;
}
for (const dependency of dependencies) {
const dependencyName = dependency.target;
// we're only intersted in project dependencies, not npm
if (dependencyName.startsWith('npm:')) {
continue;
}
dependencyNodeNames.add(dependencyName);
// Get the dependencies of the dependencies
collectDependentProjectNodesNames(
nxDeps,
dependencyNodeNames,
dependencyName
);
}
}