@@ -82,8 +82,7 @@ public async Task WatchAsync(CancellationToken shutdownCancellationToken)
8282                { 
8383                    var  rootProjectOptions  =  _context . RootProjectOptions ; 
8484
85-                     var  ( buildSucceeded ,  buildOutput ,  _)  =  await  BuildProjectAsync ( rootProjectOptions . ProjectPath ,  rootProjectOptions . BuildArguments ,  iterationCancellationToken ) ; 
86-                     BuildOutput . ReportBuildOutput ( _context . BuildLogger ,  buildOutput ,  buildSucceeded ,  projectDisplay :  rootProjectOptions . ProjectPath ) ; 
85+                     var  buildSucceeded  =  await  BuildProjectAsync ( rootProjectOptions . ProjectPath ,  rootProjectOptions . BuildArguments ,  iterationCancellationToken ) ; 
8786                    if  ( ! buildSucceeded ) 
8887                    { 
8988                        continue ; 
@@ -189,7 +188,7 @@ void FileChangedCallback(ChangedPath change)
189188
190189                    fileChangedCallback  =  FileChangedCallback ; 
191190                    fileWatcher . OnFileChange  +=  fileChangedCallback ; 
192-                     ReportWatchingForChanges ( ) ; 
191+                     _context . Logger . Log ( MessageDescriptor . WaitingForChanges ) ; 
193192
194193                    // Hot Reload loop - exits when the root process needs to be restarted. 
195194                    bool  extendTimeout  =  false ; 
@@ -328,15 +327,19 @@ void FileChangedCallback(ChangedPath change)
328327                                fileWatcher . SuppressEvents  =  true ; 
329328                                try 
330329                                { 
331-                                     var   buildResults   =   await   Task . WhenAll ( 
332-                                          projectsToRebuild . Select ( projectPath  =>   BuildProjectAsync ( projectPath ,   rootProjectOptions . BuildArguments ,   iterationCancellationToken ) ) ) ; 
333- 
334-                                     foreach  ( var  ( success ,   output ,   projectPath )  in  buildResults ) 
330+                                     // Build projects sequentially to avoid failed attempts to overwrite dependent project outputs. 
331+                                     // TODO: Ideally, dotnet build would be able to build multiple projects. https://github.com/dotnet/sdk/issues/51311 
332+                                      var   success   =   true ; 
333+                                     foreach  ( var  projectPath  in  projectsToRebuild ) 
335334                                    { 
336-                                         BuildOutput . ReportBuildOutput ( _context . BuildLogger ,  output ,  success ,  projectPath ) ; 
335+                                         success  =  await  BuildProjectAsync ( projectPath ,  rootProjectOptions . BuildArguments ,  iterationCancellationToken ) ; 
336+                                         if  ( ! success ) 
337+                                         { 
338+                                             break ; 
339+                                         } 
337340                                    } 
338341
339-                                     if  ( buildResults . All ( result  =>   result . success ) ) 
342+                                     if  ( success ) 
340343                                    { 
341344                                        break ; 
342345                                    } 
@@ -772,12 +775,6 @@ internal static IEnumerable<ChangedPath> NormalizePathChanges(IEnumerable<Change
772775                . Where ( item =>  item  !=  null ) 
773776                . Select ( item =>  item ! . Value ) ; 
774777
775-         private  void  ReportWatchingForChanges ( ) 
776-         { 
777-             _context . Logger . Log ( MessageDescriptor . WaitingForChanges 
778-                 . WithSeverityWhen ( MessageSeverity . Output ,  _context . EnvironmentOptions . TestFlags . HasFlag ( TestFlags . ElevateWaitingForChangesMessageSeverity ) ) ) ; 
779-         } 
780- 
781778        private  void  ReportFileChanges ( IReadOnlyList < ChangedFile >  changedFiles ) 
782779        { 
783780            Report ( kind :  ChangeKind . Add ) ; 
@@ -823,6 +820,9 @@ private async ValueTask<EvaluationResult> EvaluateRootProjectAsync(bool restore,
823820            { 
824821                cancellationToken . ThrowIfCancellationRequested ( ) ; 
825822
823+                 _context . Logger . LogInformation ( "Evaluating projects ..." ) ; 
824+                 var  stopwatch  =  Stopwatch . StartNew ( ) ; 
825+ 
826826                var  result  =  EvaluationResult . TryCreate ( 
827827                    _context . RootProjectOptions . ProjectPath , 
828828                    _context . RootProjectOptions . BuildArguments , 
@@ -832,6 +832,8 @@ private async ValueTask<EvaluationResult> EvaluateRootProjectAsync(bool restore,
832832                    restore , 
833833                    cancellationToken ) ; 
834834
835+                 _context . Logger . LogInformation ( "Evaluation completed in {Time}s." ,  stopwatch . Elapsed . TotalSeconds . ToString ( "0.0" ) ) ; 
836+ 
835837                if  ( result  !=  null ) 
836838                { 
837839                    return  result ; 
@@ -846,31 +848,43 @@ await FileWatcher.WaitForFileChangeAsync(
846848            } 
847849        } 
848850
849-         private  async  Task < ( bool  success ,  ImmutableArray < OutputLine >  output ,  string  projectPath ) >  BuildProjectAsync ( 
850-             string  projectPath ,  IReadOnlyList < string >  buildArguments ,  CancellationToken  cancellationToken ) 
851+         private  async  Task < bool >  BuildProjectAsync ( string  projectPath ,  IReadOnlyList < string >  buildArguments ,  CancellationToken  cancellationToken ) 
851852        { 
852-             var   buildOutput  =  new   List < OutputLine > ( ) ; 
853+             List < OutputLine > ?   capturedOutput  =  _context . EnvironmentOptions . TestFlags   !=   TestFlags . None   ?   [ ]   :   null ; 
853854
854855            var  processSpec  =  new  ProcessSpec 
855856            { 
856857                Executable  =  _context . EnvironmentOptions . MuxerPath , 
857858                WorkingDirectory  =  Path . GetDirectoryName ( projectPath ) ! , 
858859                IsUserApplication  =  false , 
859-                 OnOutput  =  line => 
860-                 { 
861-                     lock  ( buildOutput ) 
860+ 
861+                 // Capture output if running in a test environment. 
862+                 // If the output is not captured dotnet build will show live build progress. 
863+                 OnOutput  =  capturedOutput  !=  null 
864+                     ?  line => 
862865                    { 
863-                         buildOutput . Add ( line ) ; 
866+                         lock  ( capturedOutput ) 
867+                         { 
868+                             capturedOutput . Add ( line ) ; 
869+                         } 
864870                    } 
865-                 } , 
871+                     :  null , 
872+ 
866873                // pass user-specified build arguments last to override defaults: 
867874                Arguments  =  [ "build" ,  projectPath ,  "-consoleLoggerParameters:NoSummary;Verbosity=minimal" ,  .. buildArguments ] 
868875            } ; 
869876
870877            _context . BuildLogger . Log ( MessageDescriptor . Building ,  projectPath ) ; 
871878
872-             var  exitCode  =  await  _context . ProcessRunner . RunAsync ( processSpec ,  _context . Logger ,  launchResult :  null ,  cancellationToken ) ; 
873-             return  ( exitCode  ==  0 ,  buildOutput . ToImmutableArray ( ) ,  projectPath ) ; 
879+             var  success  =  await  _context . ProcessRunner . RunAsync ( processSpec ,  _context . Logger ,  launchResult :  null ,  cancellationToken )  ==  0 ; 
880+ 
881+             if  ( capturedOutput  !=  null ) 
882+             { 
883+                 _context . BuildLogger . Log ( success  ?  MessageDescriptor . BuildSucceeded  :  MessageDescriptor . BuildFailed ,  projectPath ) ; 
884+                 BuildOutput . ReportBuildOutput ( _context . BuildLogger ,  capturedOutput ,  success ) ; 
885+             } 
886+ 
887+             return  success ; 
874888        } 
875889
876890        private  string  GetRelativeFilePath ( string  path ) 
0 commit comments