// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
+using System.Linq;
using System.Collections;
using System.Collections.Generic;
using System.Collections.Specialized;
//string recursiveDir;
IDictionary evaluatedMetadata;
IDictionary unevaluatedMetadata;
+ bool isDynamic;
+ bool keepDuplicates = true;
+ string removeMetadata, keepMetadata;
BuildItem ()
{
this.parent_item_group = parentItemGroup;
this.itemElement = itemElement;
-
- if (Include == String.Empty)
- throw new InvalidProjectFileException (String.Format ("The required attribute \"Include\" is missing from element <{0}>.", Name));
+ isDynamic = parentItemGroup.IsDynamic;
+
+ if (IsDynamic) {
+ if (!string.IsNullOrEmpty (Remove)) {
+ if (!string.IsNullOrEmpty (Include) || !string.IsNullOrEmpty (Exclude))
+ throw new InvalidProjectFileException (string.Format ("The attribute \"Remove\" in element <{0}> is unrecognized.", Name));
+ if (itemElement.HasChildNodes)
+ throw new InvalidProjectFileException ("Children are not allowed below an item remove element.");
+ }
+ if (string.IsNullOrEmpty (Include) && !string.IsNullOrEmpty (Exclude))
+ throw new InvalidProjectFileException (string.Format ("The attribute \"Exclude\" in element <{0}> is unrecognized.", Name));
+ } else {
+ if (string.IsNullOrEmpty (Include))
+ throw new InvalidProjectFileException (string.Format ("The required attribute \"Include\" is missing from element <{0}>.", Name));
+ if (!string.IsNullOrEmpty (Remove))
+ throw new InvalidProjectFileException (string.Format ("The attribute \"Remove\" in element <{0}> is unrecognized.", Name));
+ }
+
+ foreach (XmlAttribute attr in itemElement.Attributes) {
+ if (attr.Name == "Include" || attr.Name == "Exclude" || attr.Name == "Condition")
+ continue;
+ if (!IsDynamic)
+ throw new InvalidProjectFileException (string.Format ("The attribute \"{0}\" in element <{1}> is unrecognized.", attr.Name, Name));
+
+ switch (attr.Name) {
+ case "Remove":
+ Remove = attr.Value;
+ break;
+ case "KeepDuplicates":
+ KeepDuplicates = bool.Parse (attr.Value);
+ break;
+ case "RemoveMetadata":
+ removeMetadata = attr.Value;
+ break;
+ case "KeepMetadata":
+ keepMetadata = attr.Value;
+ break;
+ default:
+ throw new InvalidProjectFileException (string.Format ("The attribute \"{0}\" in element <{1}> is unrecognized.", attr.Name, Name));
+ }
+ }
}
-
+
BuildItem (BuildItem parent)
{
isImported = parent.isImported;
this.finalItemSpec = MSBuildUtils.Unescape (Include);
return;
}
-
+
foreach (XmlNode xn in itemElement.ChildNodes) {
XmlElement xe = xn as XmlElement;
if (xe != null && ConditionParser.ParseAndEvaluate (xe.GetAttribute ("Condition"), project))
AddMetadata (xe.Name, xe.InnerText);
}
+ if (IsDynamic) {
+ if (!evaluatedTo)
+ return;
+
+ if (!string.IsNullOrEmpty (Remove)) {
+ RemoveItems (project);
+ return;
+ }
+
+ if (string.IsNullOrEmpty (Include)) {
+ UpdateMetadata (project);
+ return;
+ }
+ }
+
DirectoryScanner directoryScanner;
Expression includeExpr, excludeExpr;
ITaskItem[] includes, excludes;
+ var options = IsDynamic ?
+ ParseOptions.AllowItemsMetadataAndSplit : ParseOptions.AllowItemsNoMetadataAndSplit;
+
includeExpr = new Expression ();
- includeExpr.Parse (Include, ParseOptions.AllowItemsNoMetadataAndSplit);
+ includeExpr.Parse (Include, options);
excludeExpr = new Expression ();
- excludeExpr.Parse (Exclude, ParseOptions.AllowItemsNoMetadataAndSplit);
+ excludeExpr.Parse (Exclude, options);
includes = (ITaskItem[]) includeExpr.ConvertTo (project, typeof (ITaskItem[]),
ExpressionOptions.ExpandItemRefs);
foreach (ITaskItem matchedItem in directoryScanner.MatchedItems)
AddEvaluatedItem (project, evaluatedTo, matchedItem);
}
-
+
+ bool CheckCondition (Project project)
+ {
+ if (parent_item_group != null && !ConditionParser.ParseAndEvaluate (parent_item_group.Condition, project))
+ return false;
+ if (parent_item != null && !parent_item.CheckCondition (project))
+ return false;
+ return ConditionParser.ParseAndEvaluate (Condition, project);
+ }
+
+ void UpdateMetadata (Project project)
+ {
+ BuildItemGroup group;
+ if (!project.TryGetEvaluatedItemByNameBatched (Name, out group))
+ return;
+
+ foreach (BuildItem item in group) {
+ if (!item.CheckCondition (project))
+ continue;
+
+ foreach (string name in evaluatedMetadata.Keys) {
+ item.SetMetadata (name, (string)evaluatedMetadata [name]);
+ }
+
+ AddAndRemoveMetadata (project, item);
+ }
+ }
+
+ void AddAndRemoveMetadata (Project project, BuildItem item)
+ {
+ if (!string.IsNullOrEmpty (removeMetadata)) {
+ var removeExpr = new Expression ();
+ removeExpr.Parse (removeMetadata, ParseOptions.AllowItemsNoMetadataAndSplit);
+
+ var removeSpec = (string[]) removeExpr.ConvertTo (
+ project, typeof (string[]), ExpressionOptions.ExpandItemRefs);
+
+ foreach (var remove in removeSpec) {
+ item.DeleteMetadata (remove);
+ }
+ }
+
+ if (!string.IsNullOrEmpty (keepMetadata)) {
+ var keepExpr = new Expression ();
+ keepExpr.Parse (keepMetadata, ParseOptions.AllowItemsNoMetadataAndSplit);
+
+ var keepSpec = (string[]) keepExpr.ConvertTo (
+ project, typeof (string[]), ExpressionOptions.ExpandItemRefs);
+
+ var metadataNames = new string [item.evaluatedMetadata.Count];
+ item.evaluatedMetadata.Keys.CopyTo (metadataNames, 0);
+
+ foreach (string name in metadataNames) {
+ if (!keepSpec.Contains (name))
+ item.DeleteMetadata (name);
+ }
+ }
+ }
+
+ void RemoveItems (Project project)
+ {
+ BuildItemGroup group;
+ if (!project.TryGetEvaluatedItemByNameBatched (Name, out group))
+ return;
+
+ var removeExpr = new Expression ();
+ removeExpr.Parse (Remove, ParseOptions.AllowItemsNoMetadataAndSplit);
+
+ var removes = (ITaskItem[]) removeExpr.ConvertTo (
+ project, typeof (ITaskItem[]), ExpressionOptions.ExpandItemRefs);
+
+ var directoryScanner = new DirectoryScanner ();
+
+ directoryScanner.Includes = removes;
+
+ if (project.FullFileName != String.Empty)
+ directoryScanner.BaseDirectory = new DirectoryInfo (Path.GetDirectoryName (project.FullFileName));
+ else
+ directoryScanner.BaseDirectory = new DirectoryInfo (Directory.GetCurrentDirectory ());
+
+ directoryScanner.Scan ();
+
+ foreach (ITaskItem matchedItem in directoryScanner.MatchedItems) {
+ group.RemoveItem (matchedItem);
+ }
+ }
+
+ bool ContainsItem (Project project, ITaskItem taskItem)
+ {
+ BuildItemGroup group;
+ if (!project.TryGetEvaluatedItemByNameBatched (Name, out group))
+ return false;
+
+ var item = group.FindItem (taskItem);
+ if (item == null)
+ return false;
+
+ foreach (string metadataName in evaluatedMetadata.Keys) {
+ string metadataValue = (string)evaluatedMetadata [metadataName];
+ if (!metadataValue.Equals (item.evaluatedMetadata [metadataName]))
+ return false;
+ }
+
+ foreach (string metadataName in item.evaluatedMetadata.Keys) {
+ string metadataValue = (string)item.evaluatedMetadata [metadataName];
+ if (!metadataValue.Equals (evaluatedMetadata [metadataName]))
+ return false;
+ }
+
+ return true;
+ }
+
void AddEvaluatedItem (Project project, bool evaluatedTo, ITaskItem taskitem)
{
+ if (IsDynamic && evaluatedTo && !KeepDuplicates && ContainsItem (project, taskitem))
+ return;
+
BuildItemGroup big;
BuildItem bi = new BuildItem (this);
bi.finalItemSpec = taskitem.ItemSpec;
}
big.AddItem (bi);
+
+ if (IsDynamic)
+ AddAndRemoveMetadata (project, bi);
}
// during item's eval phase, any item refs in this item, have either
}
}
+ internal bool IsDynamic {
+ get { return isDynamic; }
+ }
+
+ internal string Remove {
+ get;
+ private set;
+ }
+
+ internal bool KeepDuplicates {
+ get { return keepDuplicates; }
+ private set { keepDuplicates = value; }
+ }
+
public bool IsImported {
get { return isImported; }
}
internal bool FromXml {
get { return itemElement != null; }
}
+
+ internal XmlElement XmlElement {
+ get { return itemElement; }
+ }
internal bool HasParentItem {
get { return parent_item != null; }
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
+using System.Linq;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
GroupingCollection parentCollection;
Project parentProject;
bool read_only;
- bool evaluated;
+ bool evaluated;
+ bool isDynamic;
public BuildItemGroup ()
: this (null, null, null, false)
}
internal BuildItemGroup (XmlElement xmlElement, Project project, ImportedProject importedProject, bool readOnly)
+ : this (xmlElement, project, importedProject, readOnly, false)
+ {
+ }
+
+ internal BuildItemGroup (XmlElement xmlElement, Project project, ImportedProject importedProject, bool readOnly, bool dynamic)
{
this.buildItems = new List <BuildItem> ();
this.importedProject = importedProject;
this.itemGroupElement = xmlElement;
this.parentProject = project;
this.read_only = readOnly;
+ this.isDynamic = dynamic;
if (!FromXml)
return;
RemoveItem (item);
}
+ internal BuildItem FindItem (ITaskItem taskItem)
+ {
+ return buildItems.FirstOrDefault (i => i.FinalItemSpec == taskItem.ItemSpec);
+ }
+
+ internal void RemoveItem (ITaskItem itemToRemove)
+ {
+ if (itemToRemove == null)
+ return;
+
+ var item = FindItem (itemToRemove);
+ if (item == null)
+ return;
+
+ item.Detach ();
+ buildItems.Remove (item);
+ }
+
public BuildItem[] ToArray ()
{
return buildItems.ToArray ();
internal void Evaluate ()
{
- if (evaluated)
+ if (!isDynamic && evaluated)
return;
foreach (BuildItem bi in buildItems) {
if (bi.Condition == String.Empty)
return itemGroupElement;
}
}
+
+ internal bool IsDynamic {
+ get {
+ return isDynamic;
+ }
+ }
}
}
using Microsoft.Build.Utilities;
namespace Microsoft.Build.BuildEngine {
- public class BuildTask {
+ public class BuildTask : IBuildTask {
ITaskHost hostObject;
Target parentTarget;
continue;
tempNames.Add (xmlAttribute.Name);
}
-
+
return tempNames.ToArray ();
}
else
taskElement.SetAttribute (parameterName, parameterValue);
}
-
+
void LogTaskStarted ()
{
TaskStartedEventArgs tsea = new TaskStartedEventArgs ("Task started.", null,
get { return taskElement; }
set { taskElement = value; }
}
-
+
[MonoTODO]
public Type Type {
get { return parentTarget.Project.TaskDatabase.GetTypeFromClassName (Name); }
}
+
+ public IEnumerable<string> GetAttributes ()
+ {
+ foreach (XmlAttribute attrib in TaskElement.Attributes)
+ yield return attrib.Value;
+ foreach (XmlNode xn in TaskElement.ChildNodes) {
+ XmlElement xe = xn as XmlElement;
+ if (xe == null)
+ continue;
+
+ //FIXME: error on any other child
+ if (String.Compare (xe.LocalName, "Output", StringComparison.Ordinal) == 0) {
+ foreach (XmlAttribute attrib in xe.Attributes)
+ yield return attrib.Value;
+ }
+ }
+ }
+
}
}
--- /dev/null
+//
+// BuildTaskItemGroup.cs
+//
+// Author:
+// Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Collections.Generic;
+using System.Xml;
+
+namespace Microsoft.Build.BuildEngine {
+
+ internal class BuildTaskItemGroup : BuildItemGroup, IBuildTask {
+
+ public bool ContinueOnError {
+ get; set;
+ }
+
+ internal BuildTaskItemGroup (XmlElement element, Target target)
+ : base (element, target.Project, null, false, true)
+ {
+ }
+
+ public bool Execute ()
+ {
+ Evaluate ();
+ return true;
+ }
+
+ public IEnumerable<string> GetAttributes ()
+ {
+ foreach (XmlAttribute attrib in XmlElement.Attributes)
+ yield return attrib.Value;
+
+ foreach (BuildItem item in this) {
+ foreach (XmlAttribute attrib in item.XmlElement.Attributes)
+ yield return attrib.Value;
+ }
+ }
+
+ }
+}
+
--- /dev/null
+//
+// BuildTaskPropertyGroup.cs
+//
+// Author:
+// Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+
+using System;
+using System.Collections.Generic;
+using System.Xml;
+
+namespace Microsoft.Build.BuildEngine {
+
+ internal class BuildTaskPropertyGroup : BuildPropertyGroup, IBuildTask {
+
+ public bool ContinueOnError {
+ get; set;
+ }
+
+ internal BuildTaskPropertyGroup (XmlElement element, Target target)
+ : base (element, target.Project, null, false)
+ {
+ }
+
+ public bool Execute ()
+ {
+ Evaluate ();
+ return true;
+ }
+
+ public IEnumerable<string> GetAttributes ()
+ {
+ foreach (XmlAttribute attrib in XmlElement.Attributes)
+ yield return attrib.Value;
+ }
+
+ }
+}
+
{
return ParseBooleanAnd ();
}
+
+ public static string And (string a, string b)
+ {
+ return a + " and " + b;
+ }
ConditionExpression ParseBooleanAnd ()
{
--- /dev/null
+//
+// IBuildTask.cs
+//
+// Author:
+// Martin Baulig <martin.baulig@xamarin.com>
+//
+// Copyright (c) 2013 Xamarin Inc. (http://www.xamarin.com)
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+
+using System;
+using System.Collections.Generic;
+
+namespace Microsoft.Build.BuildEngine {
+ internal interface IBuildTask {
+ bool ContinueOnError {
+ get; set;
+ }
+
+ string Condition {
+ get; set;
+ }
+
+ bool Execute ();
+
+ IEnumerable<string> GetAttributes ();
+ }
+}
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
using System;
+using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Xml;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
+using Mono.XBuild.Utilities;
namespace Microsoft.Build.BuildEngine {
public class Target : IEnumerable {
Project project;
XmlElement targetElement;
List <XmlElement> onErrorElements;
- List <BuildTask> buildTasks;
+ List <IBuildTask> buildTasks;
internal Target (XmlElement targetElement, Project project, ImportedProject importedProject)
{
this.onErrorElements = new List <XmlElement> ();
this.buildState = BuildState.NotStarted;
- this.buildTasks = new List <BuildTask> ();
+ this.buildTasks = new List <IBuildTask> ();
this.batchingImpl = new TargetBatchingImpl (project, this.targetElement);
bool onErrorFound = false;
"The element <OnError> must be last under element <Target>. Found element <Error> instead.");
#if NET_3_5
else if (xe.Name == "ItemGroup") {
- //don't blow up for ItemGroups inside Targets in >= 3.5
- // TODO: evaluate them (see https://bugzilla.xamarin.com/show_bug.cgi?id=1862 and test in TargetTest.cs )
+ buildTasks.Add (new BuildTaskItemGroup (xe, this));
+ continue;
+ } else if (xe.Name == "PropertyGroup") {
+ buildTasks.Add (new BuildTaskPropertyGroup (xe, this));
continue;
}
#endif
internal List<string> AfterThisTargets { get; set; }
#endif
- internal List<BuildTask> BuildTasks {
+ internal List<IBuildTask> BuildTasks {
get { return buildTasks; }
}
for (int i = 0; i < target.BuildTasks.Count; i ++) {
//FIXME: parsing attributes repeatedly
- BuildTask bt = target.BuildTasks [i];
+ IBuildTask bt = target.BuildTasks [i];
TaskBatchingImpl batchingImpl = new TaskBatchingImpl (project);
bool task_result = batchingImpl.Build (bt, out executeOnErrors);
{
}
- public bool Build (BuildTask buildTask, out bool executeOnErrors)
+ public bool Build (IBuildTask buildTask, out bool executeOnErrors)
{
executeOnErrors = false;
try {
}
}
- bool Run (BuildTask buildTask, out bool executeOnErrors)
+ bool Run (IBuildTask buildTask, out bool executeOnErrors)
{
executeOnErrors = false;
// Parse task attributes to get list of referenced metadata and items
// to determine batching
//
- void ParseTaskAttributes (BuildTask buildTask)
+ void ParseTaskAttributes (IBuildTask buildTask)
{
- foreach (XmlAttribute attrib in buildTask.TaskElement.Attributes)
- ParseAttribute (attrib.Value);
-
- foreach (XmlNode xn in buildTask.TaskElement.ChildNodes) {
- XmlElement xe = xn as XmlElement;
- if (xe == null)
- continue;
-
- //FIXME: error on any other child
- if (String.Compare (xe.LocalName, "Output", StringComparison.Ordinal) == 0) {
- foreach (XmlAttribute attrib in xe.Attributes)
- ParseAttribute (attrib.Value);
- }
+ foreach (var attr in buildTask.GetAttributes ()) {
+ ParseAttribute (attr);
}
}
}
Microsoft.Build.BuildEngine/BuildPropertyGroup.cs
Microsoft.Build.BuildEngine/BuildSettings.cs
Microsoft.Build.BuildEngine/BuildTask.cs
+Microsoft.Build.BuildEngine/BuildTaskItemGroup.cs
+Microsoft.Build.BuildEngine/BuildTaskPropertyGroup.cs
Microsoft.Build.BuildEngine/BuildWhen.cs
Microsoft.Build.BuildEngine/ChangeType.cs
Microsoft.Build.BuildEngine/ColorResetter.cs
Microsoft.Build.BuildEngine/ImportedProject.cs
Microsoft.Build.BuildEngine/InternalLoggerException.cs
Microsoft.Build.BuildEngine/InvalidProjectFileException.cs
+Microsoft.Build.BuildEngine/IBuildTask.cs
Microsoft.Build.BuildEngine/IReference.cs
Microsoft.Build.BuildEngine/ItemReference.cs
Microsoft.Build.BuildEngine/LogExtensions.cs
// Parameter "itemInclude" cannot have zero length.
[Test]
+ [Category ("NotDotNet")]
[ExpectedException (typeof (ArgumentException))]
public void TestCtor6 ()
{
}
[Test]
+ [Category ("NotDotNet")]
public void TestGetEnumerator1 ()
{
BuildPropertyGroup bpg = new BuildPropertyGroup ();
}
[Test]
+ [Category ("NotDotNet")]
public void TestValueXml ()
{
BuildPropertyGroup [] bpgs = new BuildPropertyGroup [1];
[TestFixture]
public class ConsoleLoggerTest {
[Test]
+ [Category ("NotDotNet")]
public void TestAssignment ()
{
ConsoleLogger cl = new ConsoleLogger ();
}
[Test]
+ [Category ("NotDotNet")]
[ExpectedException (typeof (ArgumentException))]
public void TestBuildProject1 ()
{
}
[Test]
+ [Category ("NotDotNet")]
[ExpectedException (typeof (ArgumentException))]
public void TestBuildProjectNull1 ()
{
}
[Test]
+ [Category ("NotDotNet")]
[ExpectedException (typeof (ArgumentException))]
public void TestBuildProjectNull2 ()
{
}
[Test]
+ [Category ("NotDotNet")]
public void TestBatchedMetadataRef1 ()
{
//test for multiple items with same metadata also
}
[Test]
+ [Category ("NotDotNet")]
public void TestBatchedMetadataRef2 ()
{
string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
}
[Test]
+ [Category ("NotDotNet")]
public void TestBatchedMetadataRef3 ()
{
string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
}
[Test]
+ [Category ("NotDotNet")]
public void TestBatchedMetadataRef4 ()
{
string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
}
[Test]
+ [Category ("NotDotNet")]
public void TestBatchedMetadataRef5 ()
{
string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
}
[Test]
+ [Category ("NotDotNet")]
public void TestBatchedMetadataRefInOutput () {
string projectString = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
<UsingTask TaskName=""BatchingTestTask"" AssemblyFile=""Test/resources/TestTasks.dll"" />
}
[Test]
+ [Category ("NotDotNet")]
public void TestMSBuildThisProperties ()
{
Engine engine = new Engine (Consts.BinPath);
}
[Test]
+ [Category ("NotDotNet")]
public void TestRequiredTask_TaskItemArray1 ()
{
Project p = CheckProjectForRequiredTests ("RequiredTestTask_TaskItems", "@(NonExistant)",
}
[Test]
+ [Category ("NotDotNet")]
public void TestRequiredTask_TaskItemArray2 ()
{
Project p = CheckProjectForRequiredTests ("RequiredTestTask_TaskItems", "$(NonExistant)",
}
[Test]
+ [Category ("NotDotNet")]
public void TestRequiredTask_TaskItemArray3 ()
{
Project p = CheckProjectForRequiredTests ("RequiredTestTask_IntArray", "$(NonExistant)",
}
[Test]
+ [Category ("NotDotNet")]
public void TestRequiredTask_TaskItemArray4 () {
Project p = CheckProjectForRequiredTests ("RequiredTestTask_IntArray", "%(NonExistant.Md)",
true, "Build failed", "count: 0");
}
[Test]
+ [Category ("NotDotNet")]
public void TestRequiredTask_TaskItemArray5 () {
// with extra space in prop value
Project p = CheckProjectForRequiredTests ("RequiredTestTask_IntArray", " %(NonExistant.Md)",
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
using System;
using System.Collections;
using Microsoft.Build.BuildEngine;
using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
+using MonoTests.Microsoft.Build.Tasks;
using NUnit.Framework;
using System.IO;
+using System.Xml;
namespace MonoTests.Microsoft.Build.BuildEngine {
[TestFixture]
}
#if NET_3_5
- [Test]
- public void BuildProjectWithItemGroupInsideTarget()
+ bool Build (string projectXml, ILogger logger)
{
- ItemGroupInsideATarget ();
+ if (Environment.OSVersion.Platform == PlatformID.Win32NT) {
+ var reader = new StringReader (projectXml);
+ var xml = XmlReader.Create (reader);
+ return BuildOnWindows (xml, logger);
+ } else {
+ return BuildOnLinux (projectXml, logger);
+ }
}
- private MonoTests.Microsoft.Build.Tasks.TestMessageLogger ItemGroupInsideATarget() {
- var engine = new Engine(Consts.BinPath);
- var project = engine.CreateNewProject();
- var projectXml = GetProjectXmlWithItemGroupInsideATarget ();
- project.LoadXml(projectXml);
+ bool BuildOnWindows (XmlReader reader, ILogger logger)
+ {
+ var type = Type.GetType ("Microsoft.Build.Evaluation.ProjectCollection, Microsoft.Build, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
+
+ var prop = type.GetProperty ("GlobalProjectCollection");
+ var coll = prop.GetValue (null);
+
+ var loadProject = coll.GetType ().GetMethod (
+ "LoadProject", new Type[] { typeof (XmlReader), typeof (string) });
+ var proj = loadProject.Invoke (coll, new object[] { reader, "4.0" });
+
+ var build = proj.GetType ().GetMethod ("Build", new Type[] { typeof (string), typeof (ILogger[]) });
+ var ret = (bool)build.Invoke (proj, new object[] { "Main", new ILogger[] { logger }});
+ return ret;
+ }
- MonoTests.Microsoft.Build.Tasks.TestMessageLogger logger =
- new MonoTests.Microsoft.Build.Tasks.TestMessageLogger ();
+ bool BuildOnLinux (string projectXml, ILogger logger)
+ {
+ var engine = new Engine (Consts.BinPath);
+ var project = engine.CreateNewProject ();
+ project.LoadXml (projectXml);
+
engine.RegisterLogger (logger);
+
+ return project.Build ("Main");
+ }
- bool result = project.Build("Main");
- if (!result)
- {
+ TestMessageLogger CreateLogger (string projectXml)
+ {
+ var logger = new TestMessageLogger ();
+ var result = Build (projectXml, logger);
+
+ if (!result) {
logger.DumpMessages ();
- Assert.Fail("Build failed");
+ Assert.Fail ("Build failed");
}
return logger;
}
- private string GetProjectXmlWithItemGroupInsideATarget ()
+ void ItemGroupInsideTarget (string xml, params string[] messages)
+ {
+ var logger = CreateLogger (xml);
+
+ try
+ {
+ Assert.AreEqual(messages.Length, logger.NormalMessageCount, "Expected number of messages");
+ for (int i = 0; i < messages.Length; i++)
+ logger.CheckLoggedMessageHead (messages [i], i.ToString ());
+ Assert.AreEqual(0, logger.NormalMessageCount, "Extra messages found");
+
+ Assert.AreEqual(1, logger.TargetStarted, "TargetStarted count");
+ Assert.AreEqual(1, logger.TargetFinished, "TargetFinished count");
+ Assert.AreEqual(messages.Length, logger.TaskStarted, "TaskStarted count");
+ Assert.AreEqual(messages.Length, logger.TaskFinished, "TaskFinished count");
+ }
+ catch (AssertionException)
+ {
+ logger.DumpMessages();
+ throw;
+ }
+ }
+
+ [Test]
+ public void BuildProjectWithItemGroupInsideTarget ()
{
- return
+ ItemGroupInsideTarget (
@"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
<ItemGroup>
- <fruit Include=""apple""/>
+ <fruit Include=""apple""/>
<fruit Include=""apricot""/>
</ItemGroup>
</ItemGroup>
<Message Text=""%(fruit.Identity)""/>
</Target>
- </Project>";
+ </Project>", "apple", "apricot", "raspberry");
}
+
+ [Test]
+ public void BuildProjectWithItemGroupInsideTarget2 ()
+ {
+ ItemGroupInsideTarget (
+ @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"" ToolsVersion=""4.0"">
+ <ItemGroup>
+ <A Include='1'>
+ <Sub>Foo</Sub>
+ </A>
+ </ItemGroup>
+ <PropertyGroup>
+ <Foo>Bar</Foo>
+ </PropertyGroup>
+ <Target Name='Main'>
+ <ItemGroup>
+ <A Include='2'>
+ <Sub>$(Foo);Hello</Sub>
+ </A>
+ </ItemGroup>
+
+ <Message Text='@(A)' />
+ <Message Text='%(A.Sub)' />
+ </Target>
+ </Project>", "1;2", "Foo", "Bar;Hello");
+ }
+
[Test]
- [Category ("NotWorking")] //https://bugzilla.xamarin.com/show_bug.cgi?id=1862
- public void BuildProjectOutputWithItemGroupInsideTarget()
+ public void BuildProjectWithPropertyGroupInsideTarget ()
{
- var logger = ItemGroupInsideATarget ();
+ ItemGroupInsideTarget (
+ @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <PropertyGroup>
+ <A>Foo</A>
+ <B>Bar</B>
+ </PropertyGroup>
- try
- {
- Assert.AreEqual(3, logger.NormalMessageCount, "Expected number of messages");
- logger.CheckLoggedMessageHead("apple", "A1");
- logger.CheckLoggedMessageHead("apricot", "A2");
- logger.CheckLoggedMessageHead("raspberry", "A3");
- Assert.AreEqual(0, logger.NormalMessageCount, "Extra messages found");
+ <Target Name=""Main"">
+ <Message Text='$(A)' />
+ <PropertyGroup>
+ <A>$(B)</A>
+ </PropertyGroup>
+ <Message Text='$(A)' />
+ </Target>
+ </Project>", "Foo", "Bar");
+ }
- Assert.AreEqual(1, logger.TargetStarted, "TargetStarted count");
- Assert.AreEqual(1, logger.TargetFinished, "TargetFinished count");
- Assert.AreEqual(3, logger.TaskStarted, "TaskStarted count");
- Assert.AreEqual(3, logger.TaskFinished, "TaskFinished count");
+ [Test]
+ public void BuildProjectWithPropertyGroupInsideTarget2 ()
+ {
+ ItemGroupInsideTarget (
+ @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <PropertyGroup>
+ <A>Foo</A>
+ <B>Bar</B>
+ </PropertyGroup>
- }
- catch (AssertionException)
- {
- logger.DumpMessages();
- throw;
- }
+ <Target Name=""Main"">
+ <Message Text='$(A)' />
+ <PropertyGroup Condition='true'>
+ <B Condition='false'>False</B>
+ </PropertyGroup>
+ <PropertyGroup Condition='true'>
+ <A>$(B)</A>
+ </PropertyGroup>
+ <Message Text='$(A)' />
+ <Message Text='$(B)' />
+ <PropertyGroup>
+ <A Condition='$(A) == $(B)'>Equal</A>
+ </PropertyGroup>
+ <Message Text='$(A)' />
+ </Target>
+ </Project>", "Foo", "Bar", "Bar", "Equal");
}
+
+ [Test]
+ public void ItemGroupInsideTarget_ModifyMetadata ()
+ {
+ ItemGroupInsideTarget (
+ @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <ItemGroup>
+ <Server Include='Server1'>
+ <AdminContact>Mono</AdminContact>
+ </Server>
+ <Server Include='Server2'>
+ <AdminContact>Mono</AdminContact>
+ </Server>
+ <Server Include='Server3'>
+ <AdminContact>Root</AdminContact>
+ </Server>
+ </ItemGroup>
+
+ <Target Name='Main'>
+ <ItemGroup>
+ <Server Condition=""'%(Server.AdminContact)' == 'Mono'"">
+ <AdminContact>Monkey</AdminContact>
+ </Server>
+ </ItemGroup>
+
+ <Message Text='%(Server.Identity) : %(Server.AdminContact)' />
+ </Target>
+ </Project>", "Server1 : Monkey", "Server2 : Monkey", "Server3 : Root");
+ }
+
+ [Test]
+ public void ItemGroupInsideTarget_RemoveItem ()
+ {
+ ItemGroupInsideTarget (
+ @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <ItemGroup>
+ <Foo Include='A;B;C;D' />
+ </ItemGroup>
+
+ <Target Name='Main'>
+ <ItemGroup>
+ <Foo Remove='B' />
+ </ItemGroup>
+
+ <Message Text='@(Foo)' />
+ </Target>
+ </Project>", "A;C;D");
+ }
+
+ [Test]
+ public void ItemGroupInsideTarget_DontKeepDuplicates ()
+ {
+ ItemGroupInsideTarget (
+ @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <ItemGroup>
+ <Foo Include='A;B' />
+ <Foo Include='C'>
+ <Hello>World</Hello>
+ </Foo>
+ <Foo Include='D'>
+ <Hello>Boston</Hello>
+ </Foo>
+ </ItemGroup>
+
+ <Target Name='Main'>
+ <ItemGroup>
+ <Foo Include='B;C;D' KeepDuplicates='false'>
+ <Hello>Boston</Hello>
+ </Foo>
+ </ItemGroup>
+
+ <Message Text='@(Foo)' />
+ </Target>
+ </Project>", "A;B;C;D;B;C");
+ }
+
+ [Test]
+ public void ItemGroupInsideTarget_RemoveMetadata ()
+ {
+ ItemGroupInsideTarget (
+ @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <ItemGroup>
+ <Foo Include='A' />
+ <Foo Include='B'>
+ <Hello>World</Hello>
+ </Foo>
+ <Foo Include='C'>
+ <Hello>Boston</Hello>
+ </Foo>
+ <Foo Include='D'>
+ <Test>Monkey</Test>
+ </Foo>
+ </ItemGroup>
+ <PropertyGroup>
+ <Foo>Hello</Foo>
+ </PropertyGroup>
+
+ <Target Name='Main'>
+ <ItemGroup>
+ <Bar Include='@(Foo)' RemoveMetadata='$(Foo)' />
+ <Bar Include='E'>
+ <Hello>Monkey</Hello>
+ </Bar>
+ </ItemGroup>
+
+ <Message Text='%(Bar.Identity)' Condition=""'%(Bar.Hello)' != ''""/>
+ </Target>
+ </Project>", "E");
+ }
+
+ [Test]
+ public void ItemGroupInsideTarget_RemoveMetadata2 ()
+ {
+ ItemGroupInsideTarget (
+ @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <ItemGroup>
+ <Foo Include='A' />
+ <Foo Include='B'>
+ <Hello>World</Hello>
+ </Foo>
+ <Foo Include='C'>
+ <Hello>Boston</Hello>
+ </Foo>
+ <Foo Include='D'>
+ <Test>Monkey</Test>
+ </Foo>
+ </ItemGroup>
+ <PropertyGroup>
+ <Foo>Hello</Foo>
+ </PropertyGroup>
+
+ <Target Name='Main'>
+ <ItemGroup>
+ <Foo RemoveMetadata='$(Foo)' />
+ <Foo Include='E'>
+ <Hello>Monkey</Hello>
+ </Foo>
+ </ItemGroup>
+
+ <Message Text='%(Foo.Identity)' Condition=""'%(Foo.Hello)' != ''""/>
+ </Target>
+ </Project>", "E");
+ }
+
+ [Test]
+ public void ItemGroupInsideTarget_KeepMetadata ()
+ {
+ ItemGroupInsideTarget (
+ @"<Project ToolsVersion=""4.0"" xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
+ <ItemGroup>
+ <Foo Include='A' />
+ <Foo Include='B'>
+ <Hello>World</Hello>
+ </Foo>
+ <Foo Include='C'>
+ <Hello>Boston</Hello>
+ </Foo>
+ <Foo Include='D'>
+ <Test>Monkey</Test>
+ </Foo>
+ </ItemGroup>
+
+ <Target Name='Main'>
+ <ItemGroup>
+ <Foo KeepMetadata='Test' />
+ <Foo Include='E'>
+ <Hello>Monkey</Hello>
+ </Foo>
+ </ItemGroup>
+
+ <Message Text='%(Foo.Identity)' Condition=""'%(Foo.Test)' != ''""/>
+ </Target>
+ </Project>", "D");
+ }
+
#endif
[Test]
#if NET_4_0
[Test]
+ [Category ("NotDotNet")]
public void TestBeforeAndAfterTargets ()
{
Engine engine;
}
[Test]
+ [Category ("NotDotNet")]
public void TestDuplicate1 ()
{
string documentString = @"
}
[Test]
+ [Category ("NotDotNet")]
public void TestLazyLoad2 ()
{
string documentString = @"
}
[Test]
+ [Category ("NotDotNet")]
public void TestCondition10 ()
{
Engine engine = new Engine (Consts.BinPath);
}
[Test]
+ [Category ("NotDotNet")]
public void TestImportOrder1 ()
{
Engine engine = new Engine (Consts.BinPath);
}
[Test]
+ [Category ("NotDotNet")]
[ExpectedException (typeof (InvalidProjectFileException))]
public void TestImportOrder2 ()
{
}
[Test]
+ [Category ("NotDotNet")]
public void TestImportOrder5 ()
{
Engine engine = new Engine (Consts.BinPath);
}
[Test]
+ [Category ("NotDotNet")]
public void TestImportOrder6 ()
{
Engine engine = new Engine (Consts.BinPath);
}
[Test]
+ [Category ("NotDotNet")]
public void TestImportOrder7 ()
{
Engine engine = new Engine (Consts.BinPath);
}
[Test]
+ [Category ("NotDotNet")]
public void TestEmptyItemsWithBatching ()
{
string project_xml = @"<Project xmlns=""http://schemas.microsoft.com/developer/msbuild/2003"">
}
[Test]
+ [Category ("NotDotNet")]
public void TestItemsInTarget1 ()
{
Engine engine = new Engine (Consts.BinPath);
}
[Test]
+ [Category ("NotDotNet")]
public void TestItemsInTarget3 ()
{
Engine engine = new Engine (Consts.BinPath);
}
[Test]
+ [Category ("NotDotNet")]
//Test with ITaskItem[]
public void TestItemsInTarget3a ()
{
}
[Test]
+ [Category ("NotDotNet")]
//Test with string[]
public void TestItemsInTarget3b ()
{
}
[Test]
+ [Category ("NotDotNet")]
//Test with string
public void TestItemsInTarget3c ()
{
}
[Test]
+ [Category ("NotDotNet")]
public void TestSingleTaskItem1 ()
{
Project proj = BuildProjectForSingleTaskItem ("$(D)$(C)");
}
[Test]
+ [Category ("NotDotNet")]
public void TestSingleTaskItem2 ()
{
Project proj = BuildProjectForSingleTaskItem ("@(Item1)");
}
[Test]
+ [Category ("NotDotNet")]
public void TestSingleTaskItem3 ()
{
Project proj = BuildProjectForSingleTaskItem ("$(A).foo");
}
[Test]
+ [Category ("NotDotNet")]
public void TestSingleTaskItem4 ()
{
Project proj = BuildProjectForSingleTaskItem ("$(C)");
}
[Test]
+ [Category ("NotDotNet")]
public void TestProperties2 ()
{
Engine engine = new Engine (Consts.BinPath);