tool/TeamCity.Docker/BuildPathProvider.cs (54 lines of code) (raw):

// ReSharper disable ClassNeverInstantiated.Global namespace TeamCity.Docker { using System; using System.Collections.Generic; using System.Linq; using Generic; using Model; internal class BuildPathProvider : IBuildPathProvider { public IEnumerable<INode<IArtifact>> GetPath(IGraph<IArtifact, Dependency> buildGraph) { if (buildGraph == null) throw new ArgumentNullException(nameof(buildGraph)); var path = new List<INode<IArtifact>>(); var leaves = buildGraph.Nodes .Except(buildGraph.Links.Select(i => i.To)) .Where(i => i.Value is Image) .OrderBy(i => ((Image)i.Value).File); foreach (var leaf in leaves) { path.AddRange(GetPathInternal(buildGraph, leaf)); } path.Reverse(); return path.Distinct(); } public IEnumerable<INode<IArtifact>> GetPath(IGraph<IArtifact, Dependency> buildGraph, INode<IArtifact> leafNode) { if (buildGraph == null) throw new ArgumentNullException(nameof(buildGraph)); if (leafNode == null) throw new ArgumentNullException(nameof(leafNode)); return GetPathInternal(buildGraph, leafNode).Reverse().Distinct(); } private static IEnumerable<INode<IArtifact>> GetPathInternal(IGraph<IArtifact, Dependency> graph, INode<IArtifact> leafNode) { yield return leafNode; var dependencies = ( from dependencyLink in graph.Links where dependencyLink.From.Equals(leafNode) select dependencyLink.To); var images = from dependency in dependencies let image = dependency.Value as Image orderby image?.File select new { dependency, image }; var childNodes = from image in images from childNode in GetPathInternal(graph, image.dependency) select childNode; foreach (var childNode in childNodes) { yield return childNode; } } } }