aspnetcore/tools/DependencyUpdater/SubstituteProjectFileVariab...

89 lines
2.9 KiB
C#

using Microsoft.Build.Framework;
using Microsoft.Build.Utilities;
using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
namespace DependencyUpdater
{
public class SubstituteProjectFileVariables : Task
{
private static string[] ProjectFileExtensions = new[]
{
".csproj",
".fsproj"
};
[Required] public string NupkgFile { get; set; }
[Required] public string OutDir { get; set; }
[Required] public ITaskItem[] Substitutions { get; set; }
public override bool Execute()
{
// We can't modify the .nupkg in place because the build system still
// has a lock on the file. We can read it, but not write it. So copy
// to the output location and then modify the copy.
var outFile = Path.Combine(OutDir, Path.GetFileName(NupkgFile));
File.Copy(NupkgFile, outFile, true);
var numProjectFiles = 0;
using (var zipFile = ZipFile.Open(outFile, ZipArchiveMode.Update))
{
foreach (var projectFile in zipFile.Entries.Where(IsProjectFile))
{
numProjectFiles++;
PerformVariableSubstitutions(projectFile);
}
}
if (numProjectFiles == 0)
{
Log.LogMessage(
MessageImportance.High,
$"No project files found in {Path.GetFileName(outFile)}, so no variables substituted.");
}
else
{
Log.LogMessage(
MessageImportance.High,
$"Substituted variables in {numProjectFiles} project file(s) in {Path.GetFileName(outFile)}");
}
return true;
}
private static bool IsProjectFile(ZipArchiveEntry entry)
{
return ProjectFileExtensions.Any(
extension => Path.GetExtension(entry.Name).Equals(extension, StringComparison.OrdinalIgnoreCase));
}
private void PerformVariableSubstitutions(ZipArchiveEntry entry)
{
using (var fileStream = entry.Open())
{
string contents;
using (var reader = new StreamReader(fileStream))
using (var writer = new StreamWriter(fileStream))
{
contents = reader.ReadToEnd();
fileStream.Seek(0, SeekOrigin.Begin);
fileStream.SetLength(0);
writer.Write(SubstituteVariables(contents));
}
}
}
private string SubstituteVariables(string text)
{
foreach (var item in Substitutions)
{
text = text.Replace($"$({item.ItemSpec})", item.GetMetadata("Value"));
}
return text;
}
}
}