Skip to content

Commit 071f557

Browse files
committed
fix(core): read dependencies via dotnet list reference
1 parent 80bcb04 commit 071f557

File tree

14 files changed

+450
-238
lines changed

14 files changed

+450
-238
lines changed

.github/workflows/main.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ concurrency:
1212
jobs:
1313
main:
1414
name: Nx Cloud - Main Job
15-
uses: nrwl/ci/.github/workflows/nx-cloud-main.yml@v0.8
15+
uses: nrwl/ci/.github/workflows/nx-cloud-main.yml@v0.15
1616
with:
1717
main-branch-name: 'master'
1818
parallel-commands: |
@@ -25,6 +25,6 @@ jobs:
2525
2626
agents:
2727
name: Nx Cloud - Agents
28-
uses: nrwl/ci/.github/workflows/nx-cloud-agents.yml@v0.8
28+
uses: nrwl/ci/.github/workflows/nx-cloud-agents.yml@v0.15
2929
with:
3030
number-of-agents: 3

.github/workflows/pr.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ concurrency:
1414
jobs:
1515
main:
1616
name: Nx Cloud - Main Job
17-
uses: nrwl/ci/.github/workflows/nx-cloud-main.yml@v0.8
17+
uses: nrwl/ci/.github/workflows/nx-cloud-main.yml@v0.15
1818
with:
1919
main-branch-name: 'master'
2020
parallel-commands: |
@@ -26,6 +26,6 @@ jobs:
2626
2727
agents:
2828
name: Nx Cloud - Agents
29-
uses: nrwl/ci/.github/workflows/nx-cloud-agents.yml@v0.8
29+
uses: nrwl/ci/.github/workflows/nx-cloud-agents.yml@v0.15
3030
with:
3131
number-of-agents: 3

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -655,7 +655,7 @@ Co-authored-by: Craigory Coppola <craigorycoppola@gmail.com>
655655

656656
### Bug Fixes
657657

658-
- **utils:** getDependantProjectsForNxProject should work on Unix ([96cbc33](https://github.com/nx-dotnet/nx-dotnet/commit/96cbc33ec6b5e9d0492fba4902ee76938230b146)), closes [#43](https://github.com/nx-dotnet/nx-dotnet/issues/43)
658+
- **utils:** forEachDependantProject should work on Unix ([96cbc33](https://github.com/nx-dotnet/nx-dotnet/commit/96cbc33ec6b5e9d0492fba4902ee76938230b146)), closes [#43](https://github.com/nx-dotnet/nx-dotnet/issues/43)
659659

660660
## [0.6.1](https://github.com/nx-dotnet/nx-dotnet/compare/v0.6.0...v0.6.1) (2021-05-19)
661661

nx.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
"nugetPackages": {
99
"Swashbuckle.AspNetCore": "6.5.0"
1010
}
11-
}
11+
},
12+
"include": ["demo/**/*"]
1213
}
1314
],
1415
"generators": {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { workspaceRoot } from '@nx/devkit';
2+
import { resolveReferenceToProject } from './create-dependencies';
3+
4+
describe('createDependencies', () => {
5+
describe('resolveReferenceToProject', () => {
6+
it('should find project in rootMap', () => {
7+
expect(
8+
resolveReferenceToProject(
9+
'../../libs/my-lib/MyLib.csproj',
10+
'apps/my-app/MyApp.csproj',
11+
{
12+
'libs/my-lib': 'my-lib',
13+
'apps/my-app': 'my-app',
14+
},
15+
{
16+
workspaceRoot,
17+
},
18+
),
19+
).toEqual('my-lib');
20+
});
21+
});
22+
});

packages/core/src/graph/create-dependencies.ts

Lines changed: 77 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
import {
22
CreateDependencies,
33
CreateDependenciesContext,
4+
DependencyType,
45
NxPluginV1,
6+
ProjectConfiguration,
57
ProjectGraphBuilder,
68
RawProjectGraphDependency,
9+
normalizePath,
710
workspaceRoot,
811
} from '@nx/devkit';
9-
import { parse } from 'node:path';
12+
import { dirname, parse, relative, resolve } from 'node:path';
1013

11-
import {
12-
getDependenciesFromXmlFile,
13-
NxDotnetConfig,
14-
readConfig,
15-
} from '@nx-dotnet/utils';
14+
import { NxDotnetConfig, readConfig } from '@nx-dotnet/utils';
15+
import { DotNetClient, dotnetFactory } from '@nx-dotnet/dotnet';
1616

1717
// Between Nx versions 16.8 and 17, the signature of `CreateDependencies` changed.
1818
// It used to only consist of the context, but now it also includes the options.
@@ -29,6 +29,8 @@ type CreateDependenciesCompat<T> = {
2929
): ReturnType<CreateDependencies<T>>;
3030
};
3131

32+
const dotnetClient = new DotNetClient(dotnetFactory());
33+
3234
export const createDependencies: CreateDependenciesCompat<NxDotnetConfig> = (
3335
ctxOrOpts: CreateDependenciesContext | NxDotnetConfig | undefined,
3436
maybeCtx: CreateDependenciesContext | undefined,
@@ -39,17 +41,35 @@ export const createDependencies: CreateDependenciesCompat<NxDotnetConfig> = (
3941
maybeCtx ?? (ctxOrOpts as CreateDependenciesContext);
4042

4143
let dependencies: RawProjectGraphDependency[] = [];
42-
const rootMap = Object.fromEntries(
43-
Object.entries(ctx.projects).map(([name, project]) => [project.root, name]),
44-
);
44+
const rootMap = createProjectRootMappings(ctx.projects);
4545
for (const source in ctx.filesToProcess.projectFileMap) {
4646
const changed = ctx.filesToProcess.projectFileMap[source];
4747
for (const file of changed) {
4848
const { ext } = parse(file.file);
4949
if (['.csproj', '.fsproj', '.vbproj'].includes(ext)) {
50-
dependencies = dependencies.concat(
51-
getDependenciesFromXmlFile(file.file, source, rootMap),
52-
);
50+
const references = dotnetClient.getProjectReferences(file.file);
51+
const newDeps: RawProjectGraphDependency[] = [];
52+
for (const reference of references) {
53+
const project = resolveReferenceToProject(
54+
normalizePath(reference),
55+
file.file,
56+
rootMap,
57+
ctx,
58+
);
59+
if (project) {
60+
newDeps.push({
61+
source,
62+
target: project,
63+
type: DependencyType.static,
64+
sourceFile: file.file,
65+
});
66+
} else {
67+
console.warn(
68+
`Unable to resolve project for reference ${reference} in ${file.file}`,
69+
);
70+
}
71+
}
72+
dependencies = dependencies.concat(newDeps);
5373
}
5474
}
5575
}
@@ -78,3 +98,48 @@ export const processProjectGraph: Required<NxPluginV1>['processProjectGraph'] =
7898
}
7999
return builder.getUpdatedProjectGraph();
80100
};
101+
102+
function createProjectRootMappings(
103+
projects: Record<string, ProjectConfiguration>,
104+
) {
105+
const rootMap: Record<string, string> = {};
106+
for (const [, project] of Object.entries(projects)) {
107+
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
108+
rootMap[project.root!] = project.name!;
109+
}
110+
return rootMap;
111+
}
112+
113+
function findProjectForPath(
114+
filePath: string,
115+
rootMap: Record<string, string>,
116+
): string | undefined {
117+
/**
118+
* Project Mappings are in UNIX-style file paths
119+
* Windows may pass Win-style file paths
120+
* Ensure filePath is in UNIX-style
121+
*/
122+
let currentPath = normalizePath(filePath);
123+
for (
124+
;
125+
currentPath !== dirname(currentPath);
126+
currentPath = dirname(currentPath)
127+
) {
128+
const p = rootMap[currentPath];
129+
if (p) {
130+
return p;
131+
}
132+
}
133+
return rootMap[currentPath];
134+
}
135+
136+
export function resolveReferenceToProject(
137+
reference: string,
138+
source: string,
139+
rootMap: Record<string, string>,
140+
context: { workspaceRoot: string },
141+
) {
142+
const resolved = resolve(context.workspaceRoot, dirname(source), reference);
143+
console.log({ reference, source, resolved });
144+
return findProjectForPath(relative(context.workspaceRoot, resolved), rootMap);
145+
}

0 commit comments

Comments
 (0)