summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.BuildTasks
diff options
context:
space:
mode:
authorAndrew Arnott <andrewarnott@gmail.com>2009-11-15 08:45:57 -0800
committerAndrew Arnott <andrewarnott@gmail.com>2009-11-15 08:45:57 -0800
commit9dffdc07431232ffffde0d34f1a1c2bd0aa9ca4e (patch)
tree175856bda741110c31b0908d09a62a8a945f6dba /src/DotNetOpenAuth.BuildTasks
parente778892f1d9bf964c30ba6a10e50aedf12c2e857 (diff)
downloadDotNetOpenAuth-9dffdc07431232ffffde0d34f1a1c2bd0aa9ca4e.zip
DotNetOpenAuth-9dffdc07431232ffffde0d34f1a1c2bd0aa9ca4e.tar.gz
DotNetOpenAuth-9dffdc07431232ffffde0d34f1a1c2bd0aa9ca4e.tar.bz2
.vstemplates are now partially generated to remove the need to keep them in sync with their associated project files.
Diffstat (limited to 'src/DotNetOpenAuth.BuildTasks')
-rw-r--r--src/DotNetOpenAuth.BuildTasks/DiscoverProjectTemplates.cs63
-rw-r--r--src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj33
-rw-r--r--src/DotNetOpenAuth.BuildTasks/MergeProjectWithVSTemplate.cs96
3 files changed, 192 insertions, 0 deletions
diff --git a/src/DotNetOpenAuth.BuildTasks/DiscoverProjectTemplates.cs b/src/DotNetOpenAuth.BuildTasks/DiscoverProjectTemplates.cs
new file mode 100644
index 0000000..0162c16
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/DiscoverProjectTemplates.cs
@@ -0,0 +1,63 @@
+//-----------------------------------------------------------------------
+// <copyright file="DiscoverProjectTemplates.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using System.Collections.Generic;
+ using System.IO;
+ using System.Linq;
+ using System.Text;
+ using System.Xml.Linq;
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
+
+ public class DiscoverProjectTemplates : Task {
+ public ITaskItem[] TopLevelTemplates { get; set; }
+
+ [Output]
+ public ITaskItem[] ProjectTemplates { get; set; }
+
+ [Output]
+ public ITaskItem[] ProjectTemplateContents { get; set; }
+
+ /// <summary>
+ /// Executes this instance.
+ /// </summary>
+ public override bool Execute() {
+ List<ITaskItem> projectTemplates = new List<ITaskItem>();
+ List<ITaskItem> projectTemplateContents = new List<ITaskItem>();
+ foreach (ITaskItem topLevelTemplate in this.TopLevelTemplates) {
+ var vsTemplate = XElement.Load(topLevelTemplate.ItemSpec);
+ var templateContent = vsTemplate.Element(XName.Get("TemplateContent", MergeProjectWithVSTemplate.VSTemplateNamespace));
+ var projectCollection = templateContent.Element(XName.Get("ProjectCollection", MergeProjectWithVSTemplate.VSTemplateNamespace));
+ var links = projectCollection.Elements(XName.Get("ProjectTemplateLink", MergeProjectWithVSTemplate.VSTemplateNamespace));
+ var subTemplates = links.Select(
+ link => (ITaskItem)new TaskItem(
+ link.Value,
+ new Dictionary<string, string> {
+ { "TopLevelTemplate", topLevelTemplate.ItemSpec },
+ { "TopLevelTemplateFileName", Path.GetFileNameWithoutExtension(topLevelTemplate.ItemSpec) },
+ }));
+ projectTemplates.AddRange(subTemplates);
+
+ foreach (var link in links.Select(link => link.Value)) {
+ string[] files = Directory.GetFiles(Path.Combine(Path.GetDirectoryName(topLevelTemplate.ItemSpec), Path.GetDirectoryName(link)), "*.*", SearchOption.AllDirectories);
+ projectTemplateContents.AddRange(files.Select(file => (ITaskItem)new TaskItem(
+ file,
+ new Dictionary<string, string> {
+ { "TopLevelTemplate", topLevelTemplate.ItemSpec },
+ { "TopLevelTemplateFileName", Path.GetFileNameWithoutExtension(topLevelTemplate.ItemSpec) },
+ })));
+ }
+ }
+
+ this.ProjectTemplates = projectTemplates.ToArray();
+ this.ProjectTemplateContents = projectTemplateContents.ToArray();
+
+ return !this.Log.HasLoggedErrors;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj
index 3b22fff..068af4b 100644
--- a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj
+++ b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj
@@ -21,6 +21,33 @@
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
+ <CodeContractsEnableRuntimeChecking>True</CodeContractsEnableRuntimeChecking>
+ <CodeContractsRuntimeOnlyPublicSurface>False</CodeContractsRuntimeOnlyPublicSurface>
+ <CodeContractsRuntimeThrowOnFailure>False</CodeContractsRuntimeThrowOnFailure>
+ <CodeContractsRuntimeCallSiteRequires>False</CodeContractsRuntimeCallSiteRequires>
+ <CodeContractsRunCodeAnalysis>False</CodeContractsRunCodeAnalysis>
+ <CodeContractsNonNullObligations>False</CodeContractsNonNullObligations>
+ <CodeContractsBoundsObligations>False</CodeContractsBoundsObligations>
+ <CodeContractsArithmeticObligations>False</CodeContractsArithmeticObligations>
+ <CodeContractsRedundantAssumptions>False</CodeContractsRedundantAssumptions>
+ <CodeContractsRunInBackground>True</CodeContractsRunInBackground>
+ <CodeContractsShowSquigglies>False</CodeContractsShowSquigglies>
+ <CodeContractsUseBaseLine>False</CodeContractsUseBaseLine>
+ <CodeContractsEmitXMLDocs>False</CodeContractsEmitXMLDocs>
+ <CodeContractsCustomRewriterAssembly>
+ </CodeContractsCustomRewriterAssembly>
+ <CodeContractsCustomRewriterClass>
+ </CodeContractsCustomRewriterClass>
+ <CodeContractsLibPaths>
+ </CodeContractsLibPaths>
+ <CodeContractsPlatformPath>
+ </CodeContractsPlatformPath>
+ <CodeContractsExtraAnalysisOptions>
+ </CodeContractsExtraAnalysisOptions>
+ <CodeContractsBaseLineFile>
+ </CodeContractsBaseLineFile>
+ <CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
+ <CodeContractsReferenceAssembly>%28none%29</CodeContractsReferenceAssembly>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -36,6 +63,7 @@
<Reference Include="Microsoft.Build.Utilities.v3.5">
<RequiredTargetFramework>3.5</RequiredTargetFramework>
</Reference>
+ <Reference Include="Microsoft.Contracts, Version=1.0.0.0, Culture=neutral, PublicKeyToken=736440c9b414ea16, processorArchitecture=MSIL" />
<Reference Include="Microsoft.Web.Administration, Version=7.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>$(SystemRoot)\System32\inetsrv\Microsoft.Web.Administration.dll</HintPath>
@@ -46,6 +74,9 @@
</Reference>
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ChangeProjectReferenceToAssemblyReference.cs" />
@@ -54,8 +85,10 @@
<Compile Include="CopyWithTokenSubstitution.cs" />
<Compile Include="CreateWebApplication.cs" />
<Compile Include="DeleteWebApplication.cs" />
+ <Compile Include="DiscoverProjectTemplates.cs" />
<Compile Include="ECMAScriptPacker.cs" />
<Compile Include="FilterItems.cs" />
+ <Compile Include="MergeProjectWithVSTemplate.cs" />
<Compile Include="GetBuildVersion.cs" />
<Compile Include="CheckAdminRights.cs" />
<Compile Include="JsPack.cs" />
diff --git a/src/DotNetOpenAuth.BuildTasks/MergeProjectWithVSTemplate.cs b/src/DotNetOpenAuth.BuildTasks/MergeProjectWithVSTemplate.cs
new file mode 100644
index 0000000..cbdb849
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/MergeProjectWithVSTemplate.cs
@@ -0,0 +1,96 @@
+//-----------------------------------------------------------------------
+// <copyright file="MergeProjectWithVSTemplate.cs" company="Andrew Arnott">
+// Copyright (c) Andrew Arnott. All rights reserved.
+// </copyright>
+//-----------------------------------------------------------------------
+
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
+ using System.Xml.Linq;
+ using System.IO;
+ using Microsoft.Build.BuildEngine;
+ using System.Diagnostics.Contracts;
+
+ public class MergeProjectWithVSTemplate : Task {
+ internal const string VSTemplateNamespace = "http://schemas.microsoft.com/developer/vstemplate/2005";
+
+ public string[] ProjectItemTypes { get; set; }
+
+ public string[] ReplaceParametersExtensions { get; set; }
+
+ public ITaskItem[] Templates { get; set; }
+
+ /// <summary>
+ /// Executes this instance.
+ /// </summary>
+ public override bool Execute() {
+ foreach(ITaskItem sourceTemplateTaskItem in this.Templates) {
+ var template = XElement.Load(sourceTemplateTaskItem.ItemSpec);
+ var templateContentElement = template.Element(XName.Get("TemplateContent", VSTemplateNamespace));
+ var projectElement = templateContentElement.Element(XName.Get("Project", VSTemplateNamespace));
+ if (projectElement == null) {
+ Log.LogMessage("Skipping merge of \"{0}\" with a project because no project was referenced from the template.", sourceTemplateTaskItem.ItemSpec);
+ continue;
+ }
+
+ var projectPath = Path.Combine(Path.GetDirectoryName(sourceTemplateTaskItem.ItemSpec), projectElement.Attribute("File").Value);
+ Log.LogMessage("Merging project \"{0}\" with \"{1}\".", projectPath, sourceTemplateTaskItem.ItemSpec);
+ var sourceProject = new Microsoft.Build.BuildEngine.Project();
+ sourceProject.Load(projectPath);
+
+ // Collect the project items from the project that are appropriate
+ // to include in the .vstemplate file.
+ var itemsByFolder = from item in sourceProject.EvaluatedItems.Cast<BuildItem>()
+ where this.ProjectItemTypes.Contains(item.Name)
+ orderby item.Include
+ group item by Path.GetDirectoryName(item.Include);
+ foreach (var folder in itemsByFolder) {
+ XElement parentNode = FindOrCreateParent(folder.Key, projectElement);
+
+ foreach (var item in folder) {
+ bool replaceParameters = this.ReplaceParametersExtensions.Contains(Path.GetExtension(item.Include));
+ var projectItem = new XElement(
+ XName.Get("ProjectItem", VSTemplateNamespace),
+ new XAttribute("ReplaceParameters", replaceParameters ? "true" : "false"),
+ Path.GetFileName(item.Include));
+ parentNode.Add(projectItem);
+ }
+ }
+
+ template.Save(sourceTemplateTaskItem.ItemSpec);
+ }
+
+ return !Log.HasLoggedErrors;
+ }
+
+ private static XElement FindOrCreateParent(string directoryName, XElement projectElement) {
+ Contract.Requires<ArgumentNullException>(projectElement != null);
+
+ if (string.IsNullOrEmpty(directoryName)) {
+ return projectElement;
+ }
+
+ string[] segments = directoryName.Split(Path.DirectorySeparatorChar);
+ XElement parent = projectElement;
+ for (int i = 0; i < segments.Length; i++) {
+ var candidateName = XName.Get("Folder", VSTemplateNamespace);
+ var candidate = parent.Elements(XName.Get("Folder", VSTemplateNamespace)).FirstOrDefault(n => n.Attribute("Name").Value == segments[i]);
+ if (candidate == null) {
+ candidate = new XElement(
+ candidateName,
+ new XAttribute("Name", segments[i]));
+ parent.Add(candidate);
+ }
+
+ parent = candidate;
+ }
+
+ return parent;
+ }
+ }
+}