Refactor ReferenceReplaceStep

pull/1857/head
Yunus Emre Kalkan 6 years ago
parent db2c848c18
commit 55566e21fe

@ -13,13 +13,8 @@ namespace Volo.Abp.Cli.ProjectBuilding.Building
pipeline.Steps.Add(new FileEntryListReadStep());
pipeline.Steps.AddRange(context.Template.GetCustomSteps(context));
if (!context.BuildArgs.ExtraProperties.ContainsKey("local-framework-ref") ||
!string.IsNullOrWhiteSpace(context.BuildArgs.GitHubLocalRepositoryPath))
{
pipeline.Steps.Add(new NugetReferenceReplaceStep());
}
pipeline.Steps.Add(new ProjectReferenceReplaceStep());
pipeline.Steps.Add(new TemplateCodeDeleteStep());
pipeline.Steps.Add(new SolutionRenameStep());

@ -1,180 +0,0 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;
using Volo.Abp.Cli.ProjectBuilding.Files;
namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps
{
public class NugetReferenceReplaceStep : ProjectBuildPipelineStep
{
public override void Execute(ProjectBuildContext context)
{
var nugetPackageVersion = context.TemplateFile.Version;
if (IsBranchName(nugetPackageVersion))
{
nugetPackageVersion = context.TemplateFile.LatestVersion;
}
new NugetReferenceReplacer(
context.Files,
"MyCompanyName.MyProjectName",
nugetPackageVersion,
context.BuildArgs.ExtraProperties.ContainsKey("local-framework-ref"),
context.BuildArgs.GitHubLocalRepositoryPath
).Run();
}
private bool IsBranchName(string versionOrBranchName)
{
Check.NotNullOrWhiteSpace(versionOrBranchName, nameof(versionOrBranchName));
if (char.IsDigit(versionOrBranchName[0]))
{
return false;
}
if (versionOrBranchName[0].IsIn('v','V') &&
versionOrBranchName.Length > 1 &&
char.IsDigit(versionOrBranchName[1]))
{
return false;
}
return true;
}
private class NugetReferenceReplacer
{
private readonly List<FileEntry> _entries;
private readonly string _companyAndProjectNamePlaceHolder;
private readonly string _nugetPackageVersion;
private readonly bool _localReferences;
private readonly string _gitHubLocalRepositoryPath;
public NugetReferenceReplacer(
List<FileEntry> entries,
string companyAndProjectNamePlaceHolder,
string nugetPackageVersion,
bool localReferences = false,
string gitHubLocalRepositoryPath = null)
{
_entries = entries;
_companyAndProjectNamePlaceHolder = companyAndProjectNamePlaceHolder;
_nugetPackageVersion = nugetPackageVersion;
_localReferences = localReferences;
_gitHubLocalRepositoryPath = gitHubLocalRepositoryPath;
}
public void Run()
{
foreach (var fileEntry in _entries)
{
if (fileEntry.Name.EndsWith(".csproj"))
{
fileEntry.SetContent(ProcessFileContent(fileEntry.Content));
}
}
}
private string ProcessFileContent(string content)
{
Check.NotNull(content, nameof(content));
var doc = new XmlDocument() { PreserveWhitespace = true };
doc.Load(GenerateStreamFromString(content));
return ProcessReferenceNodes(doc, content);
}
private string ProcessReferenceNodes(XmlDocument doc, string content)
{
Check.NotNull(content, nameof(content));
var nodes = doc.SelectNodes("/Project/ItemGroup/ProjectReference[@Include]");
foreach (XmlNode oldNode in nodes)
{
var oldNodeIncludeValue = oldNode.Attributes["Include"].Value;
// ReSharper disable once PossibleNullReferenceException : Can not be null because nodes are selected with include attribute filter in previous method
if (oldNodeIncludeValue.Contains($"{_companyAndProjectNamePlaceHolder}"))
{
continue;
}
XmlNode newNode = null;
newNode = _localReferences ?
GetLocalReferenceNode(doc, oldNodeIncludeValue) :
GetNugetReferenceNode(doc, oldNodeIncludeValue);
oldNode.ParentNode.ReplaceChild(newNode, oldNode);
}
return doc.OuterXml;
}
private XmlElement GetNugetReferenceNode(XmlDocument doc, string oldNodeIncludeValue)
{
var newNode = doc.CreateElement("PackageReference");
var includeAttr = doc.CreateAttribute("Include");
includeAttr.Value = ConvertToNugetReference(oldNodeIncludeValue);
newNode.Attributes.Append(includeAttr);
var versionAttr = doc.CreateAttribute("Version");
versionAttr.Value = _nugetPackageVersion;
newNode.Attributes.Append(versionAttr);
return newNode;
}
private XmlElement GetLocalReferenceNode(XmlDocument doc, string oldNodeIncludeValue)
{
var newNode = doc.CreateElement("ProjectReference");
var includeAttr = doc.CreateAttribute("Include");
includeAttr.Value = SetGithubPath(oldNodeIncludeValue);
newNode.Attributes.Append(includeAttr);
return newNode;
}
private string SetGithubPath(string includeValue)
{
while (includeValue.StartsWith("..\\"))
{
includeValue = includeValue.TrimStart('.');
includeValue = includeValue.TrimStart('\\');
}
includeValue = _gitHubLocalRepositoryPath.EnsureEndsWith('\\') + includeValue;
return includeValue;
}
private string ConvertToNugetReference(string oldValue)
{
var newValue = Regex.Match(oldValue, @"\\((?!.+?\\).+?)\.csproj", RegexOptions.CultureInvariant | RegexOptions.Compiled);
if (newValue.Success && newValue.Groups.Count == 2)
{
return newValue.Groups[1].Value;
}
return oldValue;
}
private static Stream GenerateStreamFromString(string s)
{
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
}
}
}

@ -0,0 +1,212 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Text.RegularExpressions;
using System.Xml;
using Volo.Abp.Cli.ProjectBuilding.Files;
namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps
{
public class ProjectReferenceReplaceStep : ProjectBuildPipelineStep
{
public override void Execute(ProjectBuildContext context)
{
if (context.BuildArgs.ExtraProperties.ContainsKey("local-framework-ref"))
{
var localAbpRepoPath = context.BuildArgs.AbpGitHubLocalRepositoryPath;
if (string.IsNullOrWhiteSpace(localAbpRepoPath))
{
return;
}
new ProjectReferenceReplacer.LocalProjectPathReferenceReplacer(
context.Files,
"MyCompanyName.MyProjectName",
localAbpRepoPath
).Run();
}
else
{
var nugetPackageVersion = context.TemplateFile.Version;
if (IsBranchName(nugetPackageVersion))
{
nugetPackageVersion = context.TemplateFile.LatestVersion;
}
new ProjectReferenceReplacer.NugetReferenceReplacer(
context.Files,
"MyCompanyName.MyProjectName",
nugetPackageVersion
).Run();
}
}
private bool IsBranchName(string versionOrBranchName)
{
Check.NotNullOrWhiteSpace(versionOrBranchName, nameof(versionOrBranchName));
if (char.IsDigit(versionOrBranchName[0]))
{
return false;
}
if (versionOrBranchName[0].IsIn('v', 'V') &&
versionOrBranchName.Length > 1 &&
char.IsDigit(versionOrBranchName[1]))
{
return false;
}
return true;
}
private abstract class ProjectReferenceReplacer
{
private readonly List<FileEntry> _entries;
private readonly string _companyAndProjectNamePlaceHolder;
protected ProjectReferenceReplacer(
List<FileEntry> entries,
string companyAndProjectNamePlaceHolder)
{
_entries = entries;
_companyAndProjectNamePlaceHolder = companyAndProjectNamePlaceHolder;
}
public void Run()
{
foreach (var fileEntry in _entries)
{
if (fileEntry.Name.EndsWith(".csproj"))
{
fileEntry.SetContent(ProcessFileContent(fileEntry.Content));
}
}
}
private string ProcessFileContent(string content)
{
Check.NotNull(content, nameof(content));
var doc = new XmlDocument() { PreserveWhitespace = true };
doc.Load(GenerateStreamFromString(content));
return ProcessReferenceNodes(doc, content);
}
private string ProcessReferenceNodes(XmlDocument doc, string content)
{
Check.NotNull(content, nameof(content));
var nodes = doc.SelectNodes("/Project/ItemGroup/ProjectReference[@Include]");
foreach (XmlNode oldNode in nodes)
{
var oldNodeIncludeValue = oldNode.Attributes["Include"].Value;
// ReSharper disable once PossibleNullReferenceException : Can not be null because nodes are selected with include attribute filter in previous method
if (oldNodeIncludeValue.Contains($"{_companyAndProjectNamePlaceHolder}"))
{
continue;
}
XmlNode newNode = null;
newNode = GetNewReferenceNode(doc, oldNodeIncludeValue);
oldNode.ParentNode.ReplaceChild(newNode, oldNode);
}
return doc.OuterXml;
}
protected abstract XmlElement GetNewReferenceNode(XmlDocument doc, string oldNodeIncludeValue);
private static Stream GenerateStreamFromString(string s)
{
var stream = new MemoryStream();
var writer = new StreamWriter(stream);
writer.Write(s);
writer.Flush();
stream.Position = 0;
return stream;
}
public class NugetReferenceReplacer : ProjectReferenceReplacer
{
private readonly string _nugetPackageVersion;
public NugetReferenceReplacer(List<FileEntry> entries, string companyAndProjectNamePlaceHolder, string nugetPackageVersion)
: base(entries, companyAndProjectNamePlaceHolder)
{
_nugetPackageVersion = nugetPackageVersion;
}
protected override XmlElement GetNewReferenceNode(XmlDocument doc, string oldNodeIncludeValue)
{
var newNode = doc.CreateElement("PackageReference");
var includeAttr = doc.CreateAttribute("Include");
includeAttr.Value = ConvertToNugetReference(oldNodeIncludeValue);
newNode.Attributes.Append(includeAttr);
var versionAttr = doc.CreateAttribute("Version");
versionAttr.Value = _nugetPackageVersion;
newNode.Attributes.Append(versionAttr);
return newNode;
}
private string ConvertToNugetReference(string oldValue)
{
var newValue = Regex.Match(oldValue, @"\\((?!.+?\\).+?)\.csproj", RegexOptions.CultureInvariant | RegexOptions.Compiled);
if (newValue.Success && newValue.Groups.Count == 2)
{
return newValue.Groups[1].Value;
}
return oldValue;
}
}
public class LocalProjectPathReferenceReplacer : ProjectReferenceReplacer
{
private readonly string _gitHubLocalRepositoryPath;
public LocalProjectPathReferenceReplacer(List<FileEntry> entries, string companyAndProjectNamePlaceHolder, string gitHubLocalRepositoryPath)
: base(entries, companyAndProjectNamePlaceHolder)
{
_gitHubLocalRepositoryPath = gitHubLocalRepositoryPath;
}
protected override XmlElement GetNewReferenceNode(XmlDocument doc, string oldNodeIncludeValue)
{
var newNode = doc.CreateElement("ProjectReference");
var includeAttr = doc.CreateAttribute("Include");
includeAttr.Value = SetGithubPath(oldNodeIncludeValue);
newNode.Attributes.Append(includeAttr);
return newNode;
}
private string SetGithubPath(string includeValue)
{
while (includeValue.StartsWith("..\\"))
{
includeValue = includeValue.TrimStart('.');
includeValue = includeValue.TrimStart('\\');
}
includeValue = _gitHubLocalRepositoryPath.EnsureEndsWith('\\') + includeValue;
return includeValue;
}
}
}
}
}

@ -20,7 +20,7 @@ namespace Volo.Abp.Cli.ProjectBuilding
public UiFramework UiFramework { get; set; }
[CanBeNull]
public string GitHubLocalRepositoryPath { get; set; }
public string AbpGitHubLocalRepositoryPath { get; set; }
[NotNull]
public Dictionary<string, string> ExtraProperties { get; set; }
@ -31,7 +31,7 @@ namespace Volo.Abp.Cli.ProjectBuilding
[CanBeNull] string version = null,
DatabaseProvider databaseProvider = DatabaseProvider.NotSpecified,
UiFramework uiFramework = UiFramework.NotSpecified,
[CanBeNull] string gitHubLocalRepositoryPath = null,
[CanBeNull] string abpGitHubLocalRepositoryPath = null,
Dictionary<string, string> extraProperties = null)
{
SolutionName = Check.NotNull(solutionName, nameof(solutionName));
@ -39,7 +39,7 @@ namespace Volo.Abp.Cli.ProjectBuilding
Version = version;
DatabaseProvider = databaseProvider;
UiFramework = uiFramework;
GitHubLocalRepositoryPath = gitHubLocalRepositoryPath;
AbpGitHubLocalRepositoryPath = abpGitHubLocalRepositoryPath;
ExtraProperties = extraProperties ?? new Dictionary<string, string>();
}
}

Loading…
Cancel
Save