示例#1
0
        /// <summary>
        /// Order the list in build-order.
        /// </summary>
        /// <param name="projectList">List of file paths to projects</param>
        /// <returns>True if build order was determined. False if there was a circular dependency.</returns>
        public static bool SetBuildOrder(List <string> projectList)
        {
            bool changed;
            int  changeCount = 0;
            int  maxChanges  = projectList.Count * projectList.Count;

            do
            {
                if (changeCount > maxChanges)
                {
                    ErrorManager.Error("ParseProjects", "Project dependency dead-lock. There's a circular dependency in projects.");
                    return(false);
                }
                changed = false;

                for (int i = 0; i < projectList.Count; ++i)
                {
                    string proj1 = projectList[i];
                    using (ParseProject po = new ParseProject(proj1))
                    {
                        for (int j = i + 1; j < projectList.Count; ++j)
                        {
                            string proj2 = projectList[j];
                            if (po.ProjectReferences.Contains(proj2, StringComparer.OrdinalIgnoreCase))
                            {
                                ErrorManager.DebugF("'{0}' depends on '{1}'.\n\tPutting '{1}' in index '{2}'\n\tPutting '{0}' in index '{3}'"
                                                    , proj1
                                                    , proj2
                                                    , i
                                                    , i + 1
                                                    );

                                changed = true;
                                projectList.RemoveAt(j);
                                projectList.Insert(i, proj2);
                                break;
                            }
                        }
                    }

                    if (changed)
                    {
                        ++changeCount;
                        break;
                    }
                }
            } while (changed);

            return(true);
        }
示例#2
0
        /// <summary>
        /// C'tor.
        /// </summary>
        /// <param name="projFile">Project file for which references will be listed.</param>
        public ParseProject(string projFile)
        {
            try
            {
                ErrorManager.DebugF("Parsing project '{0}' ...", projFile);

                _msbuildProj = new Project(projFile);

                // Check cache. Only valid project files get into the cache.
                _myCache = GetCache(_msbuildProj.FullPath);
                if (_myCache == null)
                {
                    _cache.Add(this);
                }
            }
            catch (Microsoft.Build.Exceptions.InvalidProjectFileException ex) // Probably a .vdproj file. ignoreable.
            {
                ErrorManager.DebugF("Exception '{0}' while parsing '{1}'", ex.GetType().FullName, projFile);
                _msbuildProj = null;
            }
        }
示例#3
0
        /// <summary>
        /// Find projects that depend on a given project, and it's own project dependencies.
        /// </summary>
        /// <param name="args"></param>
        /// <param name="/project">The name of the project</param>
        /// <param name="/folder">Root folder where projects that depend on the given project are searched for</param>
        /// <param name="/out">Optional. File to dump results to. If null then results will be dumped to Console.</param>
        /// <returns></returns>
        public static int Main(string[] args)
        {
            string        projFile;
            string        outFile;
            List <string> topFolders = new List <string>();

            if (!ParseCommandLine(topFolders, out projFile, out outFile))
            {
                Usage();
                return(-1);
            }

            // Setup search folders and project pattern
            projFile = ParseProject.NormalizeReferenceName(projFile);
            SearchFolders folders = new SearchFolders();

            folders.AddFolders(topFolders);
            folders.AddPattern(projFile + ".*proj");
            ParseProject.SetSearchFolders(folders);

            // List the projects the target project depends on
            List <string> dependentProjects = new List <string>();

            foreach (string proj in folders.Search())
            {
                dependentProjects.Add(proj);
                using (ParseProject po = new ParseProject(proj))
                {
                    dependentProjects.AddRange(po.ProjectReferences);
                }
            }

            // List the projects that depend on the target project:
            // Find all project files in the folders.
            IEnumerable <string> projFiles = folders.Search("*.*proj");

            foreach (string p in projFiles)
            {
                using (ParseProject po = new ParseProject(p))
                {
                    // Test if this project depends on the target project
                    if (po.ProjectReferences.Contains(projFile, StringComparer.OrdinalIgnoreCase))
                    {
                        dependentProjects.Add(p);
                    }
                }
            }

            // Unique, sorted list
            if (ErrorManager.Good)
            {
                dependentProjects = new List <string>(dependentProjects.Distinct(StringComparer.OrdinalIgnoreCase));
                ParseProject.SetBuildOrder(dependentProjects);
            }

            // Dump project file, even if error(s) occured.
            if (!string.IsNullOrWhiteSpace(outFile))
            {
                ParseProject.CreateBuildFile(outFile, dependentProjects);
            }
            else
            {
                foreach (string s in dependentProjects)
                {
                    Console.WriteLine(s);
                }
            }

            return(ErrorManager.ExitCode);
        }
示例#4
0
        /// <summary>
        /// Parse a build.proj file, that already has all parsed dependent projects.
        /// Initially checks that build.proj file exists and had a newer modification time compared to the project file.
        /// </summary>
        private void ParseBuildProj()
        {
            try
            {
                if (_msbuildProj == null)
                {
                    return;
                }

                // build.proj exists?
                string buildProjFile = Path.Combine(Path.GetDirectoryName(_msbuildProj.FullPath), "build.proj");
                if (!File.Exists(buildProjFile))
                {
                    return;
                }

                // build.proj is newer than the project file?
                if (File.GetLastWriteTime(buildProjFile) < File.GetLastWriteTime(_msbuildProj.FullPath))
                {
                    return;
                }

                // Parse it!
                _allReferences  = new List <string>();
                _projReferences = new List <string>();
                Project buildProj         = new Project(buildProjFile);
                ProjectTargetInstance tgt = buildProj.Targets["Build"];
                if (tgt == null)
                {
                    return;
                }

                foreach (ProjectTaskInstance tsk in tgt.Tasks)
                {
                    if (tsk.Name.Equals("MSBuild"))
                    {
                        if (tsk.Parameters.Keys.Contains("Projects"))
                        {
                            // Once a build.proj includes our project we know that subsequent project depend on us.
                            string p = tsk.Parameters["Projects"];
                            if (Path.GetFileName(p).Equals(Path.GetFileName(_msbuildProj.FullPath), StringComparison.OrdinalIgnoreCase))
                            {
                                break;
                            }

                            _allReferences.Add(p);
                            AddProjectReference(p);
                            using (ParseProject po = new ParseProject(p))
                            {
                                _allReferences.AddRange(po.AllReferences);
                                AddProjectReferences(po.ProjectReferences);
                            }
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ErrorManager.DebugF("Failed parsing build.proj: {0}", ex.Message);
                _allReferences  = null;
                _projReferences = null;
                return;
            }
        }