11import {
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+
3234export 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