public OutputPathTests(ITestOutputHelper output) { _output = output; ObjectModelHelpers.DeleteTempProjectDirectory(); }
public void TreatWarningsAsMessagesWhenSpecified() { MockLogger logger = ObjectModelHelpers.BuildProjectExpectSuccess(GetTestProject(warningsAsMessages: ExpectedEventCode)); VerifyBuildMessageEvent(logger); }
public void ProjectInstanceCanSerializeEntireStateViaTranslator(string projectContents) { projectContents = string.Format(projectContents, MSBuildConstants.CurrentToolsVersion); var original = new ProjectInstance(ProjectRootElement.Create(XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents(projectContents))))); original.TranslateEntireState = true; ((INodePacketTranslatable)original).Translate(TranslationHelpers.GetWriteTranslator()); var copy = ProjectInstance.FactoryForDeserialization(TranslationHelpers.GetReadTranslator()); Assert.Equal(original, copy, new ProjectInstanceComparer()); }
public void RemovingFilesRemovesEntries() { string content = ObjectModelHelpers.CleanupFileContents(@" <Project xmlns='msbuildnamespace' ToolsVersion='msbuilddefaulttoolsversion'> <ItemGroup>Content</ItemGroup> </Project> "); string path = FileUtilities.GetTemporaryFile(); try { File.WriteAllText(path, content); ProjectStringCache cache = new ProjectStringCache(); ProjectCollection collection = new ProjectCollection(); int entryCount; ProjectRootElement pre1 = ProjectRootElement.Create(collection); pre1.XmlDocument.StringCache = cache; pre1.FullPath = path; #if FEATURE_XML_LOADPATH pre1.XmlDocument.Load(path); #else var xmlReadSettings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore }; using (XmlReader xmlReader = XmlReader.Create(path, xmlReadSettings)) { pre1.XmlDocument.Load(xmlReader); } #endif entryCount = cache.Count; Assert.True(entryCount > 0); ProjectRootElement pre2 = ProjectRootElement.Create(collection); pre2.XmlDocument.StringCache = cache; pre2.FullPath = path; #if FEATURE_XML_LOADPATH pre2.XmlDocument.Load(path); #else using (XmlReader xmlReader = XmlReader.Create(path, xmlReadSettings)) { pre2.XmlDocument.Load(xmlReader); } #endif // Entry count should not have changed Assert.Equal(entryCount, cache.Count); string itemGroupContent = cache.Get("Content"); Assert.NotNull(itemGroupContent); XmlNodeList nodes1 = pre1.XmlDocument.GetElementsByTagName("ItemGroup"); XmlNodeList nodes2 = pre2.XmlDocument.GetElementsByTagName("ItemGroup"); Assert.Equal(1, nodes1.Count); Assert.Equal(1, nodes2.Count); XmlNode node1 = nodes1[0]; XmlNode node2 = nodes2[0]; Assert.NotNull(node1); Assert.NotNull(node2); Assert.NotSame(node1, node2); Assert.Same(node1.Value, node2.Value); // Now remove one document collection.UnloadProject(pre1); // We should still be able to get Content itemGroupContent = cache.Get("Content"); Assert.NotNull(itemGroupContent); // Now remove the second document collection.UnloadProject(pre2); // Now we should not be able to get Content itemGroupContent = cache.Get("Content"); Assert.Null(itemGroupContent); // And there should be no entries Assert.Equal(0, cache.Count); } finally { File.Delete(path); } }
public void ContentCanBeModified() { string content = ObjectModelHelpers.CleanupFileContents(@" <Project xmlns='msbuildnamespace' ToolsVersion='msbuilddefaulttoolsversion'> <ItemGroup attr1='attr1value'> Item group content </ItemGroup> </Project> "); string path = FileUtilities.GetTemporaryFile(); try { File.WriteAllText(path, content); ProjectStringCache cache = new ProjectStringCache(); XmlDocumentWithLocation document1 = new XmlDocumentWithLocation(); document1.StringCache = cache; #if FEATURE_XML_LOADPATH document1.Load(path); #else var xmlReadSettings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore }; using (XmlReader xmlReader = XmlReader.Create(path, xmlReadSettings)) { document1.Load(xmlReader); } #endif XmlDocumentWithLocation document2 = new XmlDocumentWithLocation(); document2.StringCache = cache; #if FEATURE_XML_LOADPATH document2.Load(path); #else using (XmlReader xmlReader = XmlReader.Create(path, xmlReadSettings)) { document2.Load(xmlReader); } #endif string outerXml1 = document1.OuterXml; string outerXml2 = document2.OuterXml; Assert.Equal(outerXml1, outerXml2); XmlNodeList nodes1 = document1.GetElementsByTagName("ItemGroup"); XmlNodeList nodes2 = document2.GetElementsByTagName("ItemGroup"); Assert.Equal(1, nodes1.Count); Assert.Equal(1, nodes2.Count); XmlNode node1 = nodes1[0]; XmlNode node2 = nodes2[0]; Assert.NotNull(node1); Assert.NotNull(node2); Assert.NotSame(node1, node2); Assert.Equal(1, node1.Attributes.Count); Assert.Equal(1, node2.Attributes.Count); Assert.Same(node1.Attributes[0].Value, node2.Attributes[0].Value); node2.Attributes[0].Value = "attr1value"; Assert.Equal(node1.Attributes[0].Value, node2.Attributes[0].Value); Assert.NotSame(node1.Attributes[0].Value, node2.Attributes[0].Value); node1 = nodes1[0].FirstChild; node2 = nodes2[0].FirstChild; Assert.NotSame(node1, node2); Assert.Same(node1.Value, node2.Value); XmlText newText = document2.CreateTextNode("New Value"); XmlNode parent = node2.ParentNode; parent.ReplaceChild(newText, node2); Assert.NotEqual(outerXml1, document2.OuterXml); } finally { File.Delete(path); } }
public void TestDefiningProjectMetadata() { string projectA = Path.Combine(ObjectModelHelpers.TempProjectDir, "a.proj"); string projectB = Path.Combine(ObjectModelHelpers.TempProjectDir, "b.proj"); string includeFileA = Path.Combine(ObjectModelHelpers.TempProjectDir, "aaa4.cs"); string includeFileB = Path.Combine(ObjectModelHelpers.TempProjectDir, "bbb4.cs"); string contentsA = @"<?xml version=`1.0` encoding=`utf-8`?> <Project ToolsVersion=`msbuilddefaulttoolsversion` DefaultTargets=`Validate` xmlns=`msbuildnamespace`> <ItemGroup> <A Include=`aaaa.cs` /> <A2 Include=`aaa2.cs` /> <A2 Include=`aaa3.cs`> <Foo>Bar</Foo> </A2> </ItemGroup> <Import Project=`b.proj` /> <ItemGroup> <E Include=`@(C)` /> <F Include=`@(C);@(C2)` /> <G Include=`@(C->'%(Filename)')` /> <H Include=`@(C2->WithMetadataValue('Foo', 'Bar'))` /> <U Include=`*4.cs` /> </ItemGroup> <Target Name=`AddFromMainProject`> <ItemGroup> <B Include=`bbbb.cs` /> <I Include=`@(C)` /> <J Include=`@(C);@(C2)` /> <K Include=`@(C->'%(Filename)')` /> <L Include=`@(C2->WithMetadataValue('Foo', 'Bar'))` /> <V Include=`*4.cs` /> </ItemGroup> </Target> <Target Name=`Validate` DependsOnTargets=`AddFromMainProject;AddFromImport`> <Warning Text=`A is wrong: EXPECTED: [a] ACTUAL: [%(A.DefiningProjectName)]` Condition=`'%(A.DefiningProjectName)' != 'a'` /> <Warning Text=`B is wrong: EXPECTED: [a] ACTUAL: [%(B.DefiningProjectName)]` Condition=`'%(B.DefiningProjectName)' != 'a'` /> <Warning Text=`C is wrong: EXPECTED: [b] ACTUAL: [%(C.DefiningProjectName)]` Condition=`'%(C.DefiningProjectName)' != 'b'` /> <Warning Text=`D is wrong: EXPECTED: [b] ACTUAL: [%(D.DefiningProjectName)]` Condition=`'%(D.DefiningProjectName)' != 'b'` /> <Warning Text=`E is wrong: EXPECTED: [a] ACTUAL: [%(E.DefiningProjectName)]` Condition=`'%(E.DefiningProjectName)' != 'a'` /> <Warning Text=`F is wrong: EXPECTED: [a] ACTUAL: [%(F.DefiningProjectName)]` Condition=`'%(F.DefiningProjectName)' != 'a'` /> <Warning Text=`G is wrong: EXPECTED: [a] ACTUAL: [%(G.DefiningProjectName)]` Condition=`'%(G.DefiningProjectName)' != 'a'` /> <Warning Text=`H is wrong: EXPECTED: [a] ACTUAL: [%(H.DefiningProjectName)]` Condition=`'%(H.DefiningProjectName)' != 'a'` /> <Warning Text=`I is wrong: EXPECTED: [a] ACTUAL: [%(I.DefiningProjectName)]` Condition=`'%(I.DefiningProjectName)' != 'a'` /> <Warning Text=`J is wrong: EXPECTED: [a] ACTUAL: [%(J.DefiningProjectName)]` Condition=`'%(J.DefiningProjectName)' != 'a'` /> <Warning Text=`K is wrong: EXPECTED: [a] ACTUAL: [%(K.DefiningProjectName)]` Condition=`'%(K.DefiningProjectName)' != 'a'` /> <Warning Text=`L is wrong: EXPECTED: [a] ACTUAL: [%(L.DefiningProjectName)]` Condition=`'%(L.DefiningProjectName)' != 'a'` /> <Warning Text=`M is wrong: EXPECTED: [b] ACTUAL: [%(M.DefiningProjectName)]` Condition=`'%(M.DefiningProjectName)' != 'b'` /> <Warning Text=`N is wrong: EXPECTED: [b] ACTUAL: [%(N.DefiningProjectName)]` Condition=`'%(N.DefiningProjectName)' != 'b'` /> <Warning Text=`O is wrong: EXPECTED: [b] ACTUAL: [%(O.DefiningProjectName)]` Condition=`'%(O.DefiningProjectName)' != 'b'` /> <Warning Text=`P is wrong: EXPECTED: [b] ACTUAL: [%(P.DefiningProjectName)]` Condition=`'%(P.DefiningProjectName)' != 'b'` /> <Warning Text=`Q is wrong: EXPECTED: [b] ACTUAL: [%(Q.DefiningProjectName)]` Condition=`'%(Q.DefiningProjectName)' != 'b'` /> <Warning Text=`R is wrong: EXPECTED: [b] ACTUAL: [%(R.DefiningProjectName)]` Condition=`'%(R.DefiningProjectName)' != 'b'` /> <Warning Text=`S is wrong: EXPECTED: [b] ACTUAL: [%(S.DefiningProjectName)]` Condition=`'%(S.DefiningProjectName)' != 'b'` /> <Warning Text=`T is wrong: EXPECTED: [b] ACTUAL: [%(T.DefiningProjectName)]` Condition=`'%(T.DefiningProjectName)' != 'b'` /> <Warning Text=`U is wrong: EXPECTED: [a] ACTUAL: [%(U.DefiningProjectName)]` Condition=`'%(U.DefiningProjectName)' != 'a'` /> <Warning Text=`V is wrong: EXPECTED: [a] ACTUAL: [%(V.DefiningProjectName)]` Condition=`'%(V.DefiningProjectName)' != 'a'` /> <Warning Text=`W is wrong: EXPECTED: [b] ACTUAL: [%(W.DefiningProjectName)]` Condition=`'%(W.DefiningProjectName)' != 'b'` /> <Warning Text=`X is wrong: EXPECTED: [b] ACTUAL: [%(X.DefiningProjectName)]` Condition=`'%(X.DefiningProjectName)' != 'b'` /> </Target> </Project>"; string contentsB = @"<?xml version=`1.0` encoding=`utf-8`?> <Project ToolsVersion=`msbuilddefaulttoolsversion` xmlns=`msbuildnamespace`> <ItemGroup> <C Include=`cccc.cs` /> <C2 Include=`ccc2.cs` /> <C2 Include=`ccc3.cs`> <Foo>Bar</Foo> </C2> <M Include=`@(A)` /> <N Include=`@(A);@(A2)` /> <O Include=`@(A->'%(Filename)')` /> <P Include=`@(A2->WithMetadataValue('Foo', 'Bar'))` /> <W Include=`*4.cs` /> </ItemGroup> <Target Name=`AddFromImport`> <ItemGroup> <D Include=`dddd.cs` /> <Q Include=`@(A)` /> <R Include=`@(A);@(A2)` /> <S Include=`@(A->'%(Filename)')` /> <T Include=`@(A2->WithMetadataValue('Foo', 'Bar'))` /> <X Include=`*4.cs` /> </ItemGroup> </Target> </Project>"; try { File.WriteAllText(projectA, ObjectModelHelpers.CleanupFileContents(contentsA)); File.WriteAllText(projectB, ObjectModelHelpers.CleanupFileContents(contentsB)); File.WriteAllText(includeFileA, "aaaaaaa"); File.WriteAllText(includeFileB, "bbbbbbb"); MockLogger logger = new MockLogger(_testOutput); ObjectModelHelpers.BuildTempProjectFileExpectSuccess("a.proj", logger); logger.AssertNoWarnings(); } finally { if (File.Exists(projectA)) { File.Delete(projectA); } if (File.Exists(projectB)) { File.Delete(projectB); } if (File.Exists(includeFileA)) { File.Delete(includeFileA); } if (File.Exists(includeFileB)) { File.Delete(includeFileB); } } }
public void ItemOperationsShouldExpandIndirectItemReferences(string projectContent, string[] expectedItemValues, Dictionary <string, string> expectedItemMetadata) { var items = ObjectModelHelpers.GetItems(projectContent); ObjectModelHelpers.AssertItems(expectedItemValues, items, expectedItemMetadata); }
public void BasicItemDictionary() { ItemDictionary <ProjectItemInstance> items = new ItemDictionary <ProjectItemInstance>(); // Clearing empty collection items.Clear(); // Enumeration of empty collection using (IEnumerator <ProjectItemInstance> enumerator = items.GetEnumerator()) { Assert.Equal(false, enumerator.MoveNext()); ObjectModelHelpers.AssertThrows(typeof(InvalidOperationException), delegate { object o = ((IEnumerator)enumerator).Current; }); Assert.Equal(null, enumerator.Current); } List <ProjectItemInstance> list = new List <ProjectItemInstance>(); foreach (ProjectItemInstance item in items) { list.Add(item); } Assert.Equal(0, list.Count); // Cause an empty list for type 'x' to be added ICollection <ProjectItemInstance> itemList = items["x"]; // Enumerate empty collection, with an empty list in it foreach (ProjectItemInstance item in items) { list.Add(item); } Assert.Equal(0, list.Count); // Add and remove some items ProjectItemInstance item1 = GetItemInstance("i", "i1"); Assert.Equal(false, items.Remove(item1)); Assert.Equal(0, items["j"].Count); items.Add(item1); Assert.Equal(1, items["i"].Count); Assert.Equal(item1, items["i"].First()); ProjectItemInstance item2 = GetItemInstance("i", "i2"); items.Add(item2); ProjectItemInstance item3 = GetItemInstance("j", "j1"); items.Add(item3); // Enumerate to verify contents list = new List <ProjectItemInstance>(); foreach (ProjectItemInstance item in items) { list.Add(item); } list.Sort(ProjectItemInstanceComparer); Assert.Equal(item1, list[0]); Assert.Equal(item2, list[1]); Assert.Equal(item3, list[2]); // Direct operations on the enumerator using (IEnumerator <ProjectItemInstance> enumerator = items.GetEnumerator()) { Assert.Equal(null, enumerator.Current); Assert.Equal(true, enumerator.MoveNext()); Assert.NotNull(enumerator.Current); enumerator.Reset(); Assert.Equal(null, enumerator.Current); Assert.Equal(true, enumerator.MoveNext()); Assert.NotNull(enumerator.Current); } }
public void TwoWithContent() { string one = ObjectModelHelpers.CleanupFileContents( @"<?xml version=""1.0"" encoding=""utf-16""?> <Project ToolsVersion=""msbuilddefaulttoolsversion"" xmlns=""msbuildnamespace""> <PropertyGroup> <p>v0</p> </PropertyGroup> <Import Project=""p2""/> <PropertyGroup> <p>v2</p> </PropertyGroup> </Project>"); string two = ObjectModelHelpers.CleanupFileContents( @"<?xml version=""1.0"" encoding=""utf-16""?> <Project ToolsVersion=""msbuilddefaulttoolsversion"" xmlns=""msbuildnamespace""> <PropertyGroup> <p>v1</p> </PropertyGroup> </Project>"); ProjectRootElement twoXml = ProjectRootElement.Create(XmlReader.Create(new StringReader(two))); twoXml.FullPath = "p2"; Project project; using (StringReader sr = new StringReader(one)) { using (XmlReader xr = XmlTextReader.Create(sr)) { project = new Project(xr); } } StringWriter writer = new StringWriter(); project.SaveLogicalProject(writer); string expected = ObjectModelHelpers.CleanupFileContents( @"<?xml version=""1.0"" encoding=""utf-16""?> <Project ToolsVersion=""msbuilddefaulttoolsversion"" xmlns=""msbuildnamespace""> <PropertyGroup> <p>v0</p> </PropertyGroup> <!-- ============================================================================================================================================ <Import Project=""p2""> " + CurrentDirectoryXmlCommentFriendly + Path.DirectorySeparatorChar + @"p2 ============================================================================================================================================ --> <PropertyGroup> <p>v1</p> </PropertyGroup> <!-- ============================================================================================================================================ </Import> ============================================================================================================================================ --> <PropertyGroup> <p>v2</p> </PropertyGroup> </Project>"); Helpers.VerifyAssertLineByLine(expected, writer.ToString()); }
/// <summary> /// Overload for project file content. /// </summary> /// <returns>Project File Content</returns> internal static string CreateTempProjectFile(string projContent) { return(ObjectModelHelpers.CreateFileInTempProjectDirectory("p.proj", projContent)); }
public void UsingExplicitToolsVersionShouldBeFalseWhenNoToolsetIsReferencedInProject() { var project = ObjectModelHelpers.CreateInMemoryProject("<Project></Project>"); project.TestOnlyGetPrivateData.UsingDifferentToolsVersionFromProjectFile.ShouldBeFalse(); }
/* * Method: PostBuildBuilder * * Build a project file that mimics the fairly complex way we plan to use OnError * to handle all the different combinations of project failures and post-build * conditions. * */ private static string PostBuildBuilder ( string controlFlag, // On_Success, Always, Final_Output_Changed FailAt failAt ) { string compileStep = ""; if (FailAt.Compile == failAt) { compileStep = "<Error Text='Compile-step-failed'/>"; } string generateSatellites = ""; if (FailAt.GenerateSatellites == failAt) { generateSatellites = "<Error Text='GenerateSatellites-step-failed'/>"; } return(String.Format(ObjectModelHelpers.CleanupFileContents(@" <Project DefaultTargets='Build' ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <PropertyGroup> <Flag>{0}</Flag> </PropertyGroup> <Target Name='ResGen'> <Message Text='ResGen-was-called.'/> </Target> <Target Name='Compile'> <Message Text='Compile-was-called.'/> <RemoveDir Directories='c:\__Hopefully_Nonexistent_Directory__'/> {1} <CreateItem Include='Yes'> <Output TaskParameter='Include' ItemName='FinalOutputChanged'/> </CreateItem> </Target> <Target Name='GenerateSatellites'> <Message Text='GenerateSatellites-was-called.'/> {2} </Target> <Target Name='PostBuild'> <Message Text='PostBuild-was-called.'/> </Target> <Target Name='PostBuildOnSuccess' Condition=""'$(Flag)'!='Final_Output_Changed'"" DependsOnTargets='PostBuild'> <Message Text='PostBuildOnSuccess-was-called.'/> </Target> <Target Name='PostBuildOnOutputChange' Condition=""'$(Flag)_@(FinalOutputChanged)'=='Final_Output_Changed_Yes'"" DependsOnTargets='PostBuild'> <Message Text='PostBuildOnOutputChange-was-called.'/> </Target> <Target Name='CoreBuildSucceeded' DependsOnTargets='PostBuildOnSuccess;PostBuildOnOutputChange'> <Message Text='CoreBuildSucceeded-was-called.'/> </Target> <Target Name='CoreBuild' DependsOnTargets='ResGen;Compile;GenerateSatellites'> <Message Text='CoreBuild-was-called.'/> <OnError Condition=""'$(Flag)'=='Always'"" ExecuteTargets='PostBuild'/> <OnError ExecuteTargets='PostBuildOnOutputChange'/> </Target> <Target Name='Build' DependsOnTargets='CoreBuild;CoreBuildSucceeded'> <Message Text='Build-target-was-called.'/> </Target> </Project> "), controlFlag, compileStep, generateSatellites)); }
public void FailingTaskStillPublishesOutputs() { MockLogger l = new MockLogger(); string resx = Path.Combine(Path.GetTempPath(), "FailingTaskStillPublishesOutputs.resx"); try { File.WriteAllText(resx, @" <root> <resheader name=""resmimetype""> <value>text/microsoft-resx</value> </resheader> <resheader name=""version""> <value>2.0</value> </resheader> <resheader name=""reader""> <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <resheader name=""writer""> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> </resheader> <data name=""a""> <value>aa</value> </data> <data name=""b""> <value>bb</value> </data> </root>"); Project project = new Project(XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents(@" <Project DefaultTargets='Build' ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <Target Name='Build'> <GenerateResource ExecuteAsTool='false' Sources='" + resx + @"' StronglyTypedLanguage='!@:|'> <Output TaskParameter='FilesWritten' ItemName='FilesWrittenItem'/> <Output TaskParameter='FilesWritten' PropertyName='FilesWrittenProperty'/> </GenerateResource> <OnError ExecuteTargets='ErrorTarget'/> </Target> <Target Name='ErrorTarget'> <Message Text='[@(fileswrittenitem)]'/> <Message Text='[$(fileswrittenproperty)]'/> </Target> </Project>")))); ProjectInstance p = project.CreateProjectInstance(); p.Build(new string[] { "Build" }, new ILogger[] { l }); string resource = Path.ChangeExtension(resx, ".resources"); Assert.Equal(1, l.ErrorCount); // "Expected one error because 'Build' failed." l.AssertLogContains("[" + resource + "]", "[" + resource + "]"); // And outputs are visible at the project level Assert.Equal(resource, Helpers.MakeList(p.GetItems("FilesWrittenItem"))[0].EvaluatedInclude); Assert.Equal(resource, p.GetPropertyValue("FilesWrittenProperty")); p = project.CreateProjectInstance(); // But are gone after resetting of course Assert.Empty(Helpers.MakeList(p.GetItems("FilesWrittenItem"))); Assert.Equal(String.Empty, p.GetPropertyValue("FilesWrittenProperty")); } finally { File.Delete(resx); } }
public void Dispose() { ObjectModelHelpers.DeleteTempProjectDirectory(); }
private DependencyAnalysisResult PerformDependencyAnalysisTestHelper ( FileWriteInfo[] filesToAnalyze, ItemDictionary <ProjectItemInstance> itemsByName, string inputs, string outputs, out ItemDictionary <ProjectItemInstance> changedTargetInputs, out ItemDictionary <ProjectItemInstance> upToDateTargetInputs ) { List <string> filesToDelete = new List <string>(); try { // first set the disk up for (int i = 0; i < filesToAnalyze.Length; ++i) { string path = ObjectModelHelpers.CreateFileInTempProjectDirectory(filesToAnalyze[i].Path, ""); File.SetCreationTime(path, filesToAnalyze[i].LastWriteTime); File.SetLastWriteTime(path, filesToAnalyze[i].LastWriteTime); filesToDelete.Add(path); } // Wait Thread.Sleep(50); // now create the project string unformattedProjectXml = ObjectModelHelpers.CleanupFileContents( @"<Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <Target Name='Build' Inputs=""{0}"" Outputs=""{1}""> </Target> </Project>" ); string projectFile = Path.Combine(ObjectModelHelpers.TempProjectDir, "temp.proj"); string formattedProjectXml = String.Format(unformattedProjectXml, inputs, outputs); File.WriteAllText(projectFile, formattedProjectXml); // Wait Thread.Sleep(50); filesToDelete.Add(projectFile); Project project = new Project(projectFile); ProjectInstance p = project.CreateProjectInstance(); // now do the dependency analysis ItemBucket itemBucket = new ItemBucket(null, null, new Lookup(itemsByName, new PropertyDictionary <ProjectPropertyInstance>()), 0); TargetUpToDateChecker analyzer = new TargetUpToDateChecker(p, p.Targets["Build"], _mockHost, BuildEventContext.Invalid); return(analyzer.PerformDependencyAnalysis(itemBucket, out changedTargetInputs, out upToDateTargetInputs)); } finally { // finally clean up foreach (string path in filesToDelete) { if (File.Exists(path)) { File.Delete(path); } } ProjectCollection.GlobalProjectCollection.UnloadAllProjects(); } }
public void ImportGroupDoubleChildPlusCondition() { ProjectRootElement xml1 = ProjectRootElement.Create("p1"); xml1.AddProperty("p", "v1"); ProjectImportGroupElement group = xml1.AddImportGroup(); group.Condition = "true"; group.AddImport("p2"); group.AddImport("p3"); ProjectRootElement xml2 = ProjectRootElement.Create("p2"); xml2.AddProperty("p", "v2"); ProjectRootElement xml3 = ProjectRootElement.Create("p3"); xml3.AddProperty("p", "v3"); Project project = new Project(xml1); StringWriter writer = new StringWriter(); project.SaveLogicalProject(writer); string expected = ObjectModelHelpers.CleanupFileContents( @"<?xml version=""1.0"" encoding=""utf-16""?> <!-- ============================================================================================================================================ " + CurrentDirectoryXmlCommentFriendly + Path.DirectorySeparatorChar + @"p1 ============================================================================================================================================ --> <Project ToolsVersion=""msbuilddefaulttoolsversion"" xmlns=""msbuildnamespace""> <PropertyGroup> <p>v1</p> </PropertyGroup> <!--<ImportGroup Condition=""true"">--> <!-- ============================================================================================================================================ <Import Project=""p2""> " + CurrentDirectoryXmlCommentFriendly + Path.DirectorySeparatorChar + @"p2 ============================================================================================================================================ --> <PropertyGroup> <p>v2</p> </PropertyGroup> <!-- ============================================================================================================================================ </Import> " + CurrentDirectoryXmlCommentFriendly + Path.DirectorySeparatorChar + @"p1 ============================================================================================================================================ --> <!-- ============================================================================================================================================ <Import Project=""p3""> " + CurrentDirectoryXmlCommentFriendly + Path.DirectorySeparatorChar + @"p3 ============================================================================================================================================ --> <PropertyGroup> <p>v3</p> </PropertyGroup> <!-- ============================================================================================================================================ </Import> " + CurrentDirectoryXmlCommentFriendly + Path.DirectorySeparatorChar + @"p1 ============================================================================================================================================ --> <!--</ImportGroup>--> </Project>"); Helpers.VerifyAssertLineByLine(expected, writer.ToString()); }
public void ExtensionPathsTest_Basic1() { // NOTE: for some reason, <configSections> MUST be the first element under <configuration> // for the API to read it. The docs don't make this clear. ToolsetConfigurationReaderTestHelper.WriteConfigFile(ObjectModelHelpers.CleanupFileContents(@" <configuration> <configSections> <section name=""msbuildToolsets"" type=""Microsoft.Build.Evaluation.ToolsetConfigurationSection, Microsoft.Build"" /> </configSections> <msbuildToolsets default=""2.0""> <toolset toolsVersion=""2.0""> <property name=""MSBuildBinPath"" value=""D:\windows\Microsoft.NET\Framework\v2.0.x86ret\""/> <property name=""MSBuildToolsPath"" value=""D:\windows\Microsoft.NET\Framework\v2.0.x86ret\""/> <projectImportSearchPaths> <searchPaths os=""windows""> <property name=""MSBuildExtensionsPath"" value=""c:\foo""/> <property name=""MSBuildExtensionsPath64"" value=""c:\foo64;c:\bar64""/> </searchPaths> <searchPaths os=""osx""> <property name=""MSBuildExtensionsPath"" value=""/tmp/foo""/> <property name=""MSBuildExtensionsPath32"" value=""/tmp/foo32;/tmp/bar32""/> </searchPaths> <searchPaths os=""unix""> <property name=""MSBuildExtensionsPath"" value=""/tmp/bar""/> </searchPaths> </projectImportSearchPaths> </toolset> </msbuildToolsets> </configuration>")); Configuration config = ToolsetConfigurationReaderTestHelper.ReadApplicationConfigurationTest(); ToolsetConfigurationSection msbuildToolsetSection = config.GetSection(s_msbuildToolsets) as ToolsetConfigurationSection; Assert.Equal("2.0", msbuildToolsetSection.Default); Assert.Single(msbuildToolsetSection.Toolsets); Assert.Equal("2.0", msbuildToolsetSection.Toolsets.GetElement(0).toolsVersion); Assert.Equal(2, msbuildToolsetSection.Toolsets.GetElement("2.0").PropertyElements.Count); Assert.Equal( @"D:\windows\Microsoft.NET\Framework\v2.0.x86ret\", msbuildToolsetSection.Toolsets.GetElement("2.0").PropertyElements.GetElement("MSBuildBinPath").Value); Assert.Equal(3, msbuildToolsetSection.Toolsets.GetElement(0).AllProjectImportSearchPaths.Count); var allPaths = msbuildToolsetSection.Toolsets.GetElement(0).AllProjectImportSearchPaths; Assert.Equal("windows", allPaths.GetElement(0).OS); Assert.Equal(2, allPaths.GetElement(0).PropertyElements.Count); Assert.Equal(@"c:\foo", allPaths.GetElement(0).PropertyElements.GetElement("MSBuildExtensionsPath").Value); Assert.Equal(@"c:\foo64;c:\bar64", allPaths.GetElement(0).PropertyElements.GetElement("MSBuildExtensionsPath64").Value); Assert.Equal("osx", allPaths.GetElement(1).OS); Assert.Equal(2, allPaths.GetElement(1).PropertyElements.Count); Assert.Equal(@"/tmp/foo", allPaths.GetElement(1).PropertyElements.GetElement("MSBuildExtensionsPath").Value); Assert.Equal(@"/tmp/foo32;/tmp/bar32", allPaths.GetElement(1).PropertyElements.GetElement("MSBuildExtensionsPath32").Value); Assert.Equal("unix", allPaths.GetElement(2).OS); Assert.Single(allPaths.GetElement(2).PropertyElements); Assert.Equal(@"/tmp/bar", allPaths.GetElement(2).PropertyElements.GetElement("MSBuildExtensionsPath").Value); var reader = GetStandardConfigurationReader(); Dictionary <string, Toolset> toolsets = new Dictionary <string, Toolset>(StringComparer.OrdinalIgnoreCase); string msbuildOverrideTasksPath = null; string defaultOverrideToolsVersion = null; reader.ReadToolsets(toolsets, new PropertyDictionary <ProjectPropertyInstance>(), new PropertyDictionary <ProjectPropertyInstance>(), true, out msbuildOverrideTasksPath, out defaultOverrideToolsVersion); Dictionary <string, ProjectImportPathMatch> pathsTable = toolsets["2.0"].ImportPropertySearchPathsTable; if (NativeMethodsShared.IsWindows) { CheckPathsTable(pathsTable, "MSBuildExtensionsPath", new string[] { "c:\\foo" }); CheckPathsTable(pathsTable, "MSBuildExtensionsPath64", new string[] { "c:\\foo64", "c:\\bar64" }); } else if (NativeMethodsShared.IsOSX) { CheckPathsTable(pathsTable, "MSBuildExtensionsPath", new string[] { "/tmp/foo" }); CheckPathsTable(pathsTable, "MSBuildExtensionsPath32", new string[] { "/tmp/foo32", "/tmp/bar32" }); } else { CheckPathsTable(pathsTable, "MSBuildExtensionsPath", new string[] { "/tmp/bar" }); } }
public void ImportWildcard() { string directory = null; ProjectRootElement xml0, xml1 = null, xml2 = null, xml3 = null; try { directory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString()); Directory.CreateDirectory(directory); xml0 = ProjectRootElement.Create("p1"); xml0.AddImport(directory + Path.DirectorySeparatorChar + "*.targets"); xml1 = ProjectRootElement.Create(directory + Path.DirectorySeparatorChar + "1.targets"); xml1.AddProperty("p", "v1"); xml1.Save(); xml2 = ProjectRootElement.Create(directory + Path.DirectorySeparatorChar + "2.targets"); xml2.AddProperty("p", "v2"); xml2.Save(); xml3 = ProjectRootElement.Create(directory + Path.DirectorySeparatorChar + "3.xxxxxx"); xml3.AddProperty("p", "v3"); xml3.Save(); Project project = new Project(xml0); StringWriter writer = new StringWriter(); project.SaveLogicalProject(writer); string directoryXmlCommentFriendly = directory.Replace("--", "__"); string expected = ObjectModelHelpers.CleanupFileContents( @"<?xml version=""1.0"" encoding=""utf-16""?> <!-- ============================================================================================================================================ " + CurrentDirectoryXmlCommentFriendly + Path.DirectorySeparatorChar + @"p1 ============================================================================================================================================ --> <Project ToolsVersion=""msbuilddefaulttoolsversion"" xmlns=""msbuildnamespace""> <!-- ============================================================================================================================================ <Import Project=""" + Path.Combine(directoryXmlCommentFriendly, "*.targets") + @"""> " + Path.Combine(directoryXmlCommentFriendly, "1.targets") + @" ============================================================================================================================================ --> <PropertyGroup> <p>v1</p> </PropertyGroup> <!-- ============================================================================================================================================ </Import> ============================================================================================================================================ --> <!-- ============================================================================================================================================ <Import Project=""" + Path.Combine(directoryXmlCommentFriendly, "*.targets") + @"""> " + Path.Combine(directoryXmlCommentFriendly, "2.targets") + @" ============================================================================================================================================ --> <PropertyGroup> <p>v2</p> </PropertyGroup> <!-- ============================================================================================================================================ </Import> " + CurrentDirectoryXmlCommentFriendly + Path.DirectorySeparatorChar + @"p1 ============================================================================================================================================ --> </Project>"); Helpers.VerifyAssertLineByLine(expected, writer.ToString()); } finally { File.Delete(xml1.FullPath); File.Delete(xml2.FullPath); File.Delete(xml3.FullPath); FileUtilities.DeleteWithoutTrailingBackslash(directory); } }
public void UpdateShouldPreserveIntermediaryReferences() { var content = @" <i2 Include='a;b;c'> <m1>m1_contents</m1> <m2>%(Identity)</m2> </i2> <i Include='@(i2)'> <m3>@(i2 -> '%(m2)')</m3> <m4 Condition=""'@(i2 -> '%(m2)')' == 'a;b;c'"">m4_contents</m4> </i> <i2 Update='a;b;c'> <m1>m1_updated</m1> <m2>m2_updated</m2> <m3>m3_updated</m3> <m4>m4_updated</m4> </i2>"; IList <ProjectItem> items = ObjectModelHelpers.GetItemsFromFragment(content, allItems: true); var a = new Dictionary <string, string> { { "m1", "m1_contents" }, { "m2", "a" }, { "m3", "a;b;c" }, { "m4", "m4_contents" }, }; var b = new Dictionary <string, string> { { "m1", "m1_contents" }, { "m2", "b" }, { "m3", "a;b;c" }, { "m4", "m4_contents" } }; var c = new Dictionary <string, string> { { "m1", "m1_contents" }, { "m2", "c" }, { "m3", "a;b;c" }, { "m4", "m4_contents" }, }; var itemsForI = items.Where(i => i.ItemType == "i").ToList(); ObjectModelHelpers.AssertItems(new[] { "a", "b", "c" }, itemsForI, new [] { a, b, c }); var metadataForI2 = new Dictionary <string, string> { { "m1", "m1_updated" }, { "m2", "m2_updated" }, { "m3", "m3_updated" }, { "m4", "m4_updated" } }; var itemsForI2 = items.Where(i => i.ItemType == "i2").ToList(); ObjectModelHelpers.AssertItems(new[] { "a", "b", "c" }, itemsForI2, metadataForI2); }
public void SdkImportsAreInPreprocessedOutput() { using (TestEnvironment env = TestEnvironment.Create()) { string testSdkDirectory = env.CreateFolder().FolderPath; var projectOptions = SdkUtilities.CreateProjectOptionsWithResolver(new SdkUtilities.FileBasedMockSdkResolver(new Dictionary <string, string> { { "MSBuildUnitTestSdk", testSdkDirectory } })); string sdkPropsPath = Path.Combine(testSdkDirectory, "Sdk.props"); string sdkTargetsPath = Path.Combine(testSdkDirectory, "Sdk.targets"); File.WriteAllText(sdkPropsPath, @"<Project> <PropertyGroup> <SdkPropsImported>true</SdkPropsImported> </PropertyGroup> </Project>"); File.WriteAllText(sdkTargetsPath, @"<Project> <PropertyGroup> <SdkTargetsImported>true</SdkTargetsImported> </PropertyGroup> </Project>"); string content = @"<Project Sdk='MSBuildUnitTestSdk'> <PropertyGroup> <p>v1</p> </PropertyGroup> </Project>"; Project project = Project.FromProjectRootElement( ProjectRootElement.Create(XmlReader.Create(new StringReader(content))), projectOptions); StringWriter writer = new StringWriter(); project.SaveLogicalProject(writer); string expected = ObjectModelHelpers.CleanupFileContents( $@"<?xml version=""1.0"" encoding=""utf-16""?> <Project> <!-- ============================================================================================================================================ <Import Project=""Sdk.props"" Sdk=""MSBuildUnitTestSdk""> This import was added implicitly because the Project element's Sdk attribute specified ""MSBuildUnitTestSdk"". {sdkPropsPath.Replace("--", "__")} ============================================================================================================================================ --> <PropertyGroup> <SdkPropsImported>true</SdkPropsImported> </PropertyGroup> <!-- ============================================================================================================================================ </Import> ============================================================================================================================================ --> <PropertyGroup> <p>v1</p> </PropertyGroup> <!-- ============================================================================================================================================ <Import Project=""Sdk.targets"" Sdk=""MSBuildUnitTestSdk""> This import was added implicitly because the Project element's Sdk attribute specified ""MSBuildUnitTestSdk"". {sdkTargetsPath.Replace("--", "__")} ============================================================================================================================================ --> <PropertyGroup> <SdkTargetsImported>true</SdkTargetsImported> </PropertyGroup> <!-- ============================================================================================================================================ </Import> ============================================================================================================================================ --> </Project>"); Helpers.VerifyAssertLineByLine(expected, writer.ToString()); } }
public void MultipleInterItemDependenciesOnSameItemOperation() { var content = @" <i1 Include='i1_1;i1_2;i1_3;i1_4;i1_5'/> <i1 Update='*'> <m>i1</m> </i1> <i1 Remove='*i1_5'/> <i_cond Condition='@(i1->Count()) == 4' Include='i1 has 4 items'/> <i2 Include='@(i1);i2_4'/> <i2 Remove='i?_4'/> <i2 Update='i?_1'> <m>i2</m> </i2> <i3 Include='@(i1);i3_3'/> <i3 Remove='*i?_3'/> <i1 Remove='*i1_2'/> <i1 Include='i1_6'/>"; IList <ProjectItem> items = ObjectModelHelpers.GetItemsFromFragment(content, allItems: true); var i1BaseMetadata = new Dictionary <string, string> { { "m", "i1" } }; //i1 items: i1_1; i1_3; i1_4; i1_6 var i1Metadata = new Dictionary <string, string>[] { i1BaseMetadata, i1BaseMetadata, i1BaseMetadata, new Dictionary <string, string>() }; var i1Items = items.Where(i => i.ItemType == "i1").ToList(); ObjectModelHelpers.AssertItems(new[] { "i1_1", "i1_3", "i1_4", "i1_6" }, i1Items, i1Metadata); //i2 items: i1_1; i1_2; i1_3 var i2Metadata = new Dictionary <string, string>[] { new Dictionary <string, string> { { "m", "i2" } }, i1BaseMetadata, i1BaseMetadata }; var i2Items = items.Where(i => i.ItemType == "i2").ToList(); ObjectModelHelpers.AssertItems(new[] { "i1_1", "i1_2", "i1_3" }, i2Items, i2Metadata); //i3 items: i1_1; i1_2; i1_4 var i3Items = items.Where(i => i.ItemType == "i3").ToList(); ObjectModelHelpers.AssertItems(new[] { "i1_1", "i1_2", "i1_4" }, i3Items, i1BaseMetadata); var i_condItems = items.Where(i => i.ItemType == "i_cond").ToList(); ObjectModelHelpers.AssertItems(new[] { "i1 has 4 items" }, i_condItems); }
public void ImportedProjectsSdkImportsAreInPreprocessedOutput() { using (TestEnvironment env = TestEnvironment.Create()) { string sdk1 = env.CreateFolder().FolderPath; string sdk2 = env.CreateFolder().FolderPath; var projectOptions = SdkUtilities.CreateProjectOptionsWithResolver(new SdkUtilities.FileBasedMockSdkResolver(new Dictionary <string, string> { { "MSBuildUnitTestSdk1", sdk1 }, { "MSBuildUnitTestSdk2", sdk2 }, })); string sdkPropsPath1 = Path.Combine(sdk1, "Sdk.props"); string sdkTargetsPath1 = Path.Combine(sdk1, "Sdk.targets"); File.WriteAllText(sdkPropsPath1, @"<Project> <PropertyGroup> <SdkProps1Imported>true</SdkProps1Imported> </PropertyGroup> </Project>"); File.WriteAllText(sdkTargetsPath1, @"<Project> <PropertyGroup> <SdkTargets1Imported>true</SdkTargets1Imported> </PropertyGroup> </Project>"); string sdkPropsPath2 = Path.Combine(sdk2, "Sdk.props"); string sdkTargetsPath2 = Path.Combine(sdk2, "Sdk.targets"); File.WriteAllText(sdkPropsPath2, @"<Project> <PropertyGroup> <SdkProps2Imported>true</SdkProps2Imported> </PropertyGroup> </Project>"); File.WriteAllText(sdkTargetsPath2, @"<Project> <PropertyGroup> <SdkTargets2Imported>true</SdkTargets2Imported> </PropertyGroup> </Project>"); TransientTestProjectWithFiles import = env.CreateTestProjectWithFiles(@"<Project Sdk='MSBuildUnitTestSdk2'> <PropertyGroup> <MyImportWasImported>true</MyImportWasImported> </PropertyGroup> </Project>"); string importPath = Path.GetFullPath(import.ProjectFile); string content = $@"<Project Sdk='MSBuildUnitTestSdk1'> <Import Project='{importPath}' /> <PropertyGroup> <p>v1</p> </PropertyGroup> </Project>"; Project project = Project.FromProjectRootElement( ProjectRootElement.Create(XmlReader.Create(new StringReader(content))), projectOptions); StringWriter writer = new StringWriter(); project.SaveLogicalProject(writer); string expected = ObjectModelHelpers.CleanupFileContents( $@"<?xml version=""1.0"" encoding=""utf-16""?> <Project> <!-- ============================================================================================================================================ <Import Project=""Sdk.props"" Sdk=""MSBuildUnitTestSdk1""> This import was added implicitly because the Project element's Sdk attribute specified ""MSBuildUnitTestSdk1"". {sdkPropsPath1.Replace("--", "__")} ============================================================================================================================================ --> <PropertyGroup> <SdkProps1Imported>true</SdkProps1Imported> </PropertyGroup> <!-- ============================================================================================================================================ </Import> ============================================================================================================================================ --> <!-- ============================================================================================================================================ <Import Project=""{importPath.Replace("--", "__")}""> {importPath.Replace("--", "__")} ============================================================================================================================================ --> <!-- ============================================================================================================================================ <Import Project=""Sdk.props"" Sdk=""MSBuildUnitTestSdk2""> This import was added implicitly because the Project element's Sdk attribute specified ""MSBuildUnitTestSdk2"". {sdkPropsPath2.Replace("--", "__")} ============================================================================================================================================ --> <PropertyGroup> <SdkProps2Imported>true</SdkProps2Imported> </PropertyGroup> <!-- ============================================================================================================================================ </Import> {importPath.Replace("--", "__")} ============================================================================================================================================ --> <PropertyGroup> <MyImportWasImported>true</MyImportWasImported> </PropertyGroup> <!-- ============================================================================================================================================ <Import Project=""Sdk.targets"" Sdk=""MSBuildUnitTestSdk2""> This import was added implicitly because the Project element's Sdk attribute specified ""MSBuildUnitTestSdk2"". {sdkTargetsPath2.Replace("--", "__")} ============================================================================================================================================ --> <PropertyGroup> <SdkTargets2Imported>true</SdkTargets2Imported> </PropertyGroup> <!-- ============================================================================================================================================ </Import> {importPath.Replace("--", "__")} ============================================================================================================================================ --> <!-- ============================================================================================================================================ </Import> ============================================================================================================================================ --> <PropertyGroup> <p>v1</p> </PropertyGroup> <!-- ============================================================================================================================================ <Import Project=""Sdk.targets"" Sdk=""MSBuildUnitTestSdk1""> This import was added implicitly because the Project element's Sdk attribute specified ""MSBuildUnitTestSdk1"". {sdkTargetsPath1.Replace("--", "__")} ============================================================================================================================================ --> <PropertyGroup> <SdkTargets1Imported>true</SdkTargets1Imported> </PropertyGroup> <!-- ============================================================================================================================================ </Import> ============================================================================================================================================ --> </Project>"); Helpers.VerifyAssertLineByLine(expected, writer.ToString()); } }
public void ContentIsSameAcrossInstances() { string content = ObjectModelHelpers.CleanupFileContents(@" <Project xmlns='msbuildnamespace' ToolsVersion='msbuilddefaulttoolsversion'> <ItemGroup> Item group content </ItemGroup> </Project> "); string path = FileUtilities.GetTemporaryFile(); try { File.WriteAllText(path, content); ProjectStringCache cache = new ProjectStringCache(); XmlDocumentWithLocation document1 = new XmlDocumentWithLocation(); document1.StringCache = cache; #if FEATURE_XML_LOADPATH document1.Load(path); #else var xmlReadSettings = new XmlReaderSettings { DtdProcessing = DtdProcessing.Ignore }; using (XmlReader xmlReader = XmlReader.Create(path, xmlReadSettings)) { document1.Load(xmlReader); } #endif XmlDocumentWithLocation document2 = new XmlDocumentWithLocation(); document2.StringCache = cache; #if FEATURE_XML_LOADPATH document2.Load(path); #else using (XmlReader xmlReader = XmlReader.Create(path, xmlReadSettings)) { document2.Load(xmlReader); } #endif XmlNodeList nodes1 = document1.GetElementsByTagName("ItemGroup"); XmlNodeList nodes2 = document2.GetElementsByTagName("ItemGroup"); Assert.Equal(1, nodes1.Count); Assert.Equal(1, nodes2.Count); XmlNode node1 = nodes1[0].FirstChild; XmlNode node2 = nodes2[0].FirstChild; Assert.NotNull(node1); Assert.NotNull(node2); Assert.NotSame(node1, node2); Assert.Same(node1.Value, node2.Value); } finally { File.Delete(path); } }
public void TestCache() { string projectBody = ObjectModelHelpers.CleanupFileContents(@" <Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <PropertyGroup> <One>1</One> <Two>2</Two> <Three>$(ThreeIn)</Three> </PropertyGroup> <ItemGroup> <Foo Include=""*""/> <Bar Include=""msbuild.out""> <One>1</One> </Bar> <Baz Include=""$(BazIn)""/> </ItemGroup> <Target Name='Build'> <CallTarget Targets='Foo;Goo'/> </Target> <Target Name='Foo' DependsOnTargets='Foo2'> <FooTarget/> </Target> <Target Name='Goo'> <GooTarget/> </Target> <Target Name='Foo2'> <Foo2Target/> </Target> </Project>"); Dictionary <string, string> globalProperties = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); globalProperties["ThreeIn"] = "3"; globalProperties["BazIn"] = "bazfile"; Project project = new Project( XmlReader.Create(new StringReader(projectBody)), globalProperties, ObjectModelHelpers.MSBuildDefaultToolsVersion, new ProjectCollection()); project.FullPath = "foo"; ProjectInstance instance = project.CreateProjectInstance(); BuildRequestConfiguration configuration = new BuildRequestConfiguration(new BuildRequestData(instance, new string[] { }, null), "2.0"); configuration.ConfigurationId = 1; string originalValue = Environment.GetEnvironmentVariable("MSBUILDCACHE"); try { Environment.SetEnvironmentVariable("MSBUILDCACHE", "1"); Assert.Equal("3", instance.GlobalProperties["ThreeIn"]); Assert.Equal("bazfile", instance.GlobalProperties["BazIn"]); Assert.Equal("1", instance.PropertiesToBuildWith["One"].EvaluatedValue); Assert.Equal("2", instance.PropertiesToBuildWith["Two"].EvaluatedValue); Assert.Equal("3", instance.PropertiesToBuildWith["Three"].EvaluatedValue); int fooCount = instance.ItemsToBuildWith["Foo"].Count; Assert.True(fooCount > 0); Assert.Single(instance.ItemsToBuildWith["Bar"]); Assert.Single(instance.ItemsToBuildWith["Baz"]); Assert.Equal("bazfile", instance.ItemsToBuildWith["Baz"].First().EvaluatedInclude); Lookup lookup = configuration.BaseLookup; Assert.NotNull(lookup); Assert.Equal(fooCount, lookup.GetItems("Foo").Count); // Configuration initialized with a ProjectInstance should not be cacheable by default. Assert.False(configuration.IsCacheable); configuration.IsCacheable = true; configuration.CacheIfPossible(); Assert.Null(instance.GlobalPropertiesDictionary); Assert.Null(instance.ItemsToBuildWith); Assert.Null(instance.PropertiesToBuildWith); configuration.RetrieveFromCache(); Assert.Equal("3", instance.GlobalProperties["ThreeIn"]); Assert.Equal("bazfile", instance.GlobalProperties["BazIn"]); Assert.Equal("1", instance.PropertiesToBuildWith["One"].EvaluatedValue); Assert.Equal("2", instance.PropertiesToBuildWith["Two"].EvaluatedValue); Assert.Equal("3", instance.PropertiesToBuildWith["Three"].EvaluatedValue); Assert.Equal(fooCount, instance.ItemsToBuildWith["Foo"].Count); Assert.Single(instance.ItemsToBuildWith["Bar"]); Assert.Single(instance.ItemsToBuildWith["Baz"]); Assert.Equal("bazfile", instance.ItemsToBuildWith["Baz"].First().EvaluatedInclude); lookup = configuration.BaseLookup; Assert.NotNull(lookup); Assert.Equal(fooCount, lookup.GetItems("Foo").Count); } finally { configuration.ClearCacheFile(); Environment.SetEnvironmentVariable("MSBUILDCACHE", originalValue); } }
public void ContextDisambiguatesAFullyQualifiedGlobPointingInAnotherRelativeGlobsCone(EvaluationContext.SharingPolicy policy, string[][] expectedGlobExpansions) { if (policy == EvaluationContext.SharingPolicy.Shared) { // This test case has a dependency on our glob expansion caching policy. If the evaluation context is reused // between evaluations and files are added to the filesystem between evaluations, the cache may be returning // stale results. Run only the Isolated variant. return; } var project1Directory = _env.DefaultTestDirectory.CreateDirectory("Project1"); var project1GlobDirectory = project1Directory.CreateDirectory("Glob").CreateDirectory("1").Path; var project2Directory = _env.DefaultTestDirectory.CreateDirectory("Project2"); var context = EvaluationContext.Create(policy); var evaluationCount = 0; File.WriteAllText(Path.Combine(project1GlobDirectory, $"{evaluationCount}.cs"), ""); EvaluateProjects( new [] { // first project uses a relative path new ProjectSpecification( Path.Combine(project1Directory.Path, "1"), $@"<Project> <ItemGroup> <i Include=`{Path.Combine("Glob", "**", "*.cs")}` /> </ItemGroup> </Project>"), // second project reaches out into first project's cone via a fully qualified path new ProjectSpecification( Path.Combine(project2Directory.Path, "2"), $@"<Project> <ItemGroup> <i Include=`{Path.Combine(project1Directory.Path, "Glob", "**", "*.cs")}` /> </ItemGroup> </Project>") }, context, project => { var projectName = Path.GetFileNameWithoutExtension(project.FullPath); // globs have the fixed directory part prepended, so add it to the expected results var expectedGlobExpansion = expectedGlobExpansions[evaluationCount] .Select(i => Path.Combine("Glob", "1", i)) .ToArray(); // project 2 has fully qualified directory parts, so make the results for 2 fully qualified if (projectName.Equals("2")) { expectedGlobExpansion = expectedGlobExpansion .Select(i => Path.Combine(project1Directory.Path, i)) .ToArray(); } var actualGlobExpansion = project.GetItems("i"); ObjectModelHelpers.AssertItems(expectedGlobExpansion, actualGlobExpansion); evaluationCount++; File.WriteAllText(Path.Combine(project1GlobDirectory, $"{evaluationCount}.cs"), ""); } ); }
public void TestCache2() { string projectBody = ObjectModelHelpers.CleanupFileContents(@" <Project ToolsVersion='msbuilddefaulttoolsversion' xmlns='msbuildnamespace'> <PropertyGroup> <One>1</One> <Two>2</Two> <Three>$(ThreeIn)</Three> </PropertyGroup> <ItemGroup> <Foo Include=""*""/> <Bar Include=""msbuild.out""> <One>1</One> </Bar> <Baz Include=""$(BazIn)""/> </ItemGroup> <Target Name='Build'> <CallTarget Targets='Foo;Bar'/> </Target> <Target Name='Foo' DependsOnTargets='Foo'> <FooTarget/> </Target> <Target Name='Bar'> <BarTarget/> </Target> <Target Name='Foo'> <FooTarget/> </Target> </Project>"); Dictionary <string, string> globalProperties = new Dictionary <string, string>(StringComparer.OrdinalIgnoreCase); globalProperties["ThreeIn"] = "3"; globalProperties["BazIn"] = "bazfile"; Project project = new Project(XmlReader.Create(new StringReader(projectBody)), globalProperties, ObjectModelHelpers.MSBuildDefaultToolsVersion, new ProjectCollection()); project.FullPath = "foo"; ProjectInstance instance = project.CreateProjectInstance(); BuildRequestConfiguration configuration = new BuildRequestConfiguration(new BuildRequestData(instance, new string[] { }, null), "2.0"); string originalTmp = Environment.GetEnvironmentVariable("TMP"); string originalTemp = Environment.GetEnvironmentVariable("TEMP"); try { string problematicTmpPath = @"C:\Users\}\blabla\temp"; Environment.SetEnvironmentVariable("TMP", problematicTmpPath); Environment.SetEnvironmentVariable("TEMP", problematicTmpPath); FileUtilities.ClearCacheDirectoryPath(); string cacheFilePath = configuration.GetCacheFile(); Assert.StartsWith(problematicTmpPath, cacheFilePath); } finally { Environment.SetEnvironmentVariable("TMP", originalTmp); Environment.SetEnvironmentVariable("TEMP", originalTemp); FileUtilities.ClearCacheDirectoryPath(); } }
public void TreatWarningsAsErrorsWhenSpecified() { MockLogger logger = ObjectModelHelpers.BuildProjectExpectFailure(GetTestProject(warningsAsErrors: ExpectedEventCode)); VerifyBuildErrorEvent(logger); }
public void MultiInputItemsThatCorrelatesWithMultipleTransformOutputItems2() { Console.WriteLine("MultiInputItemsThatCorrelatesWithMultipleTransformOutputItems2"); string currentDirectory = Directory.GetCurrentDirectory(); try { Directory.SetCurrentDirectory(ObjectModelHelpers.TempProjectDir); MockLogger logger = new MockLogger(); Project p = new Project(XmlReader.Create(new StringReader(ObjectModelHelpers.CleanupFileContents(@" <Project InitialTargets='Setup' xmlns='msbuildnamespace'> <ItemGroup> <A Include='A' /> <B Include='B' /> </ItemGroup> <Target Name='Build' DependsOnTargets='GAFT'> <Message Text='Build: @(Outs)' /> <Message Text='Build: GAFTOutsA @(GAFTOutsA)' /> <Message Text='Build: GAFTOutsB @(GAFTOutsB)' /> </Target> <Target Name='Setup'> <WriteLinesToFile File='A' Lines='A' Overwrite='true'/> <WriteLinesToFile File='B.out' Lines='B.out' Overwrite='true'/> <Exec Command='sleep.exe 1' /> <WriteLinesToFile File='B' Lines='B' Overwrite='true'/> <WriteLinesToFile File='A.out' Lines='A.out' Overwrite='true'/> </Target> <Target Name='GAFT' Inputs='@(A);@(B)' Outputs=""@(A->'%(Filename).out');@(B->'%(Filename).out')""> <CreateItem Include=""@(A->'%(Filename).out')""> <Output TaskParameter='Include' ItemName='GAFTOutsA' /> </CreateItem> <Message Text='GAFT A:@(A)' /> <CreateItem Include=""@(B->'%(Filename).out')""> <Output TaskParameter='Include' ItemName='GAFTOutsB' /> </CreateItem> <Message Text='GAFT B:@(B)' /> </Target> </Project> ")))); p.Build(new string[] { "Build" }, new ILogger[] { logger }); // If the log contains B.out twice, then there is leakage from the parent lookup logger.AssertLogDoesntContain("B.out;B.out"); } finally { Directory.SetCurrentDirectory(currentDirectory); } }
public void LocationStringsMedley() { string content = @" <Project ToolsVersion=`msbuilddefaulttoolsversion` xmlns=`http://schemas.microsoft.com/developer/msbuild/2003`> <UsingTask TaskName='t' AssemblyName='a' Condition='true'/> <UsingTask TaskName='t' AssemblyFile='a' Condition='true'/> <ItemDefinitionGroup Condition='true' Label='l'> <m Condition='true'/> </ItemDefinitionGroup> <ItemGroup> <i Include='i' Condition='true' Exclude='r'> <m Condition='true'/> </i> </ItemGroup> <PropertyGroup> <p Condition='true'/> </PropertyGroup> <Target Name='Build' Condition='true' Inputs='i' Outputs='o'> <ItemGroup> <i Include='i' Condition='true' Exclude='r'> <m Condition='true'/> </i> <i Remove='r'/> </ItemGroup> <PropertyGroup> <p Condition='true'/> </PropertyGroup> <Error Text='xyz' ContinueOnError='true' Importance='high'/> </Target> <Import Project='p' Condition='false'/> </Project> "; var project = ObjectModelHelpers.CreateInMemoryProject(content); string locations = project.Xml.Location.LocationString + "\r\n"; foreach (var element in project.Xml.AllChildren) { foreach (var property in element.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) { if (!property.Name.Equals("ImplicitImportLocation") && property.Name.Contains("Location")) { if (property.Name == "ParameterLocations") { var values = new List <KeyValuePair <string, ElementLocation> >(((ICollection <KeyValuePair <string, ElementLocation> >)property.GetValue(element, null))); values.ForEach((value) => locations += value.Key + ":" + value.Value.LocationString + "\r\n"); } else { var value = ((ElementLocation)property.GetValue(element, null)); if (value != null) // null means attribute is not present { locations += value.LocationString + "\r\n"; } } } } } locations = locations.Replace(project.FullPath, "c:\\foo\\bar.csproj"); string expected = @"c:\foo\bar.csproj (2,13) c:\foo\bar.csproj (3,32) c:\foo\bar.csproj (3,45) c:\foo\bar.csproj (3,62) c:\foo\bar.csproj (3,21) c:\foo\bar.csproj (4,32) c:\foo\bar.csproj (4,45) c:\foo\bar.csproj (4,62) c:\foo\bar.csproj (4,21) c:\foo\bar.csproj (5,42) c:\foo\bar.csproj (5,59) c:\foo\bar.csproj (5,21) c:\foo\bar.csproj (6,28) c:\foo\bar.csproj (6,25) c:\foo\bar.csproj (8,21) c:\foo\bar.csproj (9,28) c:\foo\bar.csproj (9,57) c:\foo\bar.csproj (9,40) c:\foo\bar.csproj (9,25) c:\foo\bar.csproj (10,32) c:\foo\bar.csproj (10,29) c:\foo\bar.csproj (13,21) c:\foo\bar.csproj (14,28) c:\foo\bar.csproj (14,25) c:\foo\bar.csproj (16,29) c:\foo\bar.csproj (16,59) c:\foo\bar.csproj (16,70) c:\foo\bar.csproj (16,29) c:\foo\bar.csproj (16,42) c:\foo\bar.csproj (16,21) c:\foo\bar.csproj (17,25) c:\foo\bar.csproj (18,32) c:\foo\bar.csproj (18,61) c:\foo\bar.csproj (18,44) c:\foo\bar.csproj (18,29) c:\foo\bar.csproj (19,36) c:\foo\bar.csproj (19,33) c:\foo\bar.csproj (21,32) c:\foo\bar.csproj (21,29) c:\foo\bar.csproj (23,25) c:\foo\bar.csproj (24,32) c:\foo\bar.csproj (24,29) Text: (26,32) Importance: (26,66) c:\foo\bar.csproj (26,43) c:\foo\bar.csproj (26,25) c:\foo\bar.csproj (28,29) c:\foo\bar.csproj (28,41) c:\foo\bar.csproj (28,21) "; Helpers.VerifyAssertLineByLine(expected, locations); }
public void UpdateMetadataValueAsAttributeWithSpecialCharacters(string projectContents, string updatedProject) { ProjectRootElement projectElement = ProjectRootElement.Create(XmlReader.Create( new StringReader(ObjectModelHelpers.CleanupFileContents(projectContents))), ProjectCollection.GlobalProjectCollection, preserveFormatting: true); ProjectItemGroupElement itemGroup = (ProjectItemGroupElement)projectElement.AllChildren.FirstOrDefault(c => c is ProjectItemGroupElement); var project = new Project(projectElement); var items = Helpers.MakeList(itemGroup.Items); Assert.Equal(1, items.Count); Assert.Equal(1, items[0].Metadata.Count); var metadata = items[0].Metadata.First(); Assert.Equal("m1", metadata.Name); Assert.Equal("v1", metadata.Value); Assert.True(metadata.ExpressedAsAttribute); metadata.Value = @"<&>"""; Assert.True(project.IsDirty); Assert.True(metadata.ExpressedAsAttribute); StringWriter writer = new StringWriter(); project.Save(writer); string expected = @"<?xml version=""1.0"" encoding=""utf-16""?>" + ObjectModelHelpers.CleanupFileContents(updatedProject); string actual = writer.ToString(); VerifyAssertLineByLine(expected, actual); }