@@ -52,67 +52,17 @@ public override int Execute()
5252 throw new GracefulException ( CliStrings . SpecifyAtLeastOneProjectToAdd ) ;
5353 }
5454
55- try
56- {
57- PathUtility . EnsureAllPathsExist ( _projects , CliStrings . CouldNotFindProjectOrDirectory , true ) ;
58- IEnumerable < string > fullProjectPaths = _projects . Select ( project =>
59- {
60- var fullPath = Path . GetFullPath ( project ) ;
61- return Directory . Exists ( fullPath ) ? MsbuildProject . GetProjectFileFromDirectory ( fullPath ) . FullName : fullPath ;
62- } ) ;
63- AddProjectsToSolutionAsync ( fullProjectPaths , CancellationToken . None ) . GetAwaiter ( ) . GetResult ( ) ;
64- return 0 ;
65- }
66- catch ( Exception ex ) when ( ex is not GracefulException )
67- {
68- {
69- if ( ex is SolutionException || ex . InnerException is SolutionException )
70- {
71- throw new GracefulException ( CliStrings . InvalidSolutionFormatString , _solutionFileFullPath , ex . Message ) ;
72- }
73- throw new GracefulException ( ex . Message , ex ) ;
74- }
75- }
76- }
55+ // Get project paths from the command line arguments
56+ PathUtility . EnsureAllPathsExist ( _projects , CliStrings . CouldNotFindProjectOrDirectory , true ) ;
7757
78- private async Task AddProjectsToSolutionAsync ( IEnumerable < string > projectPaths , CancellationToken cancellationToken )
79- {
80- SolutionModel solution = SlnFileFactory . CreateFromFileOrDirectory ( _solutionFileFullPath ) ;
81- ISolutionSerializer serializer = solution . SerializerExtension . Serializer ;
82-
83- // set UTF8 BOM encoding for .sln
84- if ( serializer is ISolutionSerializer < SlnV12SerializerSettings > v12Serializer )
58+ IEnumerable < string > fullProjectPaths = _projects . Select ( project =>
8559 {
86- solution . SerializerExtension = v12Serializer . CreateModelExtension ( new ( )
87- {
88- Encoding = new UTF8Encoding ( encoderShouldEmitUTF8Identifier : true )
89- } ) ;
90-
91- // Set default configurations and platforms for sln file
92- SlnFileFactory . DefaultPlatforms . ToList ( ) . ForEach ( solution . AddPlatform ) ;
93- SlnFileFactory . DefaultBuildTypes . ToList ( ) . ForEach ( solution . AddBuildType ) ;
94- }
95-
96-
97- foreach ( var projectPath in projectPaths )
98- {
99- string relativePath = Path . GetRelativePath ( Path . GetDirectoryName ( _solutionFileFullPath ) , projectPath ) ;
60+ var fullPath = Path . GetFullPath ( project ) ;
61+ return Directory . Exists ( fullPath ) ? MsbuildProject . GetProjectFileFromDirectory ( fullPath ) . FullName : fullPath ;
62+ } ) ;
10063
101- try
102- {
103- AddProject ( solution , relativePath , projectPath , serializer ) ;
104- }
105- catch ( InvalidProjectFileException ex )
106- {
107- Reporter . Error . WriteLine ( string . Format ( CliStrings . InvalidProjectWithExceptionMessage , projectPath , ex . Message ) ) ;
108- }
109- catch ( SolutionArgumentException ex ) when ( ex . Type == SolutionErrorType . DuplicateProjectName || solution . FindProject ( relativePath ) is not null )
110- {
111- Reporter . Output . WriteLine ( CliStrings . SolutionAlreadyContainsProject , _solutionFileFullPath , relativePath ) ;
112- }
113- }
114-
115- await serializer . SaveAsync ( _solutionFileFullPath , solution , cancellationToken ) ;
64+ AddProjectsToSolutionAsync ( fullProjectPaths , CancellationToken . None ) . GetAwaiter ( ) . GetResult ( ) ;
65+ return 0 ;
11666 }
11767
11868 private SolutionFolderModel ? GenerateIntermediateSolutionFoldersForProjectPath ( SolutionModel solution , string relativeProjectPath )
@@ -152,30 +102,73 @@ private async Task AddProjectsToSolutionAsync(IEnumerable<string> projectPaths,
152102 : solution . AddFolder ( GetSolutionFolderPathWithForwardSlashes ( relativeSolutionFolderPath ) ) ;
153103 }
154104
155- private void AddProject ( SolutionModel solution , string solutionRelativeProjectPath , string fullProjectPath , ISolutionSerializer serializer = null )
105+ private async Task AddProjectsToSolutionAsync ( IEnumerable < string > projectPaths , CancellationToken cancellationToken )
156106 {
107+ SolutionModel solution = SlnFileFactory . CreateFromFileOrDirectory ( _solutionFileFullPath ) ;
108+ ISolutionSerializer serializer = solution . SerializerExtension . Serializer ;
109+
110+ // set UTF8 BOM encoding for .sln
111+ if ( serializer is ISolutionSerializer < SlnV12SerializerSettings > v12Serializer )
112+ {
113+ solution . SerializerExtension = v12Serializer . CreateModelExtension ( new ( )
114+ {
115+ Encoding = new UTF8Encoding ( encoderShouldEmitUTF8Identifier : true )
116+ } ) ;
117+
118+ // Set default configurations and platforms for sln file
119+ SlnFileFactory . DefaultPlatforms . ToList ( ) . ForEach ( solution . AddPlatform ) ;
120+ SlnFileFactory . DefaultBuildTypes . ToList ( ) . ForEach ( solution . AddBuildType ) ;
121+ }
122+
123+
124+ foreach ( var projectPath in projectPaths )
125+ {
126+ // TODO: Remove this when we have a better way to handle this
127+ string solutionRelativeProjectPath = Path . GetRelativePath ( Path . GetDirectoryName ( _solutionFileFullPath ) , projectPath ) ;
128+ // Generate the solution folder path based on the project path
129+ SolutionFolderModel ? solutionFolder = GenerateIntermediateSolutionFoldersForProjectPath ( solution , solutionRelativeProjectPath ) ;
130+ AddProject ( solution , projectPath , solutionFolder , serializer ) ;
131+ }
132+
133+ await serializer . SaveAsync ( _solutionFileFullPath , solution , cancellationToken ) ;
134+ }
135+
136+ private void AddProject ( SolutionModel solution , string fullProjectPath , SolutionFolderModel solutionFolder , ISolutionSerializer serializer = null )
137+ {
138+ string solutionRelativeProjectPath = Path . GetRelativePath ( Path . GetDirectoryName ( _solutionFileFullPath ) , fullProjectPath ) ;
139+
157140 // Open project instance to see if it is a valid project
158- ProjectRootElement projectRootElement = ProjectRootElement . Open ( fullProjectPath ) ;
141+ ProjectRootElement projectRootElement ;
142+ try
143+ {
144+ projectRootElement = ProjectRootElement . Open ( fullProjectPath ) ;
145+ }
146+ catch ( InvalidProjectFileException ex )
147+ {
148+ Reporter . Error . WriteLine ( string . Format ( CliStrings . InvalidProjectWithExceptionMessage , fullProjectPath , ex . Message ) ) ;
149+ return ;
150+ }
151+
159152 ProjectInstance projectInstance = new ProjectInstance ( projectRootElement ) ;
160153 SolutionProjectModel project ;
161154
162- // Generate the solution folder path based on the project path
163- SolutionFolderModel ? solutionFolder = GenerateIntermediateSolutionFoldersForProjectPath ( solution , solutionRelativeProjectPath ) ;
155+ // Handle guid
156+ string projectTypeGuid = solution . ProjectTypes . FirstOrDefault ( t => t . Extension == Path . GetExtension ( fullProjectPath ) ) ? . ProjectTypeId . ToString ( )
157+ ?? projectRootElement . GetProjectTypeGuid ( ) ?? projectInstance . GetDefaultProjectTypeGuid ( ) ;
164158
165159 try
166160 {
167- project = solution . AddProject ( solutionRelativeProjectPath , null , solutionFolder ) ;
161+ project = solution . AddProject ( solutionRelativeProjectPath , projectTypeGuid , solutionFolder ) ;
168162 }
169163 catch ( SolutionArgumentException ex ) when ( ex . Type == SolutionErrorType . InvalidProjectTypeReference )
170164 {
171- // If guid is not identified by vs-solutionpersistence, check in project element itself
172- var guid = projectRootElement . GetProjectTypeGuid ( ) ?? projectInstance . GetDefaultProjectTypeGuid ( ) ;
173- if ( string . IsNullOrEmpty ( guid ) )
174- {
175- Reporter . Error . WriteLine ( CliStrings . UnsupportedProjectType , fullProjectPath ) ;
176- return ;
177- }
178- project = solution . AddProject ( solutionRelativeProjectPath , guid , solutionFolder ) ;
165+ Reporter . Error . WriteLine ( CliStrings . UnsupportedProjectType , fullProjectPath ) ;
166+ return ;
167+ }
168+ catch ( SolutionArgumentException ex ) when ( ex . Type == SolutionErrorType . DuplicateProjectName || solution . FindProject ( solutionRelativeProjectPath ) is not null )
169+ {
170+ Reporter . Output . WriteLine ( CliStrings . SolutionAlreadyContainsProject , _solutionFileFullPath , solutionRelativeProjectPath ) ;
171+ return ;
179172 }
180173
181174 // Add settings based on existing project instance
@@ -203,6 +196,18 @@ private void AddProject(SolutionModel solution, string solutionRelativeProjectPa
203196 project . AddProjectConfigurationRule ( new ConfigurationRule ( BuildDimension . BuildType , solutionBuildType , "*" , projectBuildType ) ) ;
204197 }
205198
199+ // Get referencedprojects from the project instance
200+ //var referencedProjectsFullPaths = projectInstance.EvaluatedItemElements
201+ // .Where(item => item.ItemType == "ProjectReference")
202+ // .Select(item => item.Include)
203+ // .Select(item => Path.GetFullPath(item, Path.GetDirectoryName(fullProjectPath)))
204+ // .ToList();
205+
206+ //foreach (var referencedProjectFullPath in referencedProjectsFullPaths)
207+ //{
208+ // var referencedProjectRelativePath = Path.GetRelativePath(_solutionFileFullPath, referencedProjectFullPath);
209+ //}
210+
206211 Reporter . Output . WriteLine ( CliStrings . ProjectAddedToTheSolution , solutionRelativeProjectPath ) ;
207212 }
208213}
0 commit comments