@@ -27,60 +27,91 @@ public static (bool SolutionOrProjectFileFound, string Message) TryGetProjectOrS
27
27
return ( false , string . Format ( CliCommandStrings . CmdNonExistentDirectoryErrorDescription , directory ) ) ;
28
28
}
29
29
30
- var solutionPaths = GetSolutionFilePaths ( directory ) ;
30
+ var actualSolutionFiles = GetSolutionFilePaths ( directory ) ;
31
+ var solutionFilterFiles = GetSolutionFilterFilePaths ( directory ) ;
32
+ var actualProjectFiles = GetProjectFilePaths ( directory ) ;
31
33
32
- // If more than a single sln file is found, an error is thrown since we can't determine which one to choose.
33
- if ( solutionPaths . Length > 1 )
34
+ // NOTE: The logic here is duplicated from https://github.com/dotnet/msbuild/blob/b878078fbaa28491a3a7fb273474ba71675c1613/src/MSBuild/XMake.cs#L3589
35
+ // If there is exactly 1 project file and exactly 1 solution file
36
+ if ( actualProjectFiles . Length == 1 && actualSolutionFiles . Length == 1 )
34
37
{
35
- return ( false , string . Format ( CliStrings . MoreThanOneSolutionInDirectory , directory ) ) ;
36
- }
37
-
38
- if ( solutionPaths . Length == 1 )
39
- {
40
- var projectPaths = GetProjectFilePaths ( directory ) ;
38
+ // Grab the name of both project and solution without extensions
39
+ string solutionName = Path . GetFileNameWithoutExtension ( actualSolutionFiles [ 0 ] ) ;
40
+ string projectName = Path . GetFileNameWithoutExtension ( actualProjectFiles [ 0 ] ) ;
41
41
42
- if ( projectPaths . Length == 0 )
42
+ // Compare the names and error if they are not identical
43
+ if ( ! string . Equals ( solutionName , projectName ) )
43
44
{
44
- projectOrSolutionFilePath = solutionPaths [ 0 ] ;
45
- isSolution = true ;
46
- return ( true , string . Empty ) ;
45
+ return ( false , CliCommandStrings . CmdMultipleProjectOrSolutionFilesErrorDescription ) ;
47
46
}
48
47
49
- return ( false , CliCommandStrings . CmdMultipleProjectOrSolutionFilesErrorDescription ) ;
48
+ projectOrSolutionFilePath = actualSolutionFiles [ 0 ] ;
49
+ isSolution = true ;
50
+ }
51
+ // If there is more than one solution file in the current directory we have no idea which one to use
52
+ else if ( actualSolutionFiles . Length > 1 )
53
+ {
54
+ return ( false , string . Format ( CliStrings . MoreThanOneSolutionInDirectory , directory ) ) ;
50
55
}
51
- else // If no solutions are found, look for a project file
56
+ // If there is more than one project file in the current directory we may be able to figure it out
57
+ else if ( actualProjectFiles . Length > 1 )
52
58
{
53
- string [ ] projectPaths = GetProjectFilePaths ( directory ) ;
59
+ // We have more than one project, it is ambiguous at the moment
60
+ bool isAmbiguousProject = true ;
54
61
55
- if ( projectPaths . Length == 0 )
62
+ // If there are exactly two projects and one of them is a .proj use that one and ignore the other
63
+ if ( actualProjectFiles . Length == 2 )
56
64
{
57
- var solutionFilterPaths = GetSolutionFilterFilePaths ( directory ) ;
65
+ string firstPotentialProjectExtension = Path . GetExtension ( actualProjectFiles [ 0 ] ) ;
66
+ string secondPotentialProjectExtension = Path . GetExtension ( actualProjectFiles [ 1 ] ) ;
58
67
59
- if ( solutionFilterPaths . Length == 0 )
68
+ // If the two projects have the same extension we can't decide which one to pick
69
+ if ( ! string . Equals ( firstPotentialProjectExtension , secondPotentialProjectExtension , StringComparison . OrdinalIgnoreCase ) )
60
70
{
61
- return ( false , CliCommandStrings . CmdNoProjectOrSolutionFileErrorDescription ) ;
62
- }
63
-
64
- if ( solutionFilterPaths . Length == 1 )
65
- {
66
- projectOrSolutionFilePath = solutionFilterPaths [ 0 ] ;
67
- isSolution = true ;
68
- return ( true , string . Empty ) ;
69
- }
70
- else
71
- {
72
- return ( false , CliCommandStrings . CmdMultipleProjectOrSolutionFilesErrorDescription ) ;
71
+ // Check to see if the first project is the proj, if it is use it
72
+ if ( string . Equals ( firstPotentialProjectExtension , ".proj" , StringComparison . OrdinalIgnoreCase ) )
73
+ {
74
+ projectOrSolutionFilePath = actualProjectFiles [ 0 ] ;
75
+ // We have made a decision
76
+ isAmbiguousProject = false ;
77
+ }
78
+ // If the first project is not the proj check to see if the second one is the proj, if so use it
79
+ else if ( string . Equals ( secondPotentialProjectExtension , ".proj" , StringComparison . OrdinalIgnoreCase ) )
80
+ {
81
+ projectOrSolutionFilePath = actualProjectFiles [ 1 ] ;
82
+ // We have made a decision
83
+ isAmbiguousProject = false ;
84
+ }
73
85
}
74
86
}
75
87
76
- if ( projectPaths . Length == 1 )
88
+ if ( isAmbiguousProject )
77
89
{
78
- projectOrSolutionFilePath = projectPaths [ 0 ] ;
79
- return ( true , string . Empty ) ;
90
+ return ( false , string . Format ( CliStrings . MoreThanOneProjectInDirectory , directory ) ) ;
80
91
}
81
-
82
- return ( false , string . Format ( CliStrings . MoreThanOneSolutionInDirectory , directory ) ) ;
83
92
}
93
+ // if there are no project, solution filter, or solution files in the directory, we can't build
94
+ else if ( actualProjectFiles . Length == 0 &&
95
+ actualSolutionFiles . Length == 0 &&
96
+ solutionFilterFiles . Length == 0 )
97
+ {
98
+ return ( false , CliCommandStrings . CmdNoProjectOrSolutionFileErrorDescription ) ;
99
+ }
100
+ else
101
+ {
102
+ // We are down to only one project, solution, or solution filter.
103
+ // If only 1 solution build the solution. If only 1 project build the project. Otherwise, build the solution filter.
104
+ projectOrSolutionFilePath = actualSolutionFiles . Length == 1 ? actualSolutionFiles [ 0 ] : actualProjectFiles . Length == 1 ? actualProjectFiles [ 0 ] : solutionFilterFiles [ 0 ] ;
105
+ isSolution = actualSolutionFiles . Length == 1 || ( actualProjectFiles . Length != 1 && solutionFilterFiles . Length == 1 ) ;
106
+ if ( actualSolutionFiles . Length != 1 &&
107
+ actualProjectFiles . Length != 1 &&
108
+ solutionFilterFiles . Length != 1 )
109
+ {
110
+ return ( false , CliCommandStrings . CmdMultipleProjectOrSolutionFilesErrorDescription ) ;
111
+ }
112
+ }
113
+
114
+ return ( true , string . Empty ) ;
84
115
}
85
116
86
117
private static string [ ] GetSolutionFilePaths ( string directory ) => [
@@ -93,9 +124,7 @@ private static string[] GetSolutionFilterFilePaths(string directory)
93
124
return Directory . GetFiles ( directory , CliConstants . SolutionFilterExtensionPattern , SearchOption . TopDirectoryOnly ) ;
94
125
}
95
126
96
- private static string [ ] GetProjectFilePaths ( string directory ) => [ .. Directory . EnumerateFiles ( directory , CliConstants . ProjectExtensionPattern , SearchOption . TopDirectoryOnly ) . Where ( IsProjectFile ) ] ;
97
-
98
- private static bool IsProjectFile ( string filePath ) => CliConstants . ProjectExtensions . Contains ( Path . GetExtension ( filePath ) , StringComparer . OrdinalIgnoreCase ) ;
127
+ private static string [ ] GetProjectFilePaths ( string directory ) => Directory . GetFiles ( directory , CliConstants . ProjectExtensionPattern , SearchOption . TopDirectoryOnly ) ;
99
128
100
129
private static ProjectInstance EvaluateProject ( ProjectCollection collection , string projectFilePath , string ? tfm )
101
130
{
0 commit comments