示例#1
0
        private ProjectDependencyGraph Evaluate(List <Project> rootProjects, BuildEnvironment environment)
        {
            var projectStack = new Stack <Tmp>(rootProjects.Count);

            foreach (var project in rootProjects)
            {
                projectStack.Push(new Tmp {
                    Project = project
                });
            }

            var graph = new ProjectDependencyGraph();

            while (projectStack.Count > 0)
            {
                var pair        = projectStack.Pop();
                var rootProject = pair.Project;

                // Evaluating a project means determining the values of properties, the
                // presence of nodes, etc...
                // Properties of a project (for example $(Configuration)) are written
                // back to the environment, but we don't want to one project's enviroment
                // to interfere with the next one, thus we create one environment for each
                // project.
                var projectEnvironment = new BuildEnvironment(environment);
                var evaluated          = _expressionEngine.Evaluate(rootProject.Merged(_buildScript), projectEnvironment);
                graph.Add(evaluated, projectEnvironment);

                if (pair.NeededBy != null)
                {
                    graph.AddDependency(pair.NeededBy, evaluated);
                }

                // Now that we've evaluated the project it's time to find out if it references
                // any other projects. This is done afterwards because dependencies might be conditional
                // and thus we won't know the dependencies until after evaluating them against the
                // current build environment.
                // Anyways, we'll simply add any referenced project to the list of projects so that
                // we can build all the things!
                var references = projectEnvironment.Items.Where(x => x.Type == Items.ProjectReference);
                foreach (var reference in references)
                {
                    var path = reference.Include;
                    if (!Path.IsPathRooted(path))
                    {
                        path = Path.Combine(projectEnvironment.Properties[Properties.MSBuildProjectDirectory], path);
                    }
                    path = Path.Normalize(path);

                    if (!graph.Contains(path))
                    {
                        var project = _csharpProjectParser.Parse(path);
                        projectStack.Push(new Tmp
                        {
                            Project  = project,
                            NeededBy = evaluated
                        });
                    }
                }
            }

            return(graph);
        }