Beispiel #1
0
        /// <summary>
        /// Gets the project file of the project with the given unique identifier.
        /// </summary>
        /// <param name="projectGuid">The unique identifier of the project for which the project file should be retrieves.</param>
        /// <returns>
        /// The project file of the project with the given unique identifier.
        /// </returns>
        /// <exception cref="BuildException">No project with unique identifier <paramref name="projectGuid" /> could be located.</exception>
        public string GetProjectFileFromGuid(string projectGuid)
        {
            // locate project entry using the project guid
            ProjectEntry projectEntry = ProjectEntries[projectGuid];

            // TODO : as an emergency patch throw a build error when a GUID fails
            // to return a project file. This should be sanity checked when the
            // HashTable is populated and not at usage time to avoid internal
            // errors during build.
            if (projectEntry == null)
            {
                throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                       "Project with GUID '{0}' must be included for the build to"
                                                       + " work.", projectGuid), Location.UnknownLocation);
            }

            return(projectEntry.Path);
        }
Beispiel #2
0
        /// <summary>
        /// Adds a <see cref="ProjectEntry"/> to the end of the collection.
        /// </summary>
        /// <param name="item">The <see cref="ProjectEntry"/> to be added to the end of the collection.</param>
        /// <returns>
        /// The position into which the new element was inserted.
        /// </returns>
        public int Add(ProjectEntry item)
        {
            if (item == null)
            {
                throw new ArgumentNullException("item");
            }

            // fail if a project with the same GUID exists in the collection
            ProjectEntry existingEntry = this[item.Guid];

            if (existingEntry != null)
            {
                throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                       "The GUIDs of projects \"{0}\" and \"{1}\" are identical."
                                                       + " Please correct this manually.", item.Path,
                                                       existingEntry.Path), Location.UnknownLocation);
            }

            return(base.List.Add(item));
        }
Beispiel #3
0
        protected void LoadProjectGuids(ArrayList projects, bool isReferenceProject)
        {
            foreach (string projectFileName in projects)
            {
                string projectGuid = _solutionTask.ProjectFactory.LoadGuid(projectFileName);

                // locate project entry using the project guid
                ProjectEntry projectEntry = ProjectEntries[projectGuid];
                if (projectEntry != null)
                {
                    throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                           "Error loading project {0}. "
                                                           + " Project GUID {1} already exists! Conflicting project is {2}.",
                                                           projectFileName, projectGuid, projectEntry.Path));
                }
                ProjectEntries.Add(new ProjectEntry(projectGuid, projectFileName));
                if (isReferenceProject)
                {
                    _htReferenceProjects[projectGuid] = null;
                }
            }
        }
Beispiel #4
0
        protected virtual void SetProjectBuildConfiguration(ProjectEntry projectEntry)
        {
            if (projectEntry.BuildConfigurations == null)
            {
                // project was not loaded from solution file, and as a result
                // there's no project configuration section available, so we'll
                // consider all project configurations as valid build
                // configurations
                ProjectBase project = projectEntry.Project;
                project.BuildConfigurations.Clear();
                foreach (ConfigurationDictionaryEntry ce in project.ProjectConfigurations)
                {
                    project.BuildConfigurations[ce.Name] = ce.Config;
                }
            }
            else
            {
                // project was loaded from solution file, so only add build
                // configurations that were listed in project configuration
                // section

                ProjectBase project = projectEntry.Project;

                foreach (ConfigurationMapEntry ce in projectEntry.BuildConfigurations)
                {
                    Configuration solutionConfig = ce.Key;
                    Configuration projectConfig  = ce.Value;

                    ConfigurationBase conf = project.ProjectConfigurations [projectConfig];
                    if (conf != null)
                    {
                        project.BuildConfigurations[solutionConfig] = conf;
                    }
                }
            }
        }
Beispiel #5
0
 /// <summary>
 /// Inserts a <see cref="ProjectEntry"/> into the collection at the specified index.
 /// </summary>
 /// <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param>
 /// <param name="item">The <see cref="ProjectEntry"/> to insert.</param>
 public void Insert(int index, ProjectEntry item)
 {
     base.List.Insert(index, item);
 }
Beispiel #6
0
 /// <summary>
 /// Copies the entire collection to a compatible one-dimensional array, starting at the specified index of the target array.        
 /// </summary>
 /// <param name="array">The one-dimensional array that is the destination of the elements copied from the collection. The array must have zero-based indexing.</param> 
 /// <param name="index">The zero-based index in <paramref name="array"/> at which copying begins.</param>
 public void CopyTo(ProjectEntry[] array, int index)
 {
     base.List.CopyTo(array, index);
 }
Beispiel #7
0
 /// <summary>
 /// Retrieves the index of a specified <see cref="ProjectEntry"/> object in the collection.
 /// </summary>
 /// <param name="item">The <see cref="ProjectEntry"/> object for which the index is returned.</param> 
 /// <returns>
 /// The index of the specified <see cref="ProjectEntry"/>. If the <see cref="ProjectEntry"/> is not currently a member of the collection, it returns -1.
 /// </returns>
 public int IndexOf(ProjectEntry item)
 {
     return base.List.IndexOf(item);
 }
Beispiel #8
0
 /// <summary>
 /// Adds the elements of a <see cref="ProjectEntry"/> array to the end of the collection.
 /// </summary>
 /// <param name="items">The array of <see cref="ProjectEntry"/> elements to be added to the end of the collection.</param> 
 public void AddRange(ProjectEntry[] items)
 {
     for (int i = 0; (i < items.Length); i = (i + 1)) {
         Add(items[i]);
     }
 }
Beispiel #9
0
 /// <summary>
 /// Determines whether a <see cref="ProjectEntry"/> is in the collection.
 /// </summary>
 /// <param name="item">The <see cref="ProjectEntry"/> to locate in the collection.</param> 
 /// <returns>
 /// <see langword="true" /> if <paramref name="item"/> is found in the 
 /// collection; otherwise, <see langword="false" />.
 /// </returns>
 public bool Contains(ProjectEntry item)
 {
     return base.List.Contains(item);
 }
Beispiel #10
0
 /// <summary>
 /// Initializes a new instance of the <see cref="ProjectEntryCollection"/> class
 /// with the specified array of <see cref="ProjectEntry"/> instances.
 /// </summary>
 public ProjectEntryCollection(ProjectEntry[] value)
 {
     AddRange(value);
 }
Beispiel #11
0
        /// <summary>
        /// Adds a <see cref="ProjectEntry"/> to the end of the collection.
        /// </summary>
        /// <param name="item">The <see cref="ProjectEntry"/> to be added to the end of the collection.</param> 
        /// <returns>
        /// The position into which the new element was inserted.
        /// </returns>
        public int Add(ProjectEntry item)
        {
            if (item == null) {
                throw new ArgumentNullException("item");
            }

            // fail if a project with the same GUID exists in the collection
            ProjectEntry existingEntry = this[item.Guid];
            if (existingEntry != null) {
                throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                    "The GUIDs of projects \"{0}\" and \"{1}\" are identical."
                    + " Please correct this manually.", item.Path,
                    existingEntry.Path), Location.UnknownLocation);
            }

            return base.List.Add(item);
        }
Beispiel #12
0
 /// <summary>
 /// Removes a member from the collection.
 /// </summary>
 /// <param name="item">The <see cref="ProjectEntry"/> to remove from the collection.</param>
 public void Remove(ProjectEntry item)
 {
     base.List.Remove(item);
 }
Beispiel #13
0
 /// <summary>
 /// Determines whether a <see cref="ProjectEntry"/> is in the collection.
 /// </summary>
 /// <param name="item">The <see cref="ProjectEntry"/> to locate in the collection.</param>
 /// <returns>
 /// <see langword="true" /> if <paramref name="item"/> is found in the
 /// collection; otherwise, <see langword="false" />.
 /// </returns>
 public bool Contains(ProjectEntry item)
 {
     return(base.List.Contains(item));
 }
Beispiel #14
0
        protected void GetDependenciesFromProjects(Configuration solutionConfiguration)
        {
            Log(Level.Verbose, "Gathering additional dependencies...");

            // first get all of the output files
            foreach (ProjectEntry projectEntry in ProjectEntries)
            {
                ProjectBase project = projectEntry.Project;

                if (project == null)
                {
                    // skip projects that are not loaded/supported
                    continue;
                }

                foreach (ConfigurationBase projectConfig in project.ProjectConfigurations.Values)
                {
                    string projectOutputFile = projectConfig.OutputPath;
                    if (projectOutputFile != null)
                    {
                        _htOutputFiles[projectOutputFile] = project.Guid;
                    }
                }
            }

            // if one of output files resides in reference search path - circle began
            // we must build project with that outputFile before projects referencing it
            // (similar to project dependency) VS.NET 7.0/7.1 do not address this problem

            // build list of output which reside in such folders
            Hashtable outputsInAssemblyFolders = CollectionsUtil.CreateCaseInsensitiveHashtable();

            foreach (DictionaryEntry de in _htOutputFiles)
            {
                string outputfile = (string)de.Key;
                string folder     = Path.GetDirectoryName(outputfile);

                if (_solutionTask.AssemblyFolderList.Contains(folder))
                {
                    outputsInAssemblyFolders[Path.GetFileName(outputfile)] =
                        (string)de.Value;
                }
            }

            // build the dependency list
            foreach (ProjectEntry projectEntry in ProjectEntries)
            {
                ProjectBase project = projectEntry.Project;

                if (project == null)
                {
                    // skip projects that are not loaded/supported
                    continue;
                }

                // check if project actually supports the build configuration
                ConfigurationBase projectConfig = project.BuildConfigurations[solutionConfiguration];
                if (projectConfig == null)
                {
                    continue;
                }

                // ensure output directory exists. VS creates output directories
                // before it starts compiling projects
                if (!projectConfig.OutputDir.Exists)
                {
                    projectConfig.OutputDir.Create();
                    projectConfig.OutputDir.Refresh();
                }

                foreach (ReferenceBase reference in project.References)
                {
                    ProjectReferenceBase projectReference = reference as ProjectReferenceBase;
                    if (projectReference != null)
                    {
                        project.ProjectDependencies.Add(projectReference.Project);
                    }
                    else
                    {
                        string outputFile = reference.GetPrimaryOutputFile(
                            solutionConfiguration);
                        // if we reference an assembly in an AssemblyFolder
                        // that is an output directory of another project,
                        // then add dependency on that project
                        if (outputFile == null)
                        {
                            continue;
                        }

                        string dependencyGuid = (string)outputsInAssemblyFolders[Path.GetFileName(outputFile)];
                        if (dependencyGuid == null)
                        {
                            continue;
                        }

                        ProjectEntry dependencyEntry = ProjectEntries[dependencyGuid];
                        if (dependencyEntry != null && dependencyEntry.Project != null)
                        {
                            project.ProjectDependencies.Add(dependencyEntry.Project);
                        }
                    }
                }
            }
        }
Beispiel #15
0
        /// <summary>
        /// Loads the projects from the file system and stores them in an
        /// instance variable.
        /// </summary>
        /// <param name="gacCache"><see cref="GacCache" /> instance to use to determine whether an assembly is located in the Global Assembly Cache.</param>
        /// <param name="refResolver"><see cref="ReferencesResolver" /> instance to use to determine location and references of assemblies.</param>
        /// <param name="explicitProjectDependencies">TODO</param>
        /// <exception cref="BuildException">A project GUID in the solution file does not match the actual GUID of the project in the project file.</exception>
        protected void LoadProjects(GacCache gacCache, ReferencesResolver refResolver, Hashtable explicitProjectDependencies)
        {
            Log(Level.Verbose, "Loading projects...");

            FileSet excludes = _solutionTask.ExcludeProjects;

            foreach (ProjectEntry projectEntry in ProjectEntries)
            {
                string projectPath = projectEntry.Path;
                string projectGuid = projectEntry.Guid;

                // determine whether project is on case-sensitive filesystem,
                bool caseSensitive = PlatformHelper.IsVolumeCaseSensitive(projectPath);

                // indicates whether the project should be skipped (excluded)
                bool skipProject = false;

                // check whether project should be excluded from build
                foreach (string excludedProjectFile in excludes.FileNames)
                {
                    if (string.Compare(excludedProjectFile, projectPath, !caseSensitive, CultureInfo.InvariantCulture) == 0)
                    {
                        Log(Level.Verbose, "Excluding project '{0}'.",
                            projectPath);
                        // do not load project
                        skipProject = true;
                        // we have a match, so quit looking
                        break;
                    }
                }

                if (skipProject)
                {
                    // remove dependencies for excluded projects
                    if (explicitProjectDependencies.ContainsKey(projectGuid))
                    {
                        explicitProjectDependencies.Remove(projectGuid);
                    }

                    // project was excluded, move on to next project
                    continue;
                }

                Log(Level.Verbose, "Loading project '{0}'.", projectPath);
                ProjectBase p = _solutionTask.ProjectFactory.LoadProject(this, _solutionTask,
                                                                         _tfc, gacCache, refResolver, _outputDir, projectPath);
                if (p == null)
                {
                    Log(Level.Warning, "Project '{0}' is of unsupported type. Skipping.", projectPath);
                    // skip the project
                    continue;
                }
                if (p.Guid == null || p.Guid.Length == 0)
                {
                    p.Guid = FindGuidFromPath(projectPath);
                }

                // add project to entry
                projectEntry.Project = p;

                // set project build configuration
                SetProjectBuildConfiguration(projectEntry);
            }

            // add explicit dependencies (as set in VS.NET) to individual projects
            foreach (DictionaryEntry dependencyEntry in explicitProjectDependencies)
            {
                string    projectGuid  = (string)dependencyEntry.Key;
                Hashtable dependencies = (Hashtable)dependencyEntry.Value;

                ProjectEntry projectEntry = ProjectEntries[projectGuid];
                if (projectEntry == null)
                {
                    throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                           "Dependencies for project \'{0}\' could not be analyzed."
                                                           + " Project is not included.", projectGuid),
                                             Location.UnknownLocation);
                }

                ProjectBase project = projectEntry.Project;

                // make sure project is loaded
                if (project == null)
                {
                    throw new BuildException(string.Format(CultureInfo.InvariantCulture,
                                                           "Dependencies for project \'{0}\' could not be analyzed."
                                                           + " Project is not loaded.", projectGuid),
                                             Location.UnknownLocation);
                }

                foreach (string dependentProjectGuid in dependencies.Keys)
                {
                    ProjectEntry dependentEntry = ProjectEntries[dependentProjectGuid];
                    if (dependentEntry == null || dependentEntry.Project == null)
                    {
                        Log(Level.Warning, "Project \"{0}\": ignored dependency"
                            + " on project \"{1}\", which is not included.",
                            project.Name, dependentProjectGuid);
                        continue;
                    }

                    project.ProjectDependencies.Add(dependentEntry.Project);
                }
            }
        }
Beispiel #16
0
 /// <summary>
 /// Retrieves the index of a specified <see cref="ProjectEntry"/> object in the collection.
 /// </summary>
 /// <param name="item">The <see cref="ProjectEntry"/> object for which the index is returned.</param>
 /// <returns>
 /// The index of the specified <see cref="ProjectEntry"/>. If the <see cref="ProjectEntry"/> is not currently a member of the collection, it returns -1.
 /// </returns>
 public int IndexOf(ProjectEntry item)
 {
     return(base.List.IndexOf(item));
 }
Beispiel #17
0
 /// <summary>
 /// Inserts a <see cref="ProjectEntry"/> into the collection at the specified index.
 /// </summary>
 /// <param name="index">The zero-based index at which <paramref name="item"/> should be inserted.</param>
 /// <param name="item">The <see cref="ProjectEntry"/> to insert.</param>
 public void Insert(int index, ProjectEntry item)
 {
     base.List.Insert(index, item);
 }
Beispiel #18
0
 /// <summary>
 /// Removes a member from the collection.
 /// </summary>
 /// <param name="item">The <see cref="ProjectEntry"/> to remove from the collection.</param>
 public void Remove(ProjectEntry item)
 {
     base.List.Remove(item);
 }
Beispiel #19
0
        public WhidbeySolution(string solutionContent, SolutionTask solutionTask, TempFileCollection tfc, GacCache gacCache, ReferencesResolver refResolver)
            : base(solutionTask, tfc, gacCache, refResolver)
        {
            Regex           reProjects     = new Regex(@"Project\(\""(?<package>\{.*?\})\"".*?\""(?<name>.*?)\"".*?\""(?<project>.*?)\"".*?\""(?<guid>.*?)\""(?<all>[\s\S]*?)EndProject", RegexOptions.Multiline);
            MatchCollection projectMatches = reProjects.Matches(solutionContent);

            Hashtable explicitProjectDependencies = CollectionsUtil.CreateCaseInsensitiveHashtable();

            foreach (Match projectMatch in projectMatches)
            {
                string project = projectMatch.Groups["project"].Value;
                string guid    = projectMatch.Groups["guid"].Value;
                string package = projectMatch.Groups["package"].Value;

                // bug #1732361: skip solution folders
                if (package == SolutionFolder_GUID)
                {
                    continue;
                }

                // translate partial project path or URL to absolute path
                string fullProjectPath = TranslateProjectPath(solutionTask.SolutionFile.DirectoryName,
                                                              project);

                if (ManagedProjectBase.IsEnterpriseTemplateProject(fullProjectPath))
                {
                    RecursiveLoadTemplateProject(fullProjectPath);
                }
                else
                {
                    // add project entry to collection
                    ProjectEntries.Add(new ProjectEntry(guid, fullProjectPath));
                }

                // set-up project dependencies
                Regex           reDependencies    = new Regex(@"^\s+(?<guid>\{[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}\})\s+=\s+(?<dep>\{[0-9a-zA-Z]{8}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{4}-[0-9a-zA-Z]{12}\})", RegexOptions.Multiline);
                MatchCollection dependencyMatches = reDependencies.Matches(projectMatch.Value);

                foreach (Match dependencyMatch in dependencyMatches)
                {
                    string dependency = dependencyMatch.Groups["dep"].Value;

                    if (!explicitProjectDependencies.ContainsKey(guid))
                    {
                        explicitProjectDependencies[guid] = CollectionsUtil.CreateCaseInsensitiveHashtable();
                    }
                    ((Hashtable)explicitProjectDependencies[guid])[dependency] = null;
                }

                // set-up project configuration
                Regex           reProjectBuildConfig = new Regex(@"^\s+" + Regex.Escape(guid) + @"\.(?<solutionConfiguration>[^|]+)\|(?<solutionPlatform>[^.]+)\.Build\.0\s*=\s*(?<projectConfiguration>[^|]+)\|(?<projectPlatform>[\.\w ]+)\s*", RegexOptions.Multiline);
                MatchCollection projectBuildMatches  = reProjectBuildConfig.Matches(solutionContent);

                ProjectEntry projectEntry = ProjectEntries [guid];
                if (projectEntry == null)
                {
                    // TODO: determine if we should report an error if a build
                    // configuration is defined for a project that does not
                    // exist in the solution
                    continue;
                }

                // holds mapping between project configuration(s) and solution(s)
                ConfigurationMap buildConfigurations = new ConfigurationMap(
                    projectBuildMatches.Count);

                for (int i = 0; i < projectBuildMatches.Count; i++)
                {
                    Match         projectBuildMatch  = projectBuildMatches [i];
                    string        solutionConfigName = projectBuildMatch.Groups["solutionConfiguration"].Value;
                    string        solutionPlatform   = projectBuildMatch.Groups["solutionPlatform"].Value;
                    string        projectConfigName  = projectBuildMatch.Groups["projectConfiguration"].Value;
                    string        projectPlatform    = projectBuildMatch.Groups["projectPlatform"].Value;
                    Configuration solutionConfig     = new Configuration(
                        solutionConfigName, solutionPlatform);
                    Configuration projectConfig = new Configuration(
                        projectConfigName, projectPlatform);
                    buildConfigurations [solutionConfig] = projectConfig;
                }

                // add map to corresponding project entry
                projectEntry.BuildConfigurations = buildConfigurations;
            }

            LoadProjectGuids(new ArrayList(solutionTask.Projects.FileNames), false);
            LoadProjectGuids(new ArrayList(solutionTask.ReferenceProjects.FileNames), true);
            LoadProjects(gacCache, refResolver, explicitProjectDependencies);
        }
Beispiel #20
0
        protected virtual void SetProjectBuildConfiguration(ProjectEntry projectEntry)
        {
            if (projectEntry.BuildConfigurations == null) {
                // project was not loaded from solution file, and as a result
                // there's no project configuration section available, so we'll
                // consider all project configurations as valid build
                // configurations
                ProjectBase project = projectEntry.Project;
                project.BuildConfigurations.Clear();
                foreach (ConfigurationDictionaryEntry ce in project.ProjectConfigurations) {
                    project.BuildConfigurations[ce.Name] = ce.Config;
                }
            } else {
                // project was loaded from solution file, so only add build
                // configurations that were listed in project configuration
                // section

                ProjectBase project = projectEntry.Project;

                foreach (ConfigurationMapEntry ce in projectEntry.BuildConfigurations) {
                    Configuration solutionConfig = ce.Key;
                    Configuration projectConfig = ce.Value;

                    ConfigurationBase conf = project.ProjectConfigurations [projectConfig];
                    if (conf != null) {
                        project.BuildConfigurations[solutionConfig] = conf;
                    }
                }
            }
        }