From 55566e21fef41f59995efde73249563e1214538e Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 9 Oct 2019 16:53:50 +0300 Subject: [PATCH] Refactor ReferenceReplaceStep --- .../Building/ProjectBuildPipelineBuilder.cs | 7 +- .../Steps/NugetReferenceReplaceStep.cs | 180 --------------- .../Steps/ProjectReferenceReplaceStep.cs | 212 ++++++++++++++++++ .../Cli/ProjectBuilding/ProjectBuildArgs.cs | 6 +- 4 files changed, 216 insertions(+), 189 deletions(-) delete mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/NugetReferenceReplaceStep.cs create mode 100644 framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildPipelineBuilder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildPipelineBuilder.cs index 945ed07338..55a7984dce 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildPipelineBuilder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/ProjectBuildPipelineBuilder.cs @@ -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()); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/NugetReferenceReplaceStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/NugetReferenceReplaceStep.cs deleted file mode 100644 index 03c25f99cb..0000000000 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/NugetReferenceReplaceStep.cs +++ /dev/null @@ -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 _entries; - private readonly string _companyAndProjectNamePlaceHolder; - private readonly string _nugetPackageVersion; - private readonly bool _localReferences; - private readonly string _gitHubLocalRepositoryPath; - - public NugetReferenceReplacer( - List 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; - } - } - } -} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs new file mode 100644 index 0000000000..b040c5320d --- /dev/null +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectReferenceReplaceStep.cs @@ -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 _entries; + private readonly string _companyAndProjectNamePlaceHolder; + + protected ProjectReferenceReplacer( + List 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 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 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; + } + } + } + } +} diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuildArgs.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuildArgs.cs index 7dc810ea84..5586321010 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuildArgs.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/ProjectBuildArgs.cs @@ -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 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 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(); } }