Esempio n. 1
0
        /// <summary>
        /// Dumps the <see cref="Solutions"/> order by their index along with optional details.
        /// </summary>
        /// <param name="m">The monitor to use.</param>
        /// <param name="current">The current solution (a star will precede its name).</param>
        /// <param name="solutionLineDetail">Optional details to be appended on the information, header, line.</param>
        /// <param name="solutionDetail">
        /// Optional detailed log generator.
        /// When not null, a group is opened by solution and this is called.
        /// </param>
        public void LogSolutions(
            IActivityMonitor m,
            DependentSolution current = null,
            Func <DependentSolution, string> solutionLineDetail         = null,
            Action <IActivityMonitor, DependentSolution> solutionDetail = null)
        {
            int rank = -1;

            foreach (var s in Solutions)
            {
                if (rank != s.Rank)
                {
                    rank = s.Rank;
                    m.Info($" -- Rank {rank}");
                }
                if (solutionDetail != null)
                {
                    using (m.OpenInfo($"{(s == current ? '*' : ' ')}   {s.Index} - {s} {solutionLineDetail?.Invoke( s )}"))
                    {
                        solutionDetail(m, s);
                    }
                }
                else
                {
                    m.Info($"{(s == current ? '*' : ' ')}   {s.Index} - {s} {solutionLineDetail?.Invoke( s )}");
                }
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Creates a new <see cref="SolutionDependencyContext"/>, possibly for a different subset of projects
        /// of the <see cref="Solutions"/> than the default set (all projects except build projects).
        /// </summary>
        /// <param name="m">The monitor to use.</param>
        /// <param name="traceGraphDetails">True to trace the details of the input and output (sorted) graphs.</param>
        /// <param name="projectFilter">
        /// Optional project filter.
        /// By default all projects are considered except build projects (see <see cref="Solution.BuildProject"/>).
        /// </param>
        /// <returns>The context or null on error.</returns>
        public SolutionDependencyContext CreateDependencyContext(IActivityMonitor m, bool traceGraphDetails, Func <IProject, bool> projectFilter = null)
        {
            if (projectFilter == null)
            {
                projectFilter = p => !p.IsBuildProject;
            }
            var sortables = new Dictionary <ISolution, SolutionItem>();

            foreach (var s in _solutions)
            {
                var sItem = new SolutionItem(s, s.Projects.Where(p => projectFilter(p)).Select(p => _projects[p]));
                sortables.Add(s, sItem);
            }

            var options = new DependencySorterOptions();

            if (traceGraphDetails)
            {
                options.HookInput  = i => i.Trace(m);
                options.HookOutput = i => i.Trace(m);
            }
            IDependencySorterResult result = DependencySorter.OrderItems(m, sortables.Values, null, options);

            if (!result.IsComplete)
            {
                result.LogError(m);
                return(new SolutionDependencyContext(this, result, GetBuildProjectInfo(m)));
            }
            // Building the list of SolutionDependencyContext.DependencyRow.
            var table = result.SortedItems
                        // 1 - Selects solutions along with their ordered index.
                        .Where(sorted => sorted.GroupForHead == null && sorted.Item is SolutionItem)
                        .Select(sorted =>
                                (
                                    Solution: (Solution)sorted.StartValue,
                                    // The projects from this solution that reference packages that are
                                    // produced by local solutions have a direct requires to a Package
                                    // that has a local Project.
                                    // 2 - First Map: LocalRefs is a set of value tuple (Project Origin, Package Target).
                                    LocalRefs: sorted.Children
                                    .Select(c => (SProject: c, Project: (Project)c.StartValue))
                                    .SelectMany(c => c.SProject.DirectRequires
                                                .Select(r => r.Item)
                                                .OfType <LocalPackageItem>()
                                                .Select(package => (Origin: c.Project, Target: package))
                                                )))
                        // 3 - Second Map: Expands the LocalRefs.
                        .SelectMany(s => s.LocalRefs.Any()
                                                ? s.LocalRefs.Select(r => new DependentSolution.Row
                                                                     (
                                                                         s.Solution,
                                                                         r.Origin,
                                                                         r.Target.Project
                                                                     ))
                                                : new[] { new DependentSolution.Row(s.Solution, null, null) }
                                    )
                        .ToList();

            // Now that the table of SolutionDependencyContext.DependencyRow is built, use it to compute the
            // pure solution dependency graph.
            //
            var       index        = new Dictionary <object, DependentSolution>();
            ISolution current      = null;
            var       depSolutions = new DependentSolution[sortables.Count];

            int idx = 0;

            foreach (var r in table)
            {
                if (current != r.Solution)
                {
                    current = r.Solution;
                    var newDependent = new DependentSolution(current, table, s => index[s]);
                    depSolutions[idx++] = newDependent;
                    index.Add(current.Name, newDependent);
                    index.Add(current, newDependent);
                }
            }
            Array.Sort(depSolutions, (d1, d2) =>
            {
                int cmp = d1.Rank - d2.Rank;
                if (cmp == 0)
                {
                    cmp = d1.Solution.Name.CompareTo(d2.Solution.Name);
                }
                return(cmp);
            });
            for (int i = 0; i < depSolutions.Length; ++i)
            {
                depSolutions[i].Index = i;
            }

            return(new SolutionDependencyContext(this, index, result, table, depSolutions, GetBuildProjectInfo(m)));
        }