diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionAbpVersionFinder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionAbpVersionFinder.cs
index a86d17fee2..93dbeacc22 100644
--- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionAbpVersionFinder.cs
+++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionAbpVersionFinder.cs
@@ -1,5 +1,7 @@
using System.IO;
+using System.Text.RegularExpressions;
using System.Xml;
+using NuGet.Versioning;
using Volo.Abp.Cli.Utils;
using Volo.Abp.DependencyInjection;
@@ -9,28 +11,139 @@ namespace Volo.Abp.Cli.ProjectModification
{
public string Find(string solutionFile)
{
- var projectFilesUnderSrc = Directory.GetFiles(Path.GetDirectoryName(solutionFile),
- "*.csproj",
- SearchOption.AllDirectories);
-
+ var projectFilesUnderSrc = GetProjectFilesOfSolution(solutionFile);
foreach (var projectFile in projectFilesUnderSrc)
{
var content = File.ReadAllText(projectFile);
- var doc = new XmlDocument() { PreserveWhitespace = true };
+ if (TryParseVersionFromCsprojViaXmlDocument(content, out var s))
+ {
+ return s;
+ }
+ }
- doc.Load(StreamHelper.GenerateStreamFromString(content));
+ return null;
+ }
+ private static bool TryParseVersionFromCsprojViaXmlDocument(string content, out string version)
+ {
+ var doc = new XmlDocument() { PreserveWhitespace = true };
+ using (var stream = StreamHelper.GenerateStreamFromString(content))
+ {
+ doc.Load(stream);
var nodes = doc.SelectNodes("/Project/ItemGroup/PackageReference[starts-with(@Include, 'Volo.Abp')]");
-
var value = nodes?[0]?.Attributes?["Version"]?.Value;
+ if (value == null)
+ {
+ version = null;
+ return false;
+ }
+
+ version = value;
+ return true;
+ }
+ }
- if (value != null)
+ public static bool TryParseVersionFromCsprojFile(string csprojContent, out string version)
+ {
+ try
+ {
+ var matches = Regex.Matches(csprojContent,
+ @"PackageReference\s*Include\s*=\s*\""Volo.Abp(.*?)\""\s*Version\s*=\s*\""(.*?)\""",
+ RegexOptions.IgnoreCase |
+ RegexOptions.IgnorePatternWhitespace |
+ RegexOptions.Singleline | RegexOptions.Multiline);
+
+ foreach (Match match in matches)
{
- return value;
+ if (match.Groups.Count > 2)
+ {
+ version = match.Groups[2].Value;
+ return true;
+ }
}
}
+ catch
+ {
+ //ignored
+ }
- return null;
+ version = null;
+ return false;
+ }
+
+
+ public static bool TryParseSemanticVersionFromCsprojFile(string csprojContent, out SemanticVersion version)
+ {
+ try
+ {
+ if (TryParseVersionFromCsprojFile(csprojContent, out var versionText))
+ {
+ return SemanticVersion.TryParse(versionText, out version);
+ }
+ }
+ catch
+ {
+ //ignored
+ }
+
+ version = null;
+ return false;
+ }
+
+ public static bool TryFind(string solutionFile, out string version)
+ {
+ var projectFiles = GetProjectFilesOfSolution(solutionFile);
+ foreach (var projectFile in projectFiles)
+ {
+ var csprojContent = File.ReadAllText(projectFile);
+ if (TryParseVersionFromCsprojFile(csprojContent, out var parsedVersion))
+ {
+ version = parsedVersion;
+ return true;
+ }
+ }
+
+ version = null;
+ return false;
+ }
+
+ public static bool TryFindSemanticVersion(string solutionFile, out SemanticVersion version)
+ {
+ var projectFiles = GetProjectFilesOfSolution(solutionFile);
+ foreach (var projectFile in projectFiles)
+ {
+ var csprojContent = File.ReadAllText(projectFile);
+ if (TryParseSemanticVersionFromCsprojFile(csprojContent, out var parsedVersion))
+ {
+ version = parsedVersion;
+ return true;
+ }
+ }
+
+ version = null;
+ return false;
+ }
+
+ //public static bool TryFindSemanticVersion(string solutionFile, out SemanticVersion version)
+ //{
+ // if (TryFind(solutionFile, out var versionText))
+ // {
+ // return SemanticVersion.TryParse(versionText, out version);
+ // }
+
+ // version = null;
+ // return false;
+ //}
+
+ private static string[] GetProjectFilesOfSolution(string solutionFile)
+ {
+ var solutionDirectory = Path.GetDirectoryName(solutionFile);
+ if (solutionDirectory == null)
+ {
+ return new string[] { };
+ }
+
+ return Directory.GetFiles(solutionDirectory, "*.csproj", SearchOption.AllDirectories);
}
}
}
diff --git a/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/ProjectVersionParse_Tests.cs b/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/ProjectVersionParse_Tests.cs
new file mode 100644
index 0000000000..eb4a9eda24
--- /dev/null
+++ b/framework/test/Volo.Abp.Cli.Core.Tests/Volo/Abp/Cli/ProjectVersionParse_Tests.cs
@@ -0,0 +1,70 @@
+using Shouldly;
+using Volo.Abp.Cli.ProjectModification;
+using Xunit;
+
+namespace Volo.Abp.Cli
+{
+ public class ProjectVersionParse_Tests
+ {
+ [Fact]
+ public void Find_Abp_Version()
+ {
+ const string csprojContent = "" +
+ "" +
+ "" +
+ "net5.0" +
+ "Blazoor.EfCore07062034" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "< PackageReference Include = \"Volo.Abp.Emailing\" Version = \"4.4.0-rc.1\" />" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "";
+
+ var success = SolutionAbpVersionFinder.TryParseVersionFromCsprojFile(csprojContent, out var version);
+ success.ShouldBe(true);
+ version.ShouldBe("4.4.0-rc.1");
+ }
+
+ [Fact]
+ public void Find_Abp_Semantic_Version()
+ {
+ const string csprojContent = "" +
+ "" +
+ "" +
+ "net5.0" +
+ "Blazoor.EfCore07062034" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "" +
+ "< PackageReference Include = \"Volo.Abp.Emailing\" Version= \"12.8.3-beta.1\" />" +
+ "" +
+ "";
+
+ var success = SolutionAbpVersionFinder.TryParseSemanticVersionFromCsprojFile(csprojContent, out var version);
+ success.ShouldBe(true);
+ version.Major.ShouldBe(12);
+ version.Minor.ShouldBe(8);
+ version.Patch.ShouldBe(3);
+ version.Release.ShouldBe("beta.1");
+ }
+
+ }
+}