@@ -14,20 +14,21 @@ namespace Microsoft.DotNet.DarcLib;
1414public class CoherencyUpdateResolver : ICoherencyUpdateResolver
1515{
1616 private readonly IBasicBarClient _barClient ;
17+ private readonly IRemoteFactory _remoteFactory ;
1718 private readonly ILogger _logger ;
1819
1920 public CoherencyUpdateResolver (
2021 IBasicBarClient barClient ,
22+ IRemoteFactory remoteFactory ,
2123 ILogger logger )
2224 {
2325 _barClient = barClient ;
26+ _remoteFactory = remoteFactory ;
2427 _logger = logger ;
2528 }
2629
27- public async Task < List < DependencyUpdate > > GetRequiredCoherencyUpdatesAsync (
28- IEnumerable < DependencyDetail > dependencies ,
29- IRemoteFactory remoteFactory )
30- => await GetRequiredStrictCoherencyUpdatesAsync ( dependencies , remoteFactory ) ;
30+ public async Task < List < DependencyUpdate > > GetRequiredCoherencyUpdatesAsync ( IEnumerable < DependencyDetail > dependencies )
31+ => await GetRequiredStrictCoherencyUpdatesAsync ( dependencies ) ;
3132
3233 public List < DependencyUpdate > GetRequiredNonCoherencyUpdates (
3334 string sourceRepoUri ,
@@ -38,18 +39,32 @@ public List<DependencyUpdate> GetRequiredNonCoherencyUpdates(
3839 Dictionary < DependencyDetail , DependencyDetail > toUpdate = [ ] ;
3940
4041 // Walk the assets, finding the dependencies that don't have coherency markers.
42+ // And are not a part of the same build.
4143 // those must be updated in a second pass.
4244 foreach ( AssetData asset in assets )
4345 {
4446 DependencyDetail matchingDependencyByName =
45- dependencies . FirstOrDefault ( d => d . Name . Equals ( asset . Name , StringComparison . OrdinalIgnoreCase ) &&
46- string . IsNullOrEmpty ( d . CoherentParentDependencyName ) ) ;
47+ dependencies . FirstOrDefault ( d => d . Name . Equals ( asset . Name , StringComparison . OrdinalIgnoreCase ) ) ;
4748
4849 if ( matchingDependencyByName == null )
4950 {
5051 continue ;
5152 }
5253
54+ // If the dependency has a coherent parent, and the parent is among the build assets (in case of VMR builds)
55+ // we still want to update the dependency.
56+ if ( ! string . IsNullOrEmpty ( matchingDependencyByName . CoherentParentDependencyName ) )
57+ {
58+ if ( ! assets . Any ( a => a . Name == matchingDependencyByName . CoherentParentDependencyName ) )
59+ {
60+ continue ;
61+ }
62+ if ( dependencies . FirstOrDefault ( d => d . Name == matchingDependencyByName . CoherentParentDependencyName ) ? . Pinned ?? false )
63+ {
64+ continue ;
65+ }
66+ }
67+
5368 // If the dependency is pinned, don't touch it.
5469 if ( matchingDependencyByName . Pinned )
5570 {
@@ -97,7 +112,6 @@ public List<DependencyUpdate> GetRequiredNonCoherencyUpdates(
97112 /// Get updates required by coherency constraints using the "strict" algorithm
98113 /// </summary>
99114 /// <param name="dependencies">Current set of dependencies.</param>
100- /// <param name="remoteFactory">Remote factory for remote queries.</param>
101115 /// <returns>Dependencies with updates.</returns>
102116 /// <remarks>
103117 /// 'Strict' coherency is a version of coherency that does not **require** any build information,
@@ -119,9 +133,7 @@ public List<DependencyUpdate> GetRequiredNonCoherencyUpdates(
119133 /// but this is fairly minimal and generally covered by the need to have dependencies explicit in the
120134 /// version details files anyway.
121135 /// </remarks>
122- private async Task < List < DependencyUpdate > > GetRequiredStrictCoherencyUpdatesAsync (
123- IEnumerable < DependencyDetail > dependencies ,
124- IRemoteFactory remoteFactory )
136+ private async Task < List < DependencyUpdate > > GetRequiredStrictCoherencyUpdatesAsync ( IEnumerable < DependencyDetail > dependencies )
125137 {
126138 List < DependencyUpdate > toUpdate = [ ] ;
127139 IEnumerable < DependencyDetail > leavesOfCoherencyTrees = CalculateLeavesOfCoherencyTrees ( dependencies ) ;
@@ -189,7 +201,7 @@ private async Task<List<DependencyUpdate>> GetRequiredStrictCoherencyUpdatesAsyn
189201 if ( ! dependenciesCache . TryGetValue ( parentCoherentDependencyCacheKey ,
190202 out IEnumerable < DependencyDetail > coherentParentsDependencies ) )
191203 {
192- IRemote remoteClient = await remoteFactory . CreateRemoteAsync ( parentCoherentDependency . RepoUri ) ;
204+ IRemote remoteClient = await _remoteFactory . CreateRemoteAsync ( parentCoherentDependency . RepoUri ) ;
193205 coherentParentsDependencies = await remoteClient . GetDependenciesAsync (
194206 parentCoherentDependency . RepoUri ,
195207 parentCoherentDependency . Commit ) ;
@@ -235,7 +247,7 @@ private async Task<List<DependencyUpdate>> GetRequiredStrictCoherencyUpdatesAsyn
235247 _logger . LogInformation ( $ "Dependency { dependencyToUpdate . Name } will be updated to " +
236248 $ "{ cpdDependency . Version } from { cpdDependency . RepoUri } @{ cpdDependency . Commit } .") ;
237249
238- Asset coherentAsset = await DisambiguateAssetsAsync ( remoteFactory , buildCache , nugetConfigCache ,
250+ Asset coherentAsset = await DisambiguateAssetsAsync ( buildCache , nugetConfigCache ,
239251 parentCoherentDependency , cpdDependency ) ;
240252
241253 var updatedDependency = new DependencyDetail ( dependencyToUpdate )
@@ -314,15 +326,16 @@ private static IEnumerable<DependencyDetail> CalculateLeavesOfCoherencyTrees(IEn
314326 /// Disambiguate a set of potential assets based the nuget config
315327 /// file in a repo. The asset's locations are returned if a match is found.
316328 /// </summary>
317- /// <param name="remoteFactory">Remote factory for looking up the nuget config.</param>
318329 /// <param name="buildCache">Cache of builds</param>
319330 /// <param name="nugetConfigCache">Cache of nuget config files</param>
320331 /// <param name="parentCoherentDependency">Parent dependency of <paramref name="cpdDependency"/></param>
321332 /// <param name="cpdDependency">Dependency to disambiguate on.</param>
322333 /// <returns>Asset if a match to nuget.config is found. Asset from newest build is returned </returns>
323- private async Task < Asset > DisambiguateAssetsAsync ( IRemoteFactory remoteFactory ,
324- Dictionary < string , List < Build > > buildCache , Dictionary < string , IEnumerable < string > > nugetConfigCache ,
325- DependencyDetail parentCoherentDependency , DependencyDetail cpdDependency )
334+ private async Task < Asset > DisambiguateAssetsAsync (
335+ Dictionary < string , List < Build > > buildCache ,
336+ Dictionary < string , IEnumerable < string > > nugetConfigCache ,
337+ DependencyDetail parentCoherentDependency ,
338+ DependencyDetail cpdDependency )
326339 {
327340 var parentCoherentDependencyCacheKey = $ "{ parentCoherentDependency . RepoUri } @{ parentCoherentDependency . Commit } ";
328341
@@ -389,7 +402,7 @@ private async Task<Asset> DisambiguateAssetsAsync(IRemoteFactory remoteFactory,
389402 // coherent asset itself.
390403 if ( ! nugetConfigCache . TryGetValue ( parentCoherentDependencyCacheKey , out IEnumerable < string > nugetFeeds ) )
391404 {
392- IRemote remoteClient = await remoteFactory . CreateRemoteAsync ( parentCoherentDependency . RepoUri ) ;
405+ IRemote remoteClient = await _remoteFactory . CreateRemoteAsync ( parentCoherentDependency . RepoUri ) ;
393406 nugetFeeds = await remoteClient . GetPackageSourcesAsync ( parentCoherentDependency . RepoUri , parentCoherentDependency . Commit ) ;
394407 }
395408
0 commit comments