summaryrefslogtreecommitdiffstats
path: root/src/DotNetOpenAuth.BuildTasks
diff options
context:
space:
mode:
Diffstat (limited to 'src/DotNetOpenAuth.BuildTasks')
-rw-r--r--src/DotNetOpenAuth.BuildTasks/CopyWithTokenSubstitution.cs61
-rw-r--r--src/DotNetOpenAuth.BuildTasks/DiscoverProjectTemplates.cs1
-rw-r--r--src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj39
-rw-r--r--src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.sln8
-rw-r--r--src/DotNetOpenAuth.BuildTasks/DowngradeProjects.cs110
-rw-r--r--src/DotNetOpenAuth.BuildTasks/FixupShippingToolSamples.cs12
-rw-r--r--src/DotNetOpenAuth.BuildTasks/HardLinkCopy.cs61
-rw-r--r--src/DotNetOpenAuth.BuildTasks/NativeMethods.cs18
8 files changed, 280 insertions, 30 deletions
diff --git a/src/DotNetOpenAuth.BuildTasks/CopyWithTokenSubstitution.cs b/src/DotNetOpenAuth.BuildTasks/CopyWithTokenSubstitution.cs
index e17d8f2..38f3b50 100644
--- a/src/DotNetOpenAuth.BuildTasks/CopyWithTokenSubstitution.cs
+++ b/src/DotNetOpenAuth.BuildTasks/CopyWithTokenSubstitution.cs
@@ -58,36 +58,47 @@ namespace DotNetOpenAuth.BuildTasks {
string destPath = this.DestinationFiles[i].ItemSpec;
bool skipUnchangedFiles = bool.Parse(this.SourceFiles[i].GetMetadata("SkipUnchangedFiles"));
- // We deliberably consider newer destination files to be up-to-date rather than
- // requiring equality because this task modifies the destination file while copying.
- if (skipUnchangedFiles && File.GetLastWriteTimeUtc(sourcePath) < File.GetLastWriteTimeUtc(destPath)) {
- Log.LogMessage(MessageImportance.Low, "Skipping \"{0}\" -> \"{1}\" because the destination is up to date.", sourcePath, destPath);
- continue;
- }
+ if (string.IsNullOrEmpty(this.SourceFiles[i].GetMetadata("BeforeTokens"))) {
+ // this is just a standard copy without token substitution
+ if (skipUnchangedFiles && File.GetLastWriteTimeUtc(sourcePath) == File.GetLastWriteTimeUtc(destPath)) {
+ Log.LogMessage(MessageImportance.Low, "Skipping \"{0}\" -> \"{1}\" because the destination is up to date.", sourcePath, destPath);
+ continue;
+ }
- Log.LogMessage(MessageImportance.Normal, "Transforming \"{0}\" -> \"{1}\"", sourcePath, destPath);
+ Log.LogMessage(MessageImportance.Normal, "Copying \"{0}\" -> \"{1}\"", sourcePath, destPath);
+ File.Copy(sourcePath, destPath, true);
+ } else {
+ // We deliberably consider newer destination files to be up-to-date rather than
+ // requiring equality because this task modifies the destination file while copying.
+ if (skipUnchangedFiles && File.GetLastWriteTimeUtc(sourcePath) < File.GetLastWriteTimeUtc(destPath)) {
+ Log.LogMessage(MessageImportance.Low, "Skipping \"{0}\" -> \"{1}\" because the destination is up to date.", sourcePath, destPath);
+ continue;
+ }
- string[] beforeTokens = this.SourceFiles[i].GetMetadata("BeforeTokens").Split(';');
- string[] afterTokens = this.SourceFiles[i].GetMetadata("AfterTokens").Split(';');
- if (beforeTokens.Length != afterTokens.Length) {
- Log.LogError("Unequal number of before and after tokens. Before: \"{0}\". After \"{1}\".", beforeTokens, afterTokens);
- return false;
- }
+ Log.LogMessage(MessageImportance.Normal, "Transforming \"{0}\" -> \"{1}\"", sourcePath, destPath);
- using (StreamReader sr = File.OpenText(sourcePath)) {
- if (!Directory.Exists(Path.GetDirectoryName(destPath))) {
- Directory.CreateDirectory(Path.GetDirectoryName(destPath));
+ string[] beforeTokens = this.SourceFiles[i].GetMetadata("BeforeTokens").Split(';');
+ string[] afterTokens = this.SourceFiles[i].GetMetadata("AfterTokens").Split(';');
+ if (beforeTokens.Length != afterTokens.Length) {
+ Log.LogError("Unequal number of before and after tokens. Before: \"{0}\". After \"{1}\".", beforeTokens, afterTokens);
+ return false;
}
- using (StreamWriter sw = File.CreateText(destPath)) {
- StringBuilder line = new StringBuilder();
- while (!sr.EndOfStream) {
- line.Length = 0;
- line.Append(sr.ReadLine());
- for (int j = 0; j < beforeTokens.Length; j++) {
- line.Replace(beforeTokens[j], afterTokens[j]);
- }
- sw.WriteLine(line);
+ using (StreamReader sr = File.OpenText(sourcePath)) {
+ if (!Directory.Exists(Path.GetDirectoryName(destPath))) {
+ Directory.CreateDirectory(Path.GetDirectoryName(destPath));
+ }
+ using (StreamWriter sw = File.CreateText(destPath)) {
+ StringBuilder line = new StringBuilder();
+ while (!sr.EndOfStream) {
+ line.Length = 0;
+ line.Append(sr.ReadLine());
+ for (int j = 0; j < beforeTokens.Length; j++) {
+ line.Replace(beforeTokens[j], afterTokens[j]);
+ }
+
+ sw.WriteLine(line);
+ }
}
}
}
diff --git a/src/DotNetOpenAuth.BuildTasks/DiscoverProjectTemplates.cs b/src/DotNetOpenAuth.BuildTasks/DiscoverProjectTemplates.cs
index 0162c16..f49c9b1 100644
--- a/src/DotNetOpenAuth.BuildTasks/DiscoverProjectTemplates.cs
+++ b/src/DotNetOpenAuth.BuildTasks/DiscoverProjectTemplates.cs
@@ -15,6 +15,7 @@ namespace DotNetOpenAuth.BuildTasks {
using Microsoft.Build.Utilities;
public class DiscoverProjectTemplates : Task {
+ [Required]
public ITaskItem[] TopLevelTemplates { get; set; }
[Output]
diff --git a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj
index b8cff51..3f76f78 100644
--- a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj
+++ b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.csproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -12,6 +12,21 @@
<AssemblyName>DotNetOpenAuth.BuildTasks</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
+ <PublishUrl>publish\</PublishUrl>
+ <Install>true</Install>
+ <InstallFrom>Disk</InstallFrom>
+ <UpdateEnabled>false</UpdateEnabled>
+ <UpdateMode>Foreground</UpdateMode>
+ <UpdateInterval>7</UpdateInterval>
+ <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+ <UpdatePeriodically>false</UpdatePeriodically>
+ <UpdateRequired>false</UpdateRequired>
+ <MapFileExtensions>true</MapFileExtensions>
+ <ApplicationRevision>0</ApplicationRevision>
+ <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+ <IsWebBootstrapper>false</IsWebBootstrapper>
+ <UseApplicationTrust>false</UseApplicationTrust>
+ <BootstrapperEnabled>true</BootstrapperEnabled>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@@ -48,6 +63,7 @@
</CodeContractsBaseLineFile>
<CodeContractsRuntimeCheckingLevel>Full</CodeContractsRuntimeCheckingLevel>
<CodeContractsReferenceAssembly>%28none%29</CodeContractsReferenceAssembly>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
@@ -56,6 +72,7 @@
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
+ <CodeAnalysisRuleSet>AllRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Build.Engine" />
@@ -89,14 +106,17 @@
<Compile Include="CreateWebApplication.cs" />
<Compile Include="DeleteWebApplication.cs" />
<Compile Include="DiscoverProjectTemplates.cs" />
+ <Compile Include="DowngradeProjects.cs" />
<Compile Include="ECMAScriptPacker.cs" />
<Compile Include="FilterItems.cs" />
<Compile Include="FixupReferenceHintPaths.cs" />
<Compile Include="FixupShippingToolSamples.cs" />
+ <Compile Include="HardLinkCopy.cs" />
<Compile Include="MergeProjectWithVSTemplate.cs" />
<Compile Include="GetBuildVersion.cs" />
<Compile Include="CheckAdminRights.cs" />
<Compile Include="JsPack.cs" />
+ <Compile Include="NativeMethods.cs" />
<Compile Include="ParseMaster.cs" />
<Compile Include="Publicize.cs" />
<Compile Include="Purge.cs" />
@@ -118,6 +138,23 @@
<LastGenOutput>TaskStrings.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
+ <ItemGroup>
+ <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+ <Install>false</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+ <Visible>False</Visible>
+ <ProductName>.NET Framework 3.5 SP1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ <BootstrapperPackage Include="Microsoft.Windows.Installer.3.1">
+ <Visible>False</Visible>
+ <ProductName>Windows Installer 3.1</ProductName>
+ <Install>true</Install>
+ </BootstrapperPackage>
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
diff --git a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.sln b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.sln
index 0d0900b..34a8e46 100644
--- a/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.sln
+++ b/src/DotNetOpenAuth.BuildTasks/DotNetOpenAuth.BuildTasks.sln
@@ -1,8 +1,6 @@

-Microsoft Visual Studio Solution File, Format Version 10.00
-# Visual Studio 2008
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetOpenAuth.BuildTasks", "DotNetOpenAuth.BuildTasks.csproj", "{AC231A51-EF60-437C-A33F-AF8ADEB8EB74}"
-EndProject
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{ABBE14A3-0404-4123-9093-E598C3DD3E9B}"
ProjectSection(SolutionItems) = preProject
..\..\build.proj = ..\..\build.proj
@@ -13,6 +11,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
..\..\tools\DotNetOpenAuth.Versioning.targets = ..\..\tools\DotNetOpenAuth.Versioning.targets
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DotNetOpenAuth.BuildTasks", "DotNetOpenAuth.BuildTasks.csproj", "{AC231A51-EF60-437C-A33F-AF8ADEB8EB74}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
diff --git a/src/DotNetOpenAuth.BuildTasks/DowngradeProjects.cs b/src/DotNetOpenAuth.BuildTasks/DowngradeProjects.cs
new file mode 100644
index 0000000..645522d
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/DowngradeProjects.cs
@@ -0,0 +1,110 @@
+//-----------------------------------------------------------------------
+// <copyright file="DowngradeProjects.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 Microsoft.Build.BuildEngine;
+ using Microsoft.Build.Framework;
+ using Microsoft.Build.Utilities;
+
+ /// <summary>
+ /// Downgrades Visual Studio 2010 solutions and projects so that they load in Visual Studio 2008.
+ /// </summary>
+ public class DowngradeProjects : Task {
+ /// <summary>
+ /// Gets or sets the projects and solutions to downgrade.
+ /// </summary>
+ [Required]
+ public ITaskItem[] Projects { get; set; }
+
+ /// <summary>
+ /// Gets or sets a value indicating whether ASP.NET MVC 2 projects are downgraded to MVC 1.0.
+ /// </summary>
+ public bool DowngradeMvc2ToMvc1 { get; set; }
+
+ /// <summary>
+ /// Executes this instance.
+ /// </summary>
+ public override bool Execute() {
+ foreach (ITaskItem taskItem in this.Projects) {
+ switch (GetClassification(taskItem)) {
+ case ProjectClassification.VS2010Project:
+ this.Log.LogMessage(MessageImportance.Low, "Downgrading project \"{0}\".", taskItem.ItemSpec);
+ Project project = new Project();
+ project.Load(taskItem.ItemSpec);
+ project.DefaultToolsVersion = "3.5";
+
+ if (this.DowngradeMvc2ToMvc1) {
+ string projectTypeGuids = project.GetEvaluatedProperty("ProjectTypeGuids");
+ if (!string.IsNullOrEmpty(projectTypeGuids)) {
+ projectTypeGuids = projectTypeGuids.Replace("{F85E285D-A4E0-4152-9332-AB1D724D3325}", "{603c0e0b-db56-11dc-be95-000d561079b0}");
+ project.SetProperty("ProjectTypeGuids", projectTypeGuids);
+ }
+ }
+
+ // Web projects usually have an import that includes these substrings
+ foreach (Import import in project.Imports) {
+ import.ProjectPath = import.ProjectPath
+ .Replace("$(MSBuildExtensionsPath32)", "$(MSBuildExtensionsPath)")
+ .Replace("VisualStudio\\v10.0", "VisualStudio\\v9.0");
+ }
+
+ // VS2010 won't let you have a System.Core reference, but VS2008 requires it.
+ BuildItemGroup references = project.GetEvaluatedItemsByName("Reference");
+ if (!references.Cast<BuildItem>().Any(item => item.FinalItemSpec.StartsWith("System.Core", StringComparison.OrdinalIgnoreCase))) {
+ project.AddNewItem("Reference", "System.Core");
+ }
+
+ project.Save(taskItem.ItemSpec);
+ break;
+ case ProjectClassification.VS2010Solution:
+ this.Log.LogMessage(MessageImportance.Low, "Downgrading solution \"{0}\".", taskItem.ItemSpec);
+ string[] contents = File.ReadAllLines(taskItem.ItemSpec);
+ if (contents[1] != "Microsoft Visual Studio Solution File, Format Version 11.00" ||
+ contents[2] != "# Visual Studio 2010") {
+ this.Log.LogError("Unrecognized solution file header in \"{0}\".", taskItem.ItemSpec);
+ break;
+ }
+
+ contents[1] = "Microsoft Visual Studio Solution File, Format Version 10.00";
+ contents[2] = "# Visual Studio 2008";
+
+ for (int i = 3; i < contents.Length; i++) {
+ contents[i] = contents[i].Replace("TargetFrameworkMoniker = \".NETFramework,Version%3Dv", "TargetFramework = \"");
+ }
+
+ File.WriteAllLines(taskItem.ItemSpec, contents);
+ break;
+ default:
+ this.Log.LogWarning("Unrecognized project type for \"{0}\".", taskItem.ItemSpec);
+ break;
+ }
+ }
+
+ return !this.Log.HasLoggedErrors;
+ }
+
+ private static ProjectClassification GetClassification(ITaskItem taskItem) {
+ if (Path.GetExtension(taskItem.ItemSpec).EndsWith("proj", StringComparison.OrdinalIgnoreCase)) {
+ return ProjectClassification.VS2010Project;
+ } else if (Path.GetExtension(taskItem.ItemSpec).Equals(".sln", StringComparison.OrdinalIgnoreCase)) {
+ return ProjectClassification.VS2010Solution;
+ } else {
+ return ProjectClassification.Unrecognized;
+ }
+ }
+
+ private enum ProjectClassification {
+ VS2010Project,
+ VS2010Solution,
+ Unrecognized,
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/FixupShippingToolSamples.cs b/src/DotNetOpenAuth.BuildTasks/FixupShippingToolSamples.cs
index a6088c9..6c71740 100644
--- a/src/DotNetOpenAuth.BuildTasks/FixupShippingToolSamples.cs
+++ b/src/DotNetOpenAuth.BuildTasks/FixupShippingToolSamples.cs
@@ -6,6 +6,7 @@
namespace DotNetOpenAuth.BuildTasks {
using System;
+ using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -24,6 +25,8 @@ namespace DotNetOpenAuth.BuildTasks {
public string[] RemoveImportsStartingWith { get; set; }
+ public ITaskItem[] AddReferences { get; set; }
+
/// <summary>
/// Executes this instance.
/// </summary>
@@ -43,6 +46,15 @@ namespace DotNetOpenAuth.BuildTasks {
.ForEach(import => project.Imports.RemoveImport(import));
}
+ if (this.AddReferences != null) {
+ foreach (var reference in this.AddReferences) {
+ BuildItem item = project.AddNewItem("Reference", reference.ItemSpec);
+ foreach (DictionaryEntry metadata in reference.CloneCustomMetadata()) {
+ item.SetMetadata((string)metadata.Key, (string)metadata.Value);
+ }
+ }
+ }
+
project.Save(projectTaskItem.ItemSpec);
}
diff --git a/src/DotNetOpenAuth.BuildTasks/HardLinkCopy.cs b/src/DotNetOpenAuth.BuildTasks/HardLinkCopy.cs
new file mode 100644
index 0000000..af2d1d0
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/HardLinkCopy.cs
@@ -0,0 +1,61 @@
+//-----------------------------------------------------------------------
+// <copyright file="HardLinkCopy.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.IO;
+
+ public class HardLinkCopy : Task {
+ [Required]
+ public ITaskItem[] SourceFiles { get; set; }
+
+ [Required]
+ public ITaskItem[] DestinationFiles { get; set; }
+
+ /// <summary>
+ /// Executes this instance.
+ /// </summary>
+ public override bool Execute() {
+ if (this.SourceFiles.Length != this.DestinationFiles.Length) {
+ this.Log.LogError("SourceFiles has {0} elements and DestinationFiles has {1} elements.", this.SourceFiles.Length, this.DestinationFiles.Length);
+ return false;
+ }
+
+ for (int i = 0; i < this.SourceFiles.Length; i++) {
+ bool hardLink;
+ bool.TryParse(this.DestinationFiles[i].GetMetadata("HardLink"), out hardLink);
+ string sourceFile = this.SourceFiles[i].ItemSpec;
+ string destinationFile = this.DestinationFiles[i].ItemSpec;
+ this.Log.LogMessage(
+ MessageImportance.Low,
+ "Copying {0} -> {1}{2}.",
+ sourceFile,
+ destinationFile,
+ hardLink ? " as hard link" : string.Empty);
+
+ if (!Directory.Exists(Path.GetDirectoryName(destinationFile))) {
+ Directory.CreateDirectory(Path.GetDirectoryName(destinationFile));
+ }
+
+ if (hardLink) {
+ if (File.Exists(destinationFile)) {
+ File.Delete(destinationFile);
+ }
+ NativeMethods.CreateHardLink(sourceFile, destinationFile);
+ } else {
+ File.Copy(sourceFile, destinationFile, true);
+ }
+ }
+
+ return !this.Log.HasLoggedErrors;
+ }
+ }
+}
diff --git a/src/DotNetOpenAuth.BuildTasks/NativeMethods.cs b/src/DotNetOpenAuth.BuildTasks/NativeMethods.cs
new file mode 100644
index 0000000..26de3a4
--- /dev/null
+++ b/src/DotNetOpenAuth.BuildTasks/NativeMethods.cs
@@ -0,0 +1,18 @@
+namespace DotNetOpenAuth.BuildTasks {
+ using System;
+ using System.Collections.Generic;
+ using System.Linq;
+ using System.Text;
+ using System.Runtime.InteropServices;
+
+ internal static class NativeMethods {
+ [DllImport("kernel32", SetLastError = true)]
+ private static extern bool CreateHardLink(string newFileName, string existingFileName, IntPtr securityAttributes);
+
+ internal static void CreateHardLink(string existingFileName, string newFileName) {
+ if (!CreateHardLink(newFileName, existingFileName, IntPtr.Zero)) {
+ Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error());
+ }
+ }
+ }
+}