Beispiel #1
0
        private ProjectGraphNode CreateNewNode(
            ConfigurationMetadata configurationMetadata,
            ProjectCollection projectCollection,
            ProjectInstanceFactoryFunc projectInstanceFactory)
        {
            // TODO: ProjectInstance just converts the dictionary back to a PropertyDictionary, so find a way to directly provide it.
            var globalProperties = configurationMetadata.GlobalProperties.ToDictionary();

            var projectInstance = projectInstanceFactory(
                configurationMetadata.ProjectFullPath,
                globalProperties,
                projectCollection);

            if (projectInstance == null)
            {
                throw new InvalidOperationException(ResourceUtilities.GetResourceString("NullReferenceFromProjectInstanceFactory"));
            }

            var graphNode = new ProjectGraphNode(
                projectInstance,
                globalProperties);

            _allParsedProjects[configurationMetadata] = graphNode;
            return(graphNode);
        }
Beispiel #2
0
        public static ConfigurationMetadata ToModuleConfiguration(this Module module)
        {
            if (module == null)
            {
                throw new ArgumentNullException("module");
            }

            var configuration = new ConfigurationMetadata {
                GroupName = module.Group.Name, Name = module.Name
            };

            foreach (PropertyValue property in module.PropertyValues)
            {
                if (configuration.Properties.ContainsKey(property.Property.Name))
                {
                    throw new ConfigurationErrorsException(
                              String.Format("Module [{0}] configuration property [{1}] is defined more than once.",
                                            configuration.Name, property.Property.Name));
                }

                configuration.Properties[property.Property.Name] = property.Value;
            }

            return(configuration);
        }
Beispiel #3
0
        private static List <ConfigurationMetadata> AddGraphBuildPropertyToEntryPoints(IEnumerable <ProjectGraphEntryPoint> entryPoints)
        {
            {
                var entryPointConfigurationMetadata = new List <ConfigurationMetadata>();

                foreach (var entryPoint in entryPoints)
                {
                    var globalPropertyDictionary = CreatePropertyDictionary(entryPoint.GlobalProperties);

                    AddGraphBuildGlobalVariable(globalPropertyDictionary);

                    var configurationMetadata = new ConfigurationMetadata(FileUtilities.NormalizePath(entryPoint.ProjectFile), globalPropertyDictionary);
                    entryPointConfigurationMetadata.Add(configurationMetadata);
                }

                return(entryPointConfigurationMetadata);
            }

            void AddGraphBuildGlobalVariable(PropertyDictionary <ProjectPropertyInstance> globalPropertyDictionary)
            {
                if (globalPropertyDictionary.GetProperty(PropertyNames.IsGraphBuild) == null)
                {
                    globalPropertyDictionary[PropertyNames.IsGraphBuild] = ProjectPropertyInstance.Create(PropertyNames.IsGraphBuild, "true");
                }
            }
        }
 public void TestValidConfiguration()
 {
     BuildRequestData data = new BuildRequestData("file", new Dictionary<string, string>(), "toolsVersion", new string[0], null);
     BuildRequestConfiguration config = new BuildRequestConfiguration(1, data, "2.0");
     ConfigurationMetadata metadata = new ConfigurationMetadata(config);
     Assert.AreEqual(data.ProjectFullPath, metadata.ProjectFullPath);
     Assert.AreEqual(data.ExplicitlySpecifiedToolsVersion, metadata.ToolsVersion);
 }
 public void TestConstructorNullConfiguration()
 {
     Assert.Throws <ArgumentNullException>(() =>
     {
         BuildRequestConfiguration config = null;
         ConfigurationMetadata metadata   = new ConfigurationMetadata(config);
     }
                                           );
 }
 public void TestConstructorNullProject()
 {
     Assert.Throws<ArgumentNullException>(() =>
     {
         Project project = null;
         ConfigurationMetadata metadata = new ConfigurationMetadata(project);
     }
    );
 }
 public void TestConstructorNullConfiguration()
 {
     Assert.Throws<ArgumentNullException>(() =>
     {
         BuildRequestConfiguration config = null;
         ConfigurationMetadata metadata = new ConfigurationMetadata(config);
     }
    );
 }
 public void TestConstructorNullProject()
 {
     Assert.Throws <ArgumentNullException>(() =>
     {
         Project project = null;
         ConfigurationMetadata metadata = new ConfigurationMetadata(project);
     }
                                           );
 }
        public void TestValidConfiguration()
        {
            BuildRequestData          data     = new BuildRequestData("file", new Dictionary <string, string>(), "toolsVersion", new string[0], null);
            BuildRequestConfiguration config   = new BuildRequestConfiguration(1, data, "2.0");
            ConfigurationMetadata     metadata = new ConfigurationMetadata(config);

            Assert.Equal(data.ProjectFullPath, metadata.ProjectFullPath);
            Assert.Equal(data.ExplicitlySpecifiedToolsVersion, metadata.ToolsVersion);
        }
        public void TestValidProject()
        {
            Project project = CreateProject();

            ConfigurationMetadata metadata = new ConfigurationMetadata(project);

            Assert.Equal(project.FullPath, metadata.ProjectFullPath);
            Assert.Equal(project.ToolsVersion, metadata.ToolsVersion);
        }
        public IEnumerable <ReferenceInfo> GetReferences(ProjectInstance requesterInstance)
        {
            IEnumerable <ProjectItemInstance>      projectReferenceItems;
            IEnumerable <GlobalPropertiesModifier> globalPropertiesModifiers = null;

            switch (GetProjectType(requesterInstance))
            {
            case ProjectType.OuterBuild:
                projectReferenceItems = ConstructInnerBuildReferences(requesterInstance);
                break;

            case ProjectType.InnerBuild:
                globalPropertiesModifiers = ModifierForNonMultitargetingNodes.Add((parts, reference) => parts.AddPropertyToUndefine(GetInnerBuildPropertyName(requesterInstance)));
                projectReferenceItems     = requesterInstance.GetItems(ItemTypeNames.ProjectReference);
                break;

            case ProjectType.NonMultitargeting:
                globalPropertiesModifiers = ModifierForNonMultitargetingNodes;
                projectReferenceItems     = requesterInstance.GetItems(ItemTypeNames.ProjectReference);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            foreach (var projectReferenceItem in projectReferenceItems)
            {
                if (!String.IsNullOrEmpty(projectReferenceItem.GetMetadataValue(ToolsVersionMetadataName)))
                {
                    throw new InvalidOperationException(
                              String.Format(
                                  CultureInfo.InvariantCulture,
                                  ResourceUtilities.GetResourceString(
                                      "ProjectGraphDoesNotSupportProjectReferenceWithToolset"),
                                  projectReferenceItem.EvaluatedInclude,
                                  requesterInstance.FullPath));
                }

                var projectReferenceFullPath = projectReferenceItem.GetMetadataValue(FullPathMetadataName);

                var referenceGlobalProperties = GetGlobalPropertiesForItem(projectReferenceItem, requesterInstance.GlobalPropertiesDictionary, globalPropertiesModifiers);

                var requesterPlatform            = "";
                var requesterPlatformLookupTable = "";

                if (ConversionUtilities.ValidBooleanTrue(requesterInstance.GetPropertyValue("EnableDynamicPlatformResolution")))
                {
                    requesterPlatform            = requesterInstance.GetPropertyValue("Platform");
                    requesterPlatformLookupTable = requesterInstance.GetPropertyValue("PlatformLookupTable");
                }

                var referenceConfig = new ConfigurationMetadata(projectReferenceFullPath, referenceGlobalProperties, requesterPlatform, requesterPlatformLookupTable, projectReferenceItem.HasMetadata("SetPlatform"));

                yield return(new ReferenceInfo(referenceConfig, projectReferenceItem));
            }
        }
 public void UpdateConfigMetaData(ConfigurationMetadata newMetaData)
 {
     if (newMetaData.GameMode != ConfigMetaData?.GameMode)
     {
         foreach (Action <GameModeId?> gameModeListener in gameModeListeners)
         {
             gameModeListener(newMetaData.GameMode);
         }
     }
     ConfigMetaData = newMetaData;
 }
Beispiel #13
0
        /// <summary>
        /// Constructs a graph starting from the given graph entry points, evaluating with the provided project collection.
        /// </summary>
        /// <param name="entryPoints">The entry points to use in constructing the graph</param>
        /// <param name="projectCollection">The collection with which all projects in the graph should be associated. May not be null.</param>
        /// <param name="projectInstanceFactory">
        /// A delegate used for constructing a <see cref="ProjectInstance"/>, called for each
        /// project created during graph creation. This value can be null, which uses
        /// a default implementation that calls the ProjectInstance constructor. See the remarks
        /// on <see cref="ProjectInstanceFactoryFunc"/> for other scenarios.
        /// </param>
        /// <exception cref="AggregateException">If the evaluation of any project in the graph fails, the InnerException contains <see cref="InvalidProjectFileException"/>
        /// If a null reference is returned from <paramref name="projectInstanceFactory"/>, the InnerException contains <see cref="InvalidOperationException"/></exception>
        /// <exception cref="CircularDependencyException">If the evaluation is successful but the project graph contains a circular dependency</exception>
        public ProjectGraph(
            IEnumerable <ProjectGraphEntryPoint> entryPoints,
            ProjectCollection projectCollection,
            ProjectInstanceFactoryFunc projectInstanceFactory)
        {
            ErrorUtilities.VerifyThrowArgumentNull(projectCollection, nameof(projectCollection));

            projectInstanceFactory = projectInstanceFactory ?? DefaultProjectInstanceFactory;

            var nodeStates         = new Dictionary <ProjectGraphNode, NodeState>();
            var entryPointNodes    = new List <ProjectGraphNode>();
            var tasksInProgress    = new ConcurrentDictionary <ConfigurationMetadata, object>();
            var projectsToEvaluate = new ConcurrentQueue <ConfigurationMetadata>();
            var entryPointConfigurationMetadata = new List <ConfigurationMetadata>();

            foreach (var entryPoint in entryPoints)
            {
                PropertyDictionary <ProjectPropertyInstance> globalPropertyDictionary = CreatePropertyDictionary(entryPoint.GlobalProperties);
                var configurationMetadata = new ConfigurationMetadata(FileUtilities.NormalizePath(entryPoint.ProjectFile), globalPropertyDictionary);
                projectsToEvaluate.Enqueue(configurationMetadata);
                entryPointConfigurationMetadata.Add(configurationMetadata);
            }

            if (LoadGraph(projectsToEvaluate, projectCollection, tasksInProgress, projectInstanceFactory, out List <Exception> exceptions))
            {
                foreach (var configurationMetadata in entryPointConfigurationMetadata)
                {
                    entryPointNodes.Add(_allParsedProjects[configurationMetadata]);
                    if (!nodeStates.TryGetValue(_allParsedProjects[configurationMetadata], out var _))
                    {
                        DetectCycles(_allParsedProjects[configurationMetadata], nodeStates, projectCollection, configurationMetadata.GlobalProperties);
                    }
                }

                var graphRoots = new List <ProjectGraphNode>(entryPointNodes.Count);
                foreach (var entryPointNode in entryPointNodes)
                {
                    if (entryPointNode.ReferencingProjects.Count == 0)
                    {
                        graphRoots.Add(entryPointNode);
                    }
                }

                EntryPointNodes = entryPointNodes.AsReadOnly();
                ProjectNodes    = _allParsedProjects.Values.ToList();
                GraphRoots      = graphRoots.AsReadOnly();

                _projectNodesTopologicallySorted = new Lazy <IReadOnlyCollection <ProjectGraphNode> >(() => TopologicalSort(GraphRoots, ProjectNodes));
            }
            else
            {
                throw new AggregateException(exceptions);
            }
        }
        public void TestGetHashCode()
        {
            BuildRequestData          data   = new BuildRequestData("file", new Dictionary <string, string>(), ObjectModelHelpers.MSBuildDefaultToolsVersion, new string[0], null);
            BuildRequestConfiguration config = new BuildRequestConfiguration(1, data, ObjectModelHelpers.MSBuildDefaultToolsVersion);

            Project project = CreateProject();

            ConfigurationMetadata metadata1 = new ConfigurationMetadata(config);
            ConfigurationMetadata metadata2 = new ConfigurationMetadata(project);

            Assert.Equal(metadata1.GetHashCode(), metadata2.GetHashCode());
        }
Beispiel #15
0
            public void EnsureCountIsNotRecursive()
            {
                // Given
                IConfiguration        configuration = GetConfiguration();
                ConfigurationMetadata metadata      = new ConfigurationMetadata(configuration);

                // When
                int count = metadata.Count;

                // Then
                count.ShouldBe(14);
            }
Beispiel #16
0
            public void ContainsKey(string key, bool expected)
            {
                // Given
                IConfiguration        configuration = GetConfiguration();
                ConfigurationMetadata metadata      = new ConfigurationMetadata(configuration);

                // When
                bool result = metadata.ContainsKey(key);

                // Then
                result.ShouldBe(expected);
            }
Beispiel #17
0
            public void GetsSimpleValue()
            {
                // Given
                IConfiguration        configuration = GetConfiguration();
                ConfigurationMetadata metadata      = new ConfigurationMetadata(configuration);

                // When
                bool result = metadata.TryGetRaw("key0", out object value);

                // Then
                result.ShouldBeTrue();
                value.ShouldBe("value0");
            }
Beispiel #18
0
        public BuildRequestConfiguration GetMatchingConfiguration(ConfigurationMetadata configMetadata)
        {
            var overrideConfig = _override.GetMatchingConfiguration(configMetadata);

            if (overrideConfig != null)
            {
#if DEBUG
                ErrorUtilities.VerifyThrow(CurrentCache.GetMatchingConfiguration(configMetadata) == null, "caches should not overlap");
#endif
                return(overrideConfig);
            }
            else
            {
                return(CurrentCache.GetMatchingConfiguration(configMetadata));
            }
        }
        public void TestTranslation()
        {
            var globalProperties = new PropertyDictionary <ProjectPropertyInstance>();

            globalProperties["a"] = ProjectPropertyInstance.Create("a", "b");

            var initial = new ConfigurationMetadata("path", globalProperties);

            initial.Translate(TranslationHelpers.GetWriteTranslator());
            var copy = ConfigurationMetadata.FactoryForDeserialization(TranslationHelpers.GetReadTranslator());

            copy.ProjectFullPath.ShouldBe(initial.ProjectFullPath);
            copy.ToolsVersion.ShouldBe(initial.ToolsVersion);

            Assert.Equal(copy.GlobalProperties.GetCopyOnReadEnumerable(), initial.GlobalProperties.GetCopyOnReadEnumerable(), EqualityComparer <ProjectPropertyInstance> .Default);
        }
Beispiel #20
0
        private ParsedProject ParseProject(ConfigurationMetadata configurationMetadata)
        {
            // TODO: ProjectInstance just converts the dictionary back to a PropertyDictionary, so find a way to directly provide it.
            var globalProperties = configurationMetadata.GlobalProperties.ToDictionary();
            ProjectGraphNode graphNode;
            ProjectInstance  projectInstance;
            var negotiatePlatform = PlatformNegotiationEnabled && !configurationMetadata.IsSetPlatformHardCoded;

            projectInstance = _projectInstanceFactory(
                configurationMetadata.ProjectFullPath,
                negotiatePlatform ? null : globalProperties,                 // Platform negotiation requires an evaluation with no global properties first
                _projectCollection);

            if (ConversionUtilities.ValidBooleanTrue(projectInstance.GetPropertyValue(EnableDynamicPlatformResolutionMetadataName)))
            {
                PlatformNegotiationEnabled = true;
            }

            if (projectInstance == null)
            {
                throw new InvalidOperationException(ResourceUtilities.GetResourceString("NullReferenceFromProjectInstanceFactory"));
            }

            if (negotiatePlatform)
            {
                var selectedPlatform = PlatformNegotiation.GetNearestPlatform(projectInstance.GetPropertyValue(PlatformMetadataName), projectInstance.GetPropertyValue(PlatformsMetadataName), projectInstance.GetPropertyValue(PlatformLookupTableMetadataName), configurationMetadata.PreviousPlatformLookupTable, projectInstance.FullPath, configurationMetadata.PreviousPlatform);

                if (selectedPlatform.Equals(String.Empty))
                {
                    globalProperties.Remove(PlatformMetadataName);
                }
                else
                {
                    globalProperties[PlatformMetadataName] = selectedPlatform;
                }
                projectInstance = _projectInstanceFactory(
                    configurationMetadata.ProjectFullPath,
                    globalProperties,
                    _projectCollection);
            }

            graphNode = new ProjectGraphNode(projectInstance);

            var referenceInfos = ParseReferences(graphNode);

            return(new ParsedProject(configurationMetadata, graphNode, referenceInfos));
        }
        public IEnumerable <ConfigurationMetadata> GetReferences(ProjectInstance requesterInstance)
        {
            IEnumerable <ProjectItemInstance>      references;
            IEnumerable <GlobalPropertiesModifier> globalPropertiesModifiers = null;

            switch (GetProjectType(requesterInstance))
            {
            case ProjectType.OuterBuild:
                references = GetInnerBuildReferences(requesterInstance);
                break;

            case ProjectType.InnerBuild:
                globalPropertiesModifiers = ModifierForNonMultitargetingNodes.Add((parts, reference) => parts.AddPropertyToUndefine(GetInnerBuildPropertyName(requesterInstance)));
                references = requesterInstance.GetItems(ItemTypeNames.ProjectReference);
                break;

            case ProjectType.NonMultitargeting:
                globalPropertiesModifiers = ModifierForNonMultitargetingNodes;
                references = requesterInstance.GetItems(ItemTypeNames.ProjectReference);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            foreach (var projectReference in references)
            {
                if (!String.IsNullOrEmpty(projectReference.GetMetadataValue(ToolsVersionMetadataName)))
                {
                    throw new InvalidOperationException(
                              String.Format(
                                  CultureInfo.InvariantCulture,
                                  ResourceUtilities.GetResourceString(
                                      "ProjectGraphDoesNotSupportProjectReferenceWithToolset"),
                                  projectReference.EvaluatedInclude,
                                  requesterInstance.FullPath));
                }

                var projectReferenceFullPath = projectReference.GetMetadataValue(FullPathMetadataName);

                var referenceGlobalProperties = GetGlobalPropertiesForItem(projectReference, requesterInstance.GlobalPropertiesDictionary, globalPropertiesModifiers);

                var referenceConfig = new ConfigurationMetadata(projectReferenceFullPath, referenceGlobalProperties);

                yield return(referenceConfig);
            }
        }
Beispiel #22
0
            public void GetsSectionValue()
            {
                // Given
                IConfiguration        configuration = GetConfiguration();
                ConfigurationMetadata metadata      = new ConfigurationMetadata(configuration);

                // When
                bool   result  = metadata.TryGetRaw("section0", out object value);
                object value2  = null;
                bool   result2 = (value as ConfigurationMetadata)?.TryGetRaw("key1", out value2) ?? false;

                // Then
                result.ShouldBeTrue();
                value.ShouldBeOfType <ConfigurationMetadata>();
                result2.ShouldBeTrue();
                value2.ShouldBe("value1");
            }
Beispiel #23
0
        public static ConfigurationMetadata ToModuleConfiguration(this Module module)
        {
            if (module == null)
                throw new ArgumentNullException("module");

            var configuration = new ConfigurationMetadata {GroupName = module.Group.Name, Name = module.Name};

            foreach (PropertyValue property in module.PropertyValues)
            {
                if (configuration.Properties.ContainsKey(property.Property.Name))
                    throw new ConfigurationErrorsException(
                        String.Format("Module [{0}] configuration property [{1}] is defined more than once.",
                            configuration.Name, property.Property.Name));

                configuration.Properties[property.Property.Name] = property.Value;
            }

            return configuration;
        }
Beispiel #24
0
        private ParsedProject ParseProject(ConfigurationMetadata configurationMetadata)
        {
            // TODO: ProjectInstance just converts the dictionary back to a PropertyDictionary, so find a way to directly provide it.
            var globalProperties = configurationMetadata.GlobalProperties.ToDictionary();

            var projectInstance = _projectInstanceFactory(
                configurationMetadata.ProjectFullPath,
                globalProperties,
                _projectCollection);

            if (projectInstance == null)
            {
                throw new InvalidOperationException(ResourceUtilities.GetResourceString("NullReferenceFromProjectInstanceFactory"));
            }

            var graphNode = new ProjectGraphNode(projectInstance);

            var referenceInfos = ParseReferences(graphNode);

            return(new ParsedProject(configurationMetadata, graphNode, referenceInfos));
        }
Beispiel #25
0
        /// <summary>
        /// Constructs a graph starting from the given graph entry points, evaluating with the provided project collection.
        /// </summary>
        /// <param name="entryPoints">The entry points to use in constructing the graph</param>
        /// <param name="projectCollection">The collection with which all projects in the graph should be associated. May not be null.</param>
        /// <param name="projectInstanceFactory">
        /// A delegate used for constructing a <see cref="ProjectInstance"/>, called for each
        /// project created during graph creation. This value can be null, which uses
        /// a default implementation that calls the ProjectInstance constructor. See the remarks
        /// on <see cref="ProjectInstanceFactoryFunc"/> for other scenarios.
        /// </param>
        /// <exception cref="AggregateException">If the evaluation of any project in the graph fails, the InnerException contains <see cref="InvalidProjectFileException"/>
        /// If a null reference is returned from <paramref name="projectInstanceFactory"/>, the InnerException contains <see cref="InvalidOperationException"/></exception>
        /// <exception cref="CircularDependencyException">If the evaluation is successful but the project graph contains a circular dependency</exception>
        public ProjectGraph(
            IEnumerable <ProjectGraphEntryPoint> entryPoints,
            ProjectCollection projectCollection,
            ProjectInstanceFactoryFunc projectInstanceFactory)
        {
            ErrorUtilities.VerifyThrowArgumentNull(projectCollection, nameof(projectCollection));

            projectInstanceFactory = projectInstanceFactory ?? DefaultProjectInstanceFactory;

            _projectInterpretation = ProjectInterpretation.Instance;

            var entryPointConfigurationMetadata = new List <ConfigurationMetadata>();

            foreach (var entryPoint in entryPoints)
            {
                var globalPropertyDictionary = CreatePropertyDictionary(entryPoint.GlobalProperties);

                AddGraphBuildGlobalVariable(globalPropertyDictionary);

                var configurationMetadata = new ConfigurationMetadata(FileUtilities.NormalizePath(entryPoint.ProjectFile), globalPropertyDictionary);
                entryPointConfigurationMetadata.Add(configurationMetadata);
            }

            var(entryPointNodes, rootNodes, allNodes) = LoadGraph(entryPointConfigurationMetadata, projectCollection, projectInstanceFactory, _projectInterpretation);

            EntryPointNodes = entryPointNodes;
            GraphRoots      = rootNodes;
            ProjectNodes    = allNodes;

            _projectNodesTopologicallySorted = new Lazy <IReadOnlyCollection <ProjectGraphNode> >(() => TopologicalSort(GraphRoots, ProjectNodes));

            void AddGraphBuildGlobalVariable(PropertyDictionary <ProjectPropertyInstance> globalPropertyDictionary)
            {
                if (globalPropertyDictionary.GetProperty(PropertyNames.IsGraphBuild) == null)
                {
                    globalPropertyDictionary[PropertyNames.IsGraphBuild] = ProjectPropertyInstance.Create(PropertyNames.IsGraphBuild, "true");
                }
            }
        }
        public void TestEquals()
        {
            BuildRequestData          data   = new BuildRequestData("file", new Dictionary <string, string>(), ObjectModelHelpers.MSBuildDefaultToolsVersion, new string[0], null);
            BuildRequestConfiguration config = new BuildRequestConfiguration(1, data, ObjectModelHelpers.MSBuildDefaultToolsVersion);

            Project project = CreateProject();

            ConfigurationMetadata metadata1 = new ConfigurationMetadata(config);
            ConfigurationMetadata metadata2 = new ConfigurationMetadata(project);

            Assert.True(metadata1.Equals(metadata2));

            data = new BuildRequestData("file2", new Dictionary <string, string>(), ObjectModelHelpers.MSBuildDefaultToolsVersion, new string[0], null);
            BuildRequestConfiguration config2   = new BuildRequestConfiguration(1, data, ObjectModelHelpers.MSBuildDefaultToolsVersion);
            ConfigurationMetadata     metadata3 = new ConfigurationMetadata(config2);

            Assert.False(metadata1.Equals(metadata3));

            data = new BuildRequestData("file", new Dictionary <string, string>(), "3.0", new string[0], null);
            BuildRequestConfiguration config3   = new BuildRequestConfiguration(1, data, "3.0");
            ConfigurationMetadata     metadata4 = new ConfigurationMetadata(config3);

            Assert.False(metadata1.Equals(metadata4));
        }
        public void TestValidProject()
        {
            Project project = CreateProject();

            ConfigurationMetadata metadata = new ConfigurationMetadata(project);
            Assert.AreEqual(project.FullPath, metadata.ProjectFullPath);
            Assert.AreEqual(project.ToolsVersion, metadata.ToolsVersion);
        }
Beispiel #28
0
 private void ParseProject(ConfigurationMetadata projectToEvaluate)
 {
     _graphWorkSet.AddWork(projectToEvaluate, () => CreateNewNode(projectToEvaluate));
 }
        public void TestGetHashCode()
        {
            BuildRequestData data = new BuildRequestData("file", new Dictionary<string, string>(), ObjectModelHelpers.MSBuildDefaultToolsVersion, new string[0], null);
            BuildRequestConfiguration config = new BuildRequestConfiguration(1, data, ObjectModelHelpers.MSBuildDefaultToolsVersion);

            Project project = CreateProject();

            ConfigurationMetadata metadata1 = new ConfigurationMetadata(config);
            ConfigurationMetadata metadata2 = new ConfigurationMetadata(project);
            Assert.AreEqual(metadata1.GetHashCode(), metadata2.GetHashCode());
        }
Beispiel #30
0
 public BuildRequestConfiguration GetMatchingConfiguration(ConfigurationMetadata configMetadata, ConfigCreateCallback callback, bool loadProject)
 {
     return(_override.GetMatchingConfiguration(configMetadata, callback, loadProject) ?? CurrentCache.GetMatchingConfiguration(configMetadata, callback, loadProject));
 }
Beispiel #31
0
        /// <remarks>
        /// Traverse an evaluated graph
        /// Maintain the state of each node (InProcess and Processed) to detect cycles
        /// returns false if loading the graph is not successful
        /// </remarks>
        private (bool success, List <string> projectsInCycle) DetectCycles(ProjectGraphNode node,
                                                                           Dictionary <ProjectGraphNode, NodeState> nodeState,
                                                                           ProjectCollection projectCollection,
                                                                           PropertyDictionary <ProjectPropertyInstance> globalProperties)
        {
            nodeState[node] = NodeState.InProcess;
            IEnumerable <ProjectItemInstance> projectReferenceItems = node.ProjectInstance.GetItems(MSBuildConstants.ProjectReferenceItemName);

            foreach (var projectReferenceToParse in projectReferenceItems)
            {
                string projectReferenceFullPath = projectReferenceToParse.GetMetadataValue(FullPathMetadataName);
                PropertyDictionary <ProjectPropertyInstance> projectReferenceGlobalProperties = GetProjectReferenceGlobalProperties(projectReferenceToParse, globalProperties);
                var projectReferenceConfigurationMetadata = new ConfigurationMetadata(projectReferenceFullPath, projectReferenceGlobalProperties);
                ProjectGraphNode projectReference         = _allParsedProjects[projectReferenceConfigurationMetadata];
                if (nodeState.TryGetValue(projectReference, out NodeState projectReferenceNodeState))
                {
                    // Because this is a depth-first search, we should only encounter new nodes or nodes whose subgraph has been completely processed.
                    // If we encounter a node that is currently being processed(InProcess state), it must be one of the ancestors in a circular dependency.
                    if (projectReferenceNodeState == NodeState.InProcess)
                    {
                        if (node.Equals(projectReference))
                        {
                            // the project being evaluated has a reference to itself
                            var selfReferencingProjectString = FormatCircularDependencyError(new List <string> {
                                node.ProjectInstance.FullPath, node.ProjectInstance.FullPath
                            });
                            throw new CircularDependencyException(string.Format(
                                                                      ResourceUtilities.GetResourceString("CircularDependencyInProjectGraph"),
                                                                      selfReferencingProjectString));
                        }
                        else
                        {
                            // the project being evaluated has a circular dependency involving multiple projects
                            // add this project to the list of projects involved in cycle
                            var projectsInCycle = new List <string> {
                                projectReferenceConfigurationMetadata.ProjectFullPath
                            };
                            return(false, projectsInCycle);
                        }
                    }
                }
                else
                {
                    // recursively process newly discovered references
                    var loadReference = DetectCycles(projectReference, nodeState, projectCollection,
                                                     projectReferenceGlobalProperties);
                    if (!loadReference.success)
                    {
                        if (loadReference.projectsInCycle[0].Equals(node.ProjectInstance.FullPath))
                        {
                            // we have reached the nth project in the cycle, form error message and throw
                            loadReference.projectsInCycle.Add(projectReferenceConfigurationMetadata.ProjectFullPath);
                            loadReference.projectsInCycle.Add(node.ProjectInstance.FullPath);
                            var errorMessage = FormatCircularDependencyError(loadReference.projectsInCycle);
                            throw new CircularDependencyException(string.Format(
                                                                      ResourceUtilities.GetResourceString("CircularDependencyInProjectGraph"),
                                                                      errorMessage));
                        }
                        else
                        {
                            // this is one of the projects in the circular dependency
                            // update the list of projects in cycle and return the list to the caller
                            loadReference.projectsInCycle.Add(projectReferenceConfigurationMetadata.ProjectFullPath);
                            return(false, loadReference.projectsInCycle);
                        }
                    }
                }
                ProjectGraphNode parsedProjectReference = _allParsedProjects[projectReferenceConfigurationMetadata];
                node.AddProjectReference(parsedProjectReference);
                parsedProjectReference.AddReferencingProject(node);
            }
            nodeState[node] = NodeState.Processed;
            return(true, null);
        }
Beispiel #32
0
        /// <summary>
        /// Load a graph with root node at entryProjectFile
        /// Maintain a queue of projects to be processed and evaluate projects in parallel
        /// Returns false if loading the graph is not successful
        /// </summary>
        private bool LoadGraph(
            ConcurrentQueue <ConfigurationMetadata> projectsToEvaluate,
            ProjectCollection projectCollection,
            ConcurrentDictionary <ConfigurationMetadata, object> tasksInProgress,
            ProjectInstanceFactoryFunc projectInstanceFactory,
            out List <Exception> exceptions)
        {
            var exceptionsInTasks    = new ConcurrentBag <Exception>();
            var evaluationWaitHandle = new AutoResetEvent(false);

            while (projectsToEvaluate.Count != 0 || tasksInProgress.Count != 0)
            {
                ConfigurationMetadata projectToEvaluate;
                if (projectsToEvaluate.Count != 0)
                {
                    projectToEvaluate = projectsToEvaluate.Dequeue();
                    var task = new Task(() =>
                    {
                        ProjectGraphNode parsedProject = CreateNewNode(projectToEvaluate, projectCollection, projectInstanceFactory);
                        IEnumerable <ProjectItemInstance> projectReferenceItems = parsedProject.ProjectInstance.GetItems(MSBuildConstants.ProjectReferenceItemName);
                        foreach (var projectReferenceToParse in projectReferenceItems)
                        {
                            if (!string.IsNullOrEmpty(projectReferenceToParse.GetMetadataValue(ToolsVersionMetadataName)))
                            {
                                throw new InvalidOperationException(string.Format(
                                                                        CultureInfo.InvariantCulture,
                                                                        ResourceUtilities.GetResourceString(
                                                                            "ProjectGraphDoesNotSupportProjectReferenceWithToolset"),
                                                                        projectReferenceToParse.EvaluatedInclude,
                                                                        parsedProject.ProjectInstance.FullPath));
                            }

                            string projectReferenceFullPath = projectReferenceToParse.GetMetadataValue(FullPathMetadataName);
                            PropertyDictionary <ProjectPropertyInstance> projectReferenceGlobalProperties = GetProjectReferenceGlobalProperties(projectReferenceToParse, projectToEvaluate.GlobalProperties);
                            var projectReferenceConfigurationMetadata = new ConfigurationMetadata(projectReferenceFullPath, projectReferenceGlobalProperties);
                            if (!tasksInProgress.ContainsKey(projectReferenceConfigurationMetadata))
                            {
                                if (!_allParsedProjects.ContainsKey(projectReferenceConfigurationMetadata))
                                {
                                    projectsToEvaluate.Enqueue(projectReferenceConfigurationMetadata);
                                    evaluationWaitHandle.Set();
                                }
                            }
                        }
                    });

                    if (tasksInProgress.TryAdd(projectToEvaluate, null))
                    {
                        // once the task completes, remove it from tasksInProgress using a chained task
                        // signal the wait handle to process new projects that have been discovered by this task or exit if all projects have been evaluated
                        task.ContinueWith(_ =>
                        {
                            if (task.IsFaulted)
                            {
                                exceptionsInTasks.Add(task.Exception.InnerException);
                            }
                            tasksInProgress.TryRemove(projectToEvaluate, out var _);
                            evaluationWaitHandle.Set();
                        });
                        task.Start();
                    }
                }
                else
                {
                    // if projectsToEvaluate is empty but there are tasks in progress, there is nothing to do till a task completes and discovers new projects
                    // wait till a task completes and sends a signal
                    evaluationWaitHandle.WaitOne();
                }
            }

            if (exceptionsInTasks.Count != 0)
            {
                exceptions = exceptionsInTasks.ToList();
                return(false);
            }

            exceptions = null;
            return(true);
        }
 public void TestConstructorNullProject()
 {
     Project project = null;
     ConfigurationMetadata metadata = new ConfigurationMetadata(project);
 }
 public void TestConstructorNullProject()
 {
     Project project = null;
     ConfigurationMetadata metadata = new ConfigurationMetadata(project);
 }
Beispiel #35
0
        /// <summary>
        /// Gets a matching configuration.  If no such configuration exists, one is created and optionally loaded.
        /// </summary>
        public BuildRequestConfiguration GetMatchingConfiguration(ConfigurationMetadata configMetadata, ConfigCreateCallback callback, bool loadProject)
        {
            lock (_configurations)
            {
                BuildRequestConfiguration configuration = GetMatchingConfiguration(configMetadata);

                // If there is no matching configuration, let the caller create one.
                if (configuration == null)
                {
                    configuration = callback(null, loadProject);
                    AddConfiguration(configuration);
                }
                else if (loadProject)
                {
                    // We already had a configuration, load the project
                    // If it exists but it cached, retrieve it 
                    if (configuration.IsCached)
                    {
                        configuration.RetrieveFromCache();
                    }

                    // If it is still not loaded (because no instance was ever created here), let the caller populate the instance.
                    if (!configuration.IsLoaded)
                    {
                        callback(configuration, loadProject: true);
                    }
                }

                // In either case, make sure the project is loaded if it was requested.
                if (loadProject)
                {
                    ErrorUtilities.VerifyThrow(configuration.IsLoaded, "Request to create configuration did not honor request to also load project.");
                }

                return configuration;
            }
        }
Beispiel #36
0
        /// <summary>
        /// Returns the entry in the cache which matches the specified config.
        /// </summary>
        /// <param name="configMetadata">The configuration metadata to match</param>
        /// <returns>A matching configuration if one exists, null otherwise.</returns>
        public BuildRequestConfiguration GetMatchingConfiguration(ConfigurationMetadata configMetadata)
        {
            ErrorUtilities.VerifyThrowArgumentNull(configMetadata, "configMetadata");
            lock (_configurations)
            {
                int configId;
                if (!_configurationIdsByMetadata.TryGetValue(configMetadata, out configId))
                {
                    return null;
                }

                return _configurations[configId];
            }
        }
Beispiel #37
0
 public ReferenceInfo(ConfigurationMetadata referenceConfiguration, ProjectItemInstance projectReferenceItem)
 {
     ReferenceConfiguration = referenceConfiguration;
     ProjectReferenceItem   = projectReferenceItem;
 }
        public void TestEquals()
        {
            BuildRequestData data = new BuildRequestData("file", new Dictionary<string, string>(), ObjectModelHelpers.MSBuildDefaultToolsVersion, new string[0], null);
            BuildRequestConfiguration config = new BuildRequestConfiguration(1, data, ObjectModelHelpers.MSBuildDefaultToolsVersion);

            Project project = CreateProject();

            ConfigurationMetadata metadata1 = new ConfigurationMetadata(config);
            ConfigurationMetadata metadata2 = new ConfigurationMetadata(project);
            Assert.IsTrue(metadata1.Equals(metadata2));

            data = new BuildRequestData("file2", new Dictionary<string, string>(), ObjectModelHelpers.MSBuildDefaultToolsVersion, new string[0], null);
            BuildRequestConfiguration config2 = new BuildRequestConfiguration(1, data, ObjectModelHelpers.MSBuildDefaultToolsVersion);
            ConfigurationMetadata metadata3 = new ConfigurationMetadata(config2);
            Assert.IsFalse(metadata1.Equals(metadata3));

            data = new BuildRequestData("file", new Dictionary<string, string>(), "3.0", new string[0], null);
            BuildRequestConfiguration config3 = new BuildRequestConfiguration(1, data, "3.0");
            ConfigurationMetadata metadata4 = new ConfigurationMetadata(config3);
            Assert.IsFalse(metadata1.Equals(metadata4));
        }
 public void TestConstructorNullConfiguration()
 {
     BuildRequestConfiguration config   = null;
     ConfigurationMetadata     metadata = new ConfigurationMetadata(config);
 }
Beispiel #40
0
 private void SubmitProjectForParsing(ConfigurationMetadata projectToEvaluate)
 {
     _graphWorkSet.AddWork(projectToEvaluate, () => ParseProject(projectToEvaluate));
 }
 public void TestConstructorNullConfiguration()
 {
     BuildRequestConfiguration config = null;
     ConfigurationMetadata metadata = new ConfigurationMetadata(config);
 }