From 9ce0a6bf34fa5baa36134b078748cbb2334602ea Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 30 Sep 2025 08:52:26 +0300 Subject: [PATCH 1/9] Cli: Slnx file support (initial) --- .../FileSystemDotNetProjectBuildConfigReader.cs | 7 ++++--- .../Volo/Abp/Cli/Commands/AddModuleCommand.cs | 14 ++++++++------ .../Volo/Abp/Cli/Commands/AddPackageCommand.cs | 5 +++-- .../Abp/Cli/Commands/ProjectCreationCommandBase.cs | 10 ++++++---- .../Volo/Abp/Cli/Commands/SuiteCommand.cs | 5 +++-- .../Volo/Abp/Cli/Commands/SwitchToLocalCommand.cs | 2 +- .../Volo/Abp/Cli/Commands/UpdateCommand.cs | 3 ++- .../Building/Steps/AppNoLayersMoveProjectsStep.cs | 2 +- .../Building/Steps/ProjectRenameStep.cs | 2 +- .../Steps/RemoveProjectFromSolutionStep.cs | 7 +++++-- .../MicroserviceServiceStringEncryptionStep.cs | 3 ++- .../ProjectModification/PackagePreviewSwitcher.cs | 6 ++++-- .../ProjectNugetPackageAdder.cs | 6 ++++-- .../Cli/ProjectModification/SolutionModuleAdder.cs | 6 ++++-- 14 files changed, 48 insertions(+), 30 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/FileSystemDotNetProjectBuildConfigReader.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/FileSystemDotNetProjectBuildConfigReader.cs index 47daa1d401..b421ea0dd4 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/FileSystemDotNetProjectBuildConfigReader.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Build/FileSystemDotNetProjectBuildConfigReader.cs @@ -21,8 +21,9 @@ public class FileSystemDotNetProjectBuildConfigReader : IDotNetProjectBuildConfi public DotNetProjectBuildConfig Read(string directoryPath) { var buildConfig = new DotNetProjectBuildConfig(); - var solutionFiles = Directory.GetFiles(directoryPath, "*.sln", SearchOption.TopDirectoryOnly); - if (solutionFiles.Length == 1) + var solutionFiles = Directory.GetFiles(directoryPath, "*.sln", SearchOption.TopDirectoryOnly) + .Concat(Directory.GetFiles(directoryPath, "*.slnx", SearchOption.TopDirectoryOnly)).ToList(); + if (solutionFiles.Count == 1) { buildConfig.SlFilePath = solutionFiles.First(); var configFile = GetClosestFile(directoryPath, _buildConfigName); @@ -86,7 +87,7 @@ public class FileSystemDotNetProjectBuildConfigReader : IDotNetProjectBuildConfi directoryInfo = directoryInfo.Parent; } while (directoryInfo?.Parent != null); - throw new Exception("There is no solution file (*.sln) and " + _buildConfigName + + throw new Exception("There is no solution file (*.sln or *.slnx) and " + _buildConfigName + " in the working directory and working directory is not a GIT repository !"); } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs index 1791a5e928..d0229538da 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs @@ -1,5 +1,6 @@ using System; using System.IO; +using System.Linq; using System.Text; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; @@ -118,7 +119,7 @@ public class AddModuleCommand : IConsoleCommand, ITransientDependency sb.AppendLine(""); sb.AppendLine("'add-module' command is used to add a multi-package ABP module to a solution."); - sb.AppendLine("It should be used in a folder containing a .sln file."); + sb.AppendLine("It should be used in a folder containing a .sln or .slnx file."); sb.AppendLine(""); sb.AppendLine("Usage:"); sb.AppendLine(" abp add-module [options]"); @@ -166,20 +167,21 @@ public class AddModuleCommand : IConsoleCommand, ITransientDependency return providedSolutionFile; } - var foundSolutionFiles = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.sln"); - if (foundSolutionFiles.Length == 1) + var foundSolutionFiles = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.sln") + .Concat(Directory.GetFiles(Directory.GetCurrentDirectory(), "*.sln")).ToList(); + if (foundSolutionFiles.Count == 1) { return foundSolutionFiles[0]; } - if (foundSolutionFiles.Length == 0) + if (foundSolutionFiles.Count == 0) { - throw new CliUsageException("'abp add-module' command should be used inside a folder containing a .sln file!"); + throw new CliUsageException("'abp add-module' command should be used inside a folder containing a .sln or .slnx file!"); } //foundSolutionFiles.Length > 1 - var sb = new StringBuilder("There are multiple solution (.sln) files in the current directory. Please specify one of the files below:"); + var sb = new StringBuilder("There are multiple solution (.sln or .slnx) files in the current directory. Please specify one of the files below:"); foreach (var foundSolutionFile in foundSolutionFiles) { diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs index 32d9f49799..e9acb7ae24 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddPackageCommand.cs @@ -83,7 +83,7 @@ public class AddPackageCommand : IConsoleCommand, ITransientDependency sb.AppendLine(""); sb.AppendLine("'add-package' command is used to add an ABP package to a project."); - sb.AppendLine("It should be used in a folder containing a .csproj file, .sln file or packages.json."); + sb.AppendLine("It should be used in a folder containing a .csproj file, .sln file, .slnx file or packages.json."); sb.AppendLine(""); sb.AppendLine("Usage:"); sb.AppendLine(""); @@ -146,7 +146,8 @@ public class AddPackageCommand : IConsoleCommand, ITransientDependency return providedSolutionFile; } - return Directory.GetFiles(Directory.GetCurrentDirectory(), "*.sln").FirstOrDefault(); + return Directory.GetFiles(Directory.GetCurrentDirectory(), "*.sln") + .Concat(Directory.GetFiles(Directory.GetCurrentDirectory(), "*.slnx")).FirstOrDefault(); } protected virtual string GetAngularDirectory(CommandLineArgs commandLineArgs) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs index dabc6b6862..63c59c2e81 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs @@ -175,9 +175,10 @@ public abstract class ProjectCreationCommandBase if (slnPath == null) { - slnPath = Directory.GetFiles(outputFolderRoot, "*.sln").FirstOrDefault(); + slnPath = Directory.GetFiles(outputFolderRoot, "*.sln") + .Concat(Directory.GetFiles(outputFolderRoot, "*.sln")).FirstOrDefault(); } - else if (slnPath.EndsWith(".sln")) + else if (slnPath.EndsWith(".sln") || slnPath.EndsWith(".slnx")) { Directory.SetCurrentDirectory(Path.GetDirectoryName(slnPath)); outputFolderRoot = Path.GetDirectoryName(slnPath); @@ -190,7 +191,8 @@ public abstract class ProjectCreationCommandBase { Directory.SetCurrentDirectory(slnPath); outputFolderRoot = slnPath; - slnPath = Directory.GetFiles(outputFolderRoot, "*.sln").FirstOrDefault(); + slnPath = Directory.GetFiles(outputFolderRoot, "*.sln") + .Concat(Directory.GetFiles(outputFolderRoot, "*.slnx")).FirstOrDefault(); } if (slnPath == null) @@ -198,7 +200,7 @@ public abstract class ProjectCreationCommandBase throw new CliUsageException($"This command should be run inside a folder that contains a microservice solution! Or use -{Options.MainSolution.Short} parameter."); } - var microserviceSolutionName = Path.GetFileName(slnPath).RemovePostFix(".sln"); + var microserviceSolutionName = Path.GetFileName(slnPath).RemovePostFix(".slnx").RemovePostFix(".sln"); version ??= SolutionPackageVersionFinder.FindByCsprojVersion(slnPath); solutionName = SolutionName.Parse(microserviceSolutionName, projectName); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs index 48f5eca5f8..80d5a5a13b 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SuiteCommand.cs @@ -119,7 +119,7 @@ public class SuiteCommand : IConsoleCommand, ITransientDependency var solutionFile = args.Options.GetOrNull(Options.Crud.Solution.Short, Options.Crud.Solution.Long); if (entityFile.IsNullOrEmpty() || !entityFile.EndsWith(".json") || !File.Exists(entityFile) || - solutionFile.IsNullOrEmpty() || !solutionFile.EndsWith(".sln")) + solutionFile.IsNullOrEmpty() || !(solutionFile.EndsWith(".sln") || solutionFile.EndsWith(".slnx"))) { throw new UserFriendlyException("Invalid Arguments!"); } @@ -476,7 +476,8 @@ public class SuiteCommand : IConsoleCommand, ITransientDependency private object GetTargetSolutionOrNull(CommandLineArgs commandLineArgs) { return commandLineArgs.Options.GetOrNull(Options.Crud.Solution.Short, Options.Crud.Solution.Long) - ?? Directory.GetFiles(Directory.GetCurrentDirectory(), "*.sln", SearchOption.TopDirectoryOnly).FirstOrDefault(); + ?? Directory.GetFiles(Directory.GetCurrentDirectory(), "*.sln", SearchOption.TopDirectoryOnly) + .Concat(Directory.GetFiles(Directory.GetCurrentDirectory(), "*.slnx", SearchOption.TopDirectoryOnly)).FirstOrDefault(); } private Process StartSuite() diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SwitchToLocalCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SwitchToLocalCommand.cs index b0889e9557..4837b2b5a0 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SwitchToLocalCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/SwitchToLocalCommand.cs @@ -70,7 +70,7 @@ public class SwitchToLocal : IConsoleCommand, ITransientDependency return null; } - if (path.EndsWith(".sln") || path.EndsWith(".csproj")) + if (path.EndsWith(".sln") || path.EndsWith(".slnx") || path.EndsWith(".csproj")) { return Path.GetDirectoryName(path); } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs index 8c6df3b0b9..d09725cfbf 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs @@ -64,6 +64,7 @@ public class UpdateCommand : IConsoleCommand, ITransientDependency if (givenSolution.IsNullOrWhiteSpace()) { solutions.AddRange(Directory.GetFiles(directory, "*.sln", SearchOption.AllDirectories)); + solutions.AddRange(Directory.GetFiles(directory, "*.slnx", SearchOption.AllDirectories)); } else { @@ -76,7 +77,7 @@ public class UpdateCommand : IConsoleCommand, ITransientDependency { foreach (var solution in solutions) { - var solutionName = Path.GetFileName(solution).RemovePostFix(".sln"); + var solutionName = Path.GetFileName(solution).RemovePostFix(".slnx").RemovePostFix(".sln"); await _nugetPackagesVersionUpdater.UpdateSolutionAsync(solution, checkAll: checkAll, version: version, leptonXVersion: leptonXVersion); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/AppNoLayersMoveProjectsStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/AppNoLayersMoveProjectsStep.cs index e9af25d28a..fc34c8a00d 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/AppNoLayersMoveProjectsStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/AppNoLayersMoveProjectsStep.cs @@ -41,7 +41,7 @@ public class AppNoLayersMoveProjectsStep : ProjectBuildPipelineStep public void ModifySolutionFile(ProjectBuildContext context, string pathInSlnFile, string newPathInSlnFile) { - var slnFile = context.Files.First(file => file.Name.EndsWith(".sln")); + var slnFile = context.Files.First(file => file.Name.EndsWith(".sln") ||file.Name.EndsWith(".slnx")); slnFile.SetContent(slnFile.Content.Replace($"\"{pathInSlnFile}\"", $"\"{newPathInSlnFile}\"")); } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectRenameStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectRenameStep.cs index a109d21f7a..75d24a66f6 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectRenameStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/ProjectRenameStep.cs @@ -24,7 +24,7 @@ public class ProjectRenameStep : ProjectBuildPipelineStep } } - var files = context.Files.Where(f => f.Name.EndsWith(".sln") || f.Name.EndsWith(".cs")); + var files = context.Files.Where(f => f.Name.EndsWith(".sln") || f.Name.EndsWith(".slnx") || f.Name.EndsWith(".cs")); foreach (var file in files) { file.NormalizeLineEndings(); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs index 3866d2c33f..463c8cca58 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs @@ -43,7 +43,7 @@ public class RemoveProjectFromSolutionStep : ProjectBuildPipelineStep private void RemoveProjectFromAbpmdlFile(ProjectBuildContext context) { - var abpmdlFile = context.FindFile(_solutionFilePath.RemovePostFix(".sln") + ".abpmdl"); + var abpmdlFile = context.FindFile(_solutionFilePath.RemovePostFix(".slnx").RemovePostFix(".sln") + ".abpmdl"); if (abpmdlFile == null) { @@ -109,8 +109,11 @@ public class RemoveProjectFromSolutionStep : ProjectBuildPipelineStep if (_solutionFilePath == null) { _solutionFilePath = context.FindFile("/aspnet-core/MyCompanyName.MyProjectName.sln")?.Name ?? + context.FindFile("/aspnet-core/MyCompanyName.MyProjectName.slnx")?.Name ?? context.FindFile("/MyCompanyName.MyProjectName.sln")?.Name ?? - context.FindFile("/MyCompanyName.MyProjectName.MicroserviceName.sln")?.Name; + context.FindFile("/MyCompanyName.MyProjectName.slnx")?.Name ?? + context.FindFile("/MyCompanyName.MyProjectName.MicroserviceName.sln")?.Name ?? + context.FindFile("/MyCompanyName.MyProjectName.MicroserviceName.slnx")?.Name; } if (_projectFolderPath == null) { diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/MicroserviceServiceStringEncryptionStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/MicroserviceServiceStringEncryptionStep.cs index 7e25cb2b96..9ae8e14a8d 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/MicroserviceServiceStringEncryptionStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Templates/MicroserviceServiceStringEncryptionStep.cs @@ -17,7 +17,8 @@ public class MicroserviceServiceStringEncryptionStep : RandomizeStringEncryption var directoryInfo = new DirectoryInfo(context.BuildArgs.OutputFolder); do { - var msSolution = Directory.GetFiles(directoryInfo.FullName, "*.sln", SearchOption.TopDirectoryOnly).FirstOrDefault(); + var msSolution = Directory.GetFiles(directoryInfo.FullName, "*.sln", SearchOption.TopDirectoryOnly) + .Concat(Directory.GetFiles(directoryInfo.FullName, "*.slnx", SearchOption.TopDirectoryOnly)).FirstOrDefault(); if (msSolution != null) { var appSettings = Directory.GetFiles(Path.Combine(directoryInfo.FullName, "apps", "auth-server"), diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackagePreviewSwitcher.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackagePreviewSwitcher.cs index 7cf1d0da7a..13046dae78 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackagePreviewSwitcher.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/PackagePreviewSwitcher.cs @@ -269,7 +269,8 @@ public class PackagePreviewSwitcher : ITransientDependency private List GetSolutionPaths(CommandLineArgs commandLineArgs) { - return Directory.GetFiles(GetDirectory(commandLineArgs), "*.sln", SearchOption.AllDirectories).ToList(); + return Directory.GetFiles(GetDirectory(commandLineArgs), "*.sln", SearchOption.AllDirectories) + .Concat(Directory.GetFiles(GetDirectory(commandLineArgs), "*.slnx", SearchOption.AllDirectories)).ToList(); } private List GetProjectPaths(CommandLineArgs commandLineArgs) @@ -317,7 +318,8 @@ public class PackagePreviewSwitcher : ITransientDependency return Path.GetDirectoryName(projectFile); } - if (Directory.GetFiles(targetFolder, "*.sln", SearchOption.TopDirectoryOnly).Any()) + if (Directory.GetFiles(targetFolder, "*.sln", SearchOption.TopDirectoryOnly) + .Concat(Directory.GetFiles(targetFolder, "*.slnx", SearchOption.TopDirectoryOnly)).Any()) { break; } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNugetPackageAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNugetPackageAdder.cs index 9d9d7e159e..f118892b5a 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNugetPackageAdder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/ProjectNugetPackageAdder.cs @@ -214,7 +214,8 @@ public class ProjectNugetPackageAdder : ITransientDependency { var folder = FindSolutionFolder(projectFile); - return Directory.GetFiles(folder, "*.sln", SearchOption.TopDirectoryOnly).FirstOrDefault(); + return Directory.GetFiles(folder, "*.sln", SearchOption.TopDirectoryOnly) + .Concat(Directory.GetFiles(folder, "*.slnx", SearchOption.TopDirectoryOnly)).FirstOrDefault(); } protected virtual string FindSolutionFolder(string projectFile) @@ -232,7 +233,8 @@ public class ProjectNugetPackageAdder : ITransientDependency return Path.GetDirectoryName(projectFile); } - if (Directory.GetFiles(targetFolder, "*.sln", SearchOption.TopDirectoryOnly).Any()) + if (Directory.GetFiles(targetFolder, "*.sln", SearchOption.TopDirectoryOnly) + .Concat(Directory.GetFiles(targetFolder, "*.slnx", SearchOption.TopDirectoryOnly)).Any()) { break; } diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs index 8a703a8deb..cf2abe3857 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionModuleAdder.cs @@ -335,7 +335,8 @@ public class SolutionModuleAdder : ITransientDependency { var projectsToRemove = new List(); var moduleDirectory = Path.Combine(solutionDirectory, "modules", module.Name); - var moduleSolutionFile = Directory.GetFiles(moduleDirectory, "*.sln", SearchOption.TopDirectoryOnly).First(); + var moduleSolutionFile = Directory.GetFiles(moduleDirectory, "*.sln", SearchOption.TopDirectoryOnly) + .Concat(Directory.GetFiles(moduleDirectory, "*.slnx", SearchOption.TopDirectoryOnly)).First(); var isProjectTiered = await IsProjectTiered(projectFiles); var webPackagesWillBeAddedToBlazorServerProject = false; @@ -609,7 +610,8 @@ public class SolutionModuleAdder : ITransientDependency private async Task DeleteRedundantHostProjects(string targetModuleFolder, string folderName) { - var moduleSolutionFile = Directory.GetFiles(targetModuleFolder, "*.sln", SearchOption.TopDirectoryOnly).First(); + var moduleSolutionFile = Directory.GetFiles(targetModuleFolder, "*.sln", SearchOption.TopDirectoryOnly) + .Concat(Directory.GetFiles(targetModuleFolder, "*.slnx", SearchOption.TopDirectoryOnly)).First(); var folder = Path.Combine(targetModuleFolder, folderName); if (Directory.Exists(folder)) From 7dea62de7936b60d373e4e3d1d6c1fabaffd1f15 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 30 Sep 2025 09:55:55 +0300 Subject: [PATCH 2/9] Cli: Slnx file support (fix errors) --- .../Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs | 2 +- .../Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs index d0229538da..4756c3f99b 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/AddModuleCommand.cs @@ -168,7 +168,7 @@ public class AddModuleCommand : IConsoleCommand, ITransientDependency } var foundSolutionFiles = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.sln") - .Concat(Directory.GetFiles(Directory.GetCurrentDirectory(), "*.sln")).ToList(); + .Concat(Directory.GetFiles(Directory.GetCurrentDirectory(), "*.slnx")).ToList(); if (foundSolutionFiles.Count == 1) { return foundSolutionFiles[0]; diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs index 63c59c2e81..00e0bb0c2c 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs @@ -176,7 +176,7 @@ public abstract class ProjectCreationCommandBase if (slnPath == null) { slnPath = Directory.GetFiles(outputFolderRoot, "*.sln") - .Concat(Directory.GetFiles(outputFolderRoot, "*.sln")).FirstOrDefault(); + .Concat(Directory.GetFiles(outputFolderRoot, "*.slnx")).FirstOrDefault(); } else if (slnPath.EndsWith(".sln") || slnPath.EndsWith(".slnx")) { From d718c2e9523c3cd013c25c00066c3989ec4c7548 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 30 Sep 2025 10:59:59 +0300 Subject: [PATCH 3/9] Made RemoveProjectFromSolutionStep work with slnx files --- .../Steps/RemoveProjectFromSolutionStep.cs | 93 +++++++++++++++---- 1 file changed, 77 insertions(+), 16 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs index 463c8cca58..484b9e991e 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs @@ -1,49 +1,110 @@ using System; using System.Collections.Generic; using System.Linq; -using Newtonsoft.Json; +using System.Xml; using Newtonsoft.Json.Linq; +using Volo.Abp.Cli.ProjectBuilding.Files; +using Formatting = Newtonsoft.Json.Formatting; namespace Volo.Abp.Cli.ProjectBuilding.Building.Steps; public class RemoveProjectFromSolutionStep : ProjectBuildPipelineStep { private readonly string _projectName; - private string _solutionFilePath; + private string _solutionFilePathWithoutFileExtension; private string _projectFolderPath; private string ProjectNameWithQuotes => $"\"{_projectName}\""; public RemoveProjectFromSolutionStep( string projectName, - string solutionFilePath = null, + string solutionFilePathWithoutFileExtension = null, string projectFolderPath = null) { _projectName = projectName; - _solutionFilePath = solutionFilePath; _projectFolderPath = projectFolderPath; + + if (solutionFilePathWithoutFileExtension != null && solutionFilePathWithoutFileExtension.EndsWith(".sln")) + { + _solutionFilePathWithoutFileExtension = solutionFilePathWithoutFileExtension.RemovePostFix(".sln"); + } + else + { + _solutionFilePathWithoutFileExtension = solutionFilePathWithoutFileExtension; + } } public override void Execute(ProjectBuildContext context) { SetSolutionAndProjectPathsIfNull(context); - if (_solutionFilePath == null || _projectFolderPath == null) + if (_solutionFilePathWithoutFileExtension == null || _projectFolderPath == null) { return; } new RemoveFolderStep(_projectFolderPath).Execute(context); - var solutionFile = context.GetFile(_solutionFilePath); - solutionFile.NormalizeLineEndings(); - solutionFile.SetLines(RemoveProject(solutionFile.GetLines().ToList())); + var solutionFile = context.FindFile(_solutionFilePathWithoutFileExtension + ".sln") + ?? context.GetFile(_solutionFilePathWithoutFileExtension + ".slnx"); + + if (solutionFile.Name.EndsWith(".sln")) + { + RemoveProjectFromSlnFile(solutionFile); + } + else + { + RemoveProjectFromSlnxFile(solutionFile); + } RemoveProjectFromAbpmdlFile(context); } + private void RemoveProjectFromSlnxFile(FileEntry solutionFile) + { + var document = new XmlDocument { PreserveWhitespace = true }; + document.LoadXml(solutionFile.Content); + var projectNodes = document.SelectNodes("/Solution/Folder/Project"); + + if (projectNodes == null || projectNodes.Count < 1) + { + return; + } + + var nodesToBeRemoved = new List(); + foreach (XmlNode projectNode in projectNodes) + { + var pathAttr = projectNode.Attributes?["Path"]?.Value; + if (string.IsNullOrWhiteSpace(pathAttr)) + { + continue; + } + + var normalized = pathAttr.Replace('\\', '/'); + var fileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(normalized); + + if (string.Equals(fileNameWithoutExtension, _projectName, StringComparison.OrdinalIgnoreCase)) + { + nodesToBeRemoved.Add(projectNode); + } + } + + foreach (var node in nodesToBeRemoved) + { + node.ParentNode!.RemoveChild(node); + } + + solutionFile.SetContent(document.OuterXml); + } + + private void RemoveProjectFromSlnFile(FileEntry solutionFile) + { + solutionFile.NormalizeLineEndings(); + solutionFile.SetLines(RemoveProject(solutionFile.GetLines().ToList())); + } + private void RemoveProjectFromAbpmdlFile(ProjectBuildContext context) { - var abpmdlFile = context.FindFile(_solutionFilePath.RemovePostFix(".slnx").RemovePostFix(".sln") + ".abpmdl"); + var abpmdlFile = context.FindFile(_solutionFilePathWithoutFileExtension + ".abpmdl"); if (abpmdlFile == null) { @@ -106,14 +167,14 @@ public class RemoveProjectFromSolutionStep : ProjectBuildPipelineStep private void SetSolutionAndProjectPathsIfNull(ProjectBuildContext context) { - if (_solutionFilePath == null) + if (_solutionFilePathWithoutFileExtension == null) { - _solutionFilePath = context.FindFile("/aspnet-core/MyCompanyName.MyProjectName.sln")?.Name ?? - context.FindFile("/aspnet-core/MyCompanyName.MyProjectName.slnx")?.Name ?? - context.FindFile("/MyCompanyName.MyProjectName.sln")?.Name ?? - context.FindFile("/MyCompanyName.MyProjectName.slnx")?.Name ?? - context.FindFile("/MyCompanyName.MyProjectName.MicroserviceName.sln")?.Name ?? - context.FindFile("/MyCompanyName.MyProjectName.MicroserviceName.slnx")?.Name; + _solutionFilePathWithoutFileExtension = context.FindFile("/aspnet-core/MyCompanyName.MyProjectName.sln")?.Name.RemovePostFix(".sln") ?? + context.FindFile("/aspnet-core/MyCompanyName.MyProjectName.slnx")?.Name.RemovePostFix(".slnx") ?? + context.FindFile("/MyCompanyName.MyProjectName.sln")?.Name.RemovePostFix(".sln") ?? + context.FindFile("/MyCompanyName.MyProjectName.slnx")?.Name.RemovePostFix(".slnx") ?? + context.FindFile("/MyCompanyName.MyProjectName.MicroserviceName.sln")?.Name.RemovePostFix(".sln") ?? + context.FindFile("/MyCompanyName.MyProjectName.MicroserviceName.slnx")?.Name.RemovePostFix(".slnx"); } if (_projectFolderPath == null) { From 09344cb6ff1e85f49a302f9c9e4df505f9709aac Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 30 Sep 2025 11:10:51 +0300 Subject: [PATCH 4/9] Made SolutionFileModifier work with slnx files --- .../Steps/RemoveProjectFromSolutionStep.cs | 3 +- .../SolutionFileModifier.cs | 77 ++++++++++++++++--- 2 files changed, 69 insertions(+), 11 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs index 484b9e991e..3f3046a584 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Xml; using Newtonsoft.Json.Linq; @@ -80,7 +81,7 @@ public class RemoveProjectFromSolutionStep : ProjectBuildPipelineStep } var normalized = pathAttr.Replace('\\', '/'); - var fileNameWithoutExtension = System.IO.Path.GetFileNameWithoutExtension(normalized); + var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(normalized); if (string.Equals(fileNameWithoutExtension, _projectName, StringComparison.OrdinalIgnoreCase)) { diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionFileModifier.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionFileModifier.cs index b1678eaca9..85abe40195 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionFileModifier.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionFileModifier.cs @@ -4,15 +4,82 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using System.Xml; +using Volo.Abp.Cli.Utils; using Volo.Abp.DependencyInjection; namespace Volo.Abp.Cli.ProjectModification; public class SolutionFileModifier : ITransientDependency { + private readonly ICmdHelper _cmdHelper; public static Encoding DefaultEncoding = Encoding.UTF8; + public SolutionFileModifier(ICmdHelper cmdHelper) + { + _cmdHelper = cmdHelper; + } + public async Task RemoveProjectFromSolutionFileAsync(string solutionFile, string projectName) + { + if (solutionFile.EndsWith(".sln")) + { + await RemoveProjectFromSlnFileAsync(solutionFile, projectName); + } + else + { + await RemoveProjectFromSlnxFileAsync(solutionFile, projectName); + } + } + + public async Task AddModuleToSolutionFileAsync(ModuleWithMastersInfo module, string solutionFile) + { + await AddModuleAsync(module, solutionFile); + } + + public async Task AddPackageToSolutionFileAsync(NugetPackageInfo package, string solutionFile) + { + await AddPackageAsync(package, solutionFile); + } + + private async Task RemoveProjectFromSlnxFileAsync(string solutionFile, string projectName) + { + var document = new XmlDocument { PreserveWhitespace = true }; + document.Load(solutionFile); + var projectNodes = document.SelectNodes("/Solution/Folder/Project"); + + if (projectNodes == null || projectNodes.Count < 1) + { + return; + } + + var nodesToBeRemoved = new List(); + foreach (XmlNode projectNode in projectNodes) + { + var pathAttr = projectNode.Attributes?["Path"]?.Value; + if (string.IsNullOrWhiteSpace(pathAttr)) + { + continue; + } + + var normalized = pathAttr.Replace('\\', '/'); + var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(normalized); + + if (string.Equals(fileNameWithoutExtension, projectName, StringComparison.OrdinalIgnoreCase)) + { + nodesToBeRemoved.Add(projectNode); + } + } + + foreach (var node in nodesToBeRemoved) + { + node.ParentNode!.RemoveChild(node); + } + + await File.WriteAllTextAsync(solutionFile, document.OuterXml); + } + + private async Task RemoveProjectFromSlnFileAsync(string solutionFile, string projectName) { using (var fileStream = File.Open(solutionFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { @@ -36,16 +103,6 @@ public class SolutionFileModifier : ITransientDependency } } - public async Task AddModuleToSolutionFileAsync(ModuleWithMastersInfo module, string solutionFile) - { - await AddModuleAsync(module, solutionFile); - } - - public async Task AddPackageToSolutionFileAsync(NugetPackageInfo package, string solutionFile) - { - await AddPackageAsync(package, solutionFile); - } - private async Task AddPackageAsync(NugetPackageInfo package, string solutionFile) { var srcFolderId = await AddNewFolderAndGetIdOrGetExistingIdAsync(solutionFile, "src"); From d2e25cd5d1da81678482696fce8e9aeddfb80947 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 30 Sep 2025 11:27:06 +0300 Subject: [PATCH 5/9] Made SolutionFileModifier work with slnx files cont. --- .../SolutionFileModifier.cs | 247 ++---------------- 1 file changed, 16 insertions(+), 231 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionFileModifier.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionFileModifier.cs index 85abe40195..52f0ffdd20 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionFileModifier.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionFileModifier.cs @@ -13,7 +13,6 @@ namespace Volo.Abp.Cli.ProjectModification; public class SolutionFileModifier : ITransientDependency { private readonly ICmdHelper _cmdHelper; - public static Encoding DefaultEncoding = Encoding.UTF8; public SolutionFileModifier(ICmdHelper cmdHelper) { @@ -22,13 +21,15 @@ public class SolutionFileModifier : ITransientDependency public async Task RemoveProjectFromSolutionFileAsync(string solutionFile, string projectName) { - if (solutionFile.EndsWith(".sln")) - { - await RemoveProjectFromSlnFileAsync(solutionFile, projectName); - } - else + var list = _cmdHelper.RunCmdAndGetOutput($"dotnet sln {solutionFile} list"); + + foreach (var line in list.Split(new[] { Environment.NewLine, "\n" }, StringSplitOptions.None)) { - await RemoveProjectFromSlnxFileAsync(solutionFile, projectName); + if (Path.GetFileNameWithoutExtension(line.Trim()).Equals(projectName, StringComparison.InvariantCultureIgnoreCase)) + { + _cmdHelper.RunCmd($"dotnet sln {solutionFile} remove {line.Trim()}"); + break; + } } } @@ -42,168 +43,18 @@ public class SolutionFileModifier : ITransientDependency await AddPackageAsync(package, solutionFile); } - private async Task RemoveProjectFromSlnxFileAsync(string solutionFile, string projectName) - { - var document = new XmlDocument { PreserveWhitespace = true }; - document.Load(solutionFile); - var projectNodes = document.SelectNodes("/Solution/Folder/Project"); - - if (projectNodes == null || projectNodes.Count < 1) - { - return; - } - - var nodesToBeRemoved = new List(); - foreach (XmlNode projectNode in projectNodes) - { - var pathAttr = projectNode.Attributes?["Path"]?.Value; - if (string.IsNullOrWhiteSpace(pathAttr)) - { - continue; - } - - var normalized = pathAttr.Replace('\\', '/'); - var fileNameWithoutExtension = Path.GetFileNameWithoutExtension(normalized); - - if (string.Equals(fileNameWithoutExtension, projectName, StringComparison.OrdinalIgnoreCase)) - { - nodesToBeRemoved.Add(projectNode); - } - } - - foreach (var node in nodesToBeRemoved) - { - node.ParentNode!.RemoveChild(node); - } - - await File.WriteAllTextAsync(solutionFile, document.OuterXml); - } - - private async Task RemoveProjectFromSlnFileAsync(string solutionFile, string projectName) - { - using (var fileStream = File.Open(solutionFile, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) - { - using (var sr = new StreamReader(fileStream, Encoding.Default, true)) - { - var solutionFileContent = await sr.ReadToEndAsync(); - solutionFileContent.NormalizeLineEndings(); - - var lines = solutionFileContent.Split(new[] { Environment.NewLine, "\n" }, StringSplitOptions.None); - var updatedContent = RemoveProject(lines.ToList(), projectName).JoinAsString(Environment.NewLine); - - fileStream.Seek(0, SeekOrigin.Begin); - fileStream.SetLength(0); - - using (var sw = new StreamWriter(fileStream, DefaultEncoding)) - { - await sw.WriteAsync(updatedContent); - await sw.FlushAsync(); - } - } - } - } - private async Task AddPackageAsync(NugetPackageInfo package, string solutionFile) { - var srcFolderId = await AddNewFolderAndGetIdOrGetExistingIdAsync(solutionFile, "src"); - - var solutionFileContent = File.ReadAllText(solutionFile); - var lines = solutionFileContent.Split(new[] { Environment.NewLine, "\n" }, StringSplitOptions.None).ToList(); - - if (lines.Any(l => l.Contains($"\"{package.Name}\""))) - { - return; - } - - var projectGuid = Guid.NewGuid().ToString(); - - var newProjectLine = "Project(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"" + package.Name + "\"," + - " \"packages\\" + package.Name + "\\" + - "\\" + package.Name + ".csproj\", \"{" + projectGuid + "}\"" - + Environment.NewLine + "EndProject"; - - lines.InsertAfter(l => l.Trim().Equals("EndProject"), newProjectLine); - - var newPostSolutionLine = - " {" + projectGuid + "}.Debug|Any CPU.ActiveCfg = Debug|Any CPU" + Environment.NewLine + - " {" + projectGuid + "}.Debug|Any CPU.Build.0 = Debug|Any CPU" + Environment.NewLine + - " {" + projectGuid + "}.Release|Any CPU.ActiveCfg = Release|Any CPU" + Environment.NewLine + - " {" + projectGuid + "}.Release|Any CPU.Build.0 = Release|Any CPU"; - - lines.InsertAfter(l => l.Contains("GlobalSection") && l.Contains("ProjectConfigurationPlatforms"), - newPostSolutionLine); - - var newPreSolutionLine = - " {" + projectGuid + "} = {" + srcFolderId + "}"; - - lines.InsertAfter(l => l.Contains("GlobalSection") && l.Contains("NestedProjects"), newPreSolutionLine); - - File.WriteAllText(solutionFile, string.Join(Environment.NewLine, lines), DefaultEncoding); - } - - private List RemoveProject(List solutionFileLines, string projectName) - { - var projectKey = FindProjectKey(solutionFileLines, projectName); - - if (projectKey == null) - { - return solutionFileLines; - } - - var newSolutionFileLines = new List(); - var firstOccurence = true; - - for (var i = 0; i < solutionFileLines.Count; ++i) - { - if (solutionFileLines[i].Contains(projectKey)) - { - if (firstOccurence) - { - firstOccurence = false; - ++i; //Skip "EndProject" line too. - } - - continue; - } - - newSolutionFileLines.Add(solutionFileLines[i]); - } - - return newSolutionFileLines; - } - - private string FindProjectKey(List solutionFileLines, string projectName) - { - var projectNameWithQuotes = $"\"{projectName}\""; - foreach (var solutionFileLine in solutionFileLines) - { - if (solutionFileLine.Contains(projectNameWithQuotes)) - { - var curlyBracketStartIndex = solutionFileLine.LastIndexOf("{", StringComparison.OrdinalIgnoreCase); - var curlyBracketEndIndex = solutionFileLine.LastIndexOf("}", StringComparison.OrdinalIgnoreCase); - return solutionFileLine.Substring(curlyBracketStartIndex + 1, - curlyBracketEndIndex - curlyBracketStartIndex - 1); - } - } - - return null; + _cmdHelper.RunCmd($"dotnet sln {solutionFile} add packages\\{package.Name}\\{package.Name}.csproj --solution-folder src"); } private async Task AddModuleAsync(ModuleWithMastersInfo module, string solutionFile) { - var srcModuleFolderId = await AddNewFolderAndGetIdOrGetExistingIdAsync(solutionFile, module.Name, - await AddNewFolderAndGetIdOrGetExistingIdAsync(solutionFile, "modules")); - var testModuleFolderId = await AddNewFolderAndGetIdOrGetExistingIdAsync(solutionFile, module.Name + ".Tests", - await AddNewFolderAndGetIdOrGetExistingIdAsync(solutionFile, "test")); - - var file = File.ReadAllText(solutionFile); - var lines = file.Split(new[] { Environment.NewLine, "\n" }, StringSplitOptions.None).ToList(); - var projectsUnderModule = Directory.GetFiles( Path.Combine(Path.GetDirectoryName(solutionFile), "modules", module.Name), "*.csproj", SearchOption.AllDirectories); - + var projectsUnderTest = new List(); if (Directory.Exists(Path.Combine(Path.GetDirectoryName(solutionFile), "modules", module.Name, "test"))) { @@ -215,41 +66,14 @@ public class SolutionFileModifier : ITransientDependency foreach (var projectPath in projectsUnderModule) { - var parentFolderId = projectsUnderTest.Contains(projectPath) ? testModuleFolderId : srcModuleFolderId; - var projectId = Path.GetFileName(projectPath).Replace(".csproj", ""); - var projectParentFolderInModule = projectsUnderTest.Contains(projectPath) ? "test" : "src"; - - if (lines.Any(l => l.Contains($"\"{projectId}\""))) - { - continue; - } - - var projectGuid = Guid.NewGuid().ToString(); + var folder = projectsUnderTest.Contains(projectPath) ? "test" : "src"; - var newProjectLine = "Project(\"{9A19103F-16F7-4668-BE54-9A1E7A4F7556}\") = \"" + projectId + "\"," + - " \"modules\\" + module.Name + "\\" + projectParentFolderInModule + "\\" + - projectId + "\\" + projectId + ".csproj\", \"{" + projectGuid + "}\"" - + Environment.NewLine + "EndProject"; - - lines.InsertAfter(l => l.Trim().Equals("EndProject"), newProjectLine); - - var newPostSolutionLine = - " {" + projectGuid + "}.Debug|Any CPU.ActiveCfg = Debug|Any CPU" + Environment.NewLine + - " {" + projectGuid + "}.Debug|Any CPU.Build.0 = Debug|Any CPU" + Environment.NewLine + - " {" + projectGuid + "}.Release|Any CPU.ActiveCfg = Release|Any CPU" + Environment.NewLine + - " {" + projectGuid + "}.Release|Any CPU.Build.0 = Release|Any CPU"; - - lines.InsertAfter(l => l.Contains("GlobalSection") && l.Contains("ProjectConfigurationPlatforms"), - newPostSolutionLine); - - var newPreSolutionLine = - " {" + projectGuid + "} = {" + parentFolderId + "}"; - - lines.InsertAfter(l => l.Contains("GlobalSection") && l.Contains("NestedProjects"), newPreSolutionLine); + var projectId = Path.GetFileName(projectPath).Replace(".csproj", ""); + var package = @$"modules\{module.Name}\{folder}\{projectId}\{projectId}.csproj"; + + _cmdHelper.RunCmd($"dotnet sln {solutionFile} add {package} --solution-folder {folder}"); } - - File.WriteAllText(solutionFile, string.Join(Environment.NewLine, lines), Encoding.UTF8); - + if (module.MasterModuleInfos != null) { foreach (var masterModule in module.MasterModuleInfos) @@ -258,43 +82,4 @@ public class SolutionFileModifier : ITransientDependency } } } - - private async Task AddNewFolderAndGetIdOrGetExistingIdAsync(string solutionFile, string folderName, - string parentFolderId = null) - { - var file = File.ReadAllText(solutionFile); - var lines = file.Split(new[] { Environment.NewLine, "\n" }, StringSplitOptions.None).ToList(); - string folderId; - - var folderLineIndex = lines.FindIndex(l => - l.Contains("2150E333-8FDC-42A3-9474-1A3956D46DE8") && l.Contains("\"" + folderName + "\"")); - - if (folderLineIndex < 0) - { - folderId = Guid.NewGuid().ToString(); - var newFolderLine = "Project(\"{2150E333-8FDC-42A3-9474-1A3956D46DE8}\") = \"" + folderName + "\", \"" + - folderName + "\", \"{" + folderId + "}\"" - + Environment.NewLine + "EndProject"; - - lines.InsertAfter(l => l.Trim().Equals("EndProject"), newFolderLine); - - if (parentFolderId != null) - { - var newPreSolutionLine = - " {" + folderId + "} = {" + parentFolderId + "}"; - - lines.InsertAfter(l => l.Contains("GlobalSection") && l.Contains("NestedProjects"), - newPreSolutionLine); - } - } - else - { - folderId = lines[folderLineIndex].Replace("\"", " ").Replace("{", " ").Replace("}", " ").TrimEnd() - .Split(" ").Last(); - } - - File.WriteAllText(solutionFile, string.Join(Environment.NewLine, lines), Encoding.UTF8); - - return folderId; - } } From 96c0e22ff37dbeb7a55a02d9b0ea8e0daf9701f4 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 30 Sep 2025 13:16:30 +0300 Subject: [PATCH 6/9] Update SolutionFileModifier.cs --- .../Abp/Cli/ProjectModification/SolutionFileModifier.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionFileModifier.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionFileModifier.cs index 52f0ffdd20..7a815df81d 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionFileModifier.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectModification/SolutionFileModifier.cs @@ -21,13 +21,13 @@ public class SolutionFileModifier : ITransientDependency public async Task RemoveProjectFromSolutionFileAsync(string solutionFile, string projectName) { - var list = _cmdHelper.RunCmdAndGetOutput($"dotnet sln {solutionFile} list"); + var list = _cmdHelper.RunCmdAndGetOutput($"dotnet sln \"{solutionFile}\" list"); foreach (var line in list.Split(new[] { Environment.NewLine, "\n" }, StringSplitOptions.None)) { if (Path.GetFileNameWithoutExtension(line.Trim()).Equals(projectName, StringComparison.InvariantCultureIgnoreCase)) { - _cmdHelper.RunCmd($"dotnet sln {solutionFile} remove {line.Trim()}"); + _cmdHelper.RunCmd($"dotnet sln \"{solutionFile}\" remove \"{line.Trim()}\""); break; } } @@ -45,7 +45,7 @@ public class SolutionFileModifier : ITransientDependency private async Task AddPackageAsync(NugetPackageInfo package, string solutionFile) { - _cmdHelper.RunCmd($"dotnet sln {solutionFile} add packages\\{package.Name}\\{package.Name}.csproj --solution-folder src"); + _cmdHelper.RunCmd($"dotnet sln \"{solutionFile}\" add \"packages\\{package.Name}\\{package.Name}.csproj\" --solution-folder src"); } private async Task AddModuleAsync(ModuleWithMastersInfo module, string solutionFile) @@ -71,7 +71,7 @@ public class SolutionFileModifier : ITransientDependency var projectId = Path.GetFileName(projectPath).Replace(".csproj", ""); var package = @$"modules\{module.Name}\{folder}\{projectId}\{projectId}.csproj"; - _cmdHelper.RunCmd($"dotnet sln {solutionFile} add {package} --solution-folder {folder}"); + _cmdHelper.RunCmd($"dotnet sln \"{solutionFile}\" add \"{package}\" --solution-folder {folder}"); } if (module.MasterModuleInfos != null) From 4c4ed27356507874f97ba0a390d0a7f597d864a4 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Tue, 30 Sep 2025 13:23:30 +0300 Subject: [PATCH 7/9] refactor --- .../Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs | 2 +- .../Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs | 2 +- .../Building/Steps/RemoveProjectFromSolutionStep.cs | 5 +++++ 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs index 00e0bb0c2c..51ade9be0c 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/ProjectCreationCommandBase.cs @@ -200,7 +200,7 @@ public abstract class ProjectCreationCommandBase throw new CliUsageException($"This command should be run inside a folder that contains a microservice solution! Or use -{Options.MainSolution.Short} parameter."); } - var microserviceSolutionName = Path.GetFileName(slnPath).RemovePostFix(".slnx").RemovePostFix(".sln"); + var microserviceSolutionName = Path.GetFileName(slnPath).RemovePostFix(".slnx", ".sln"); version ??= SolutionPackageVersionFinder.FindByCsprojVersion(slnPath); solutionName = SolutionName.Parse(microserviceSolutionName, projectName); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs index d09725cfbf..ae3cda8723 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/Commands/UpdateCommand.cs @@ -77,7 +77,7 @@ public class UpdateCommand : IConsoleCommand, ITransientDependency { foreach (var solution in solutions) { - var solutionName = Path.GetFileName(solution).RemovePostFix(".slnx").RemovePostFix(".sln"); + var solutionName = Path.GetFileName(solution).RemovePostFix(".slnx", ".sln"); await _nugetPackagesVersionUpdater.UpdateSolutionAsync(solution, checkAll: checkAll, version: version, leptonXVersion: leptonXVersion); diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs index 3f3046a584..043693a75b 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs @@ -29,6 +29,11 @@ public class RemoveProjectFromSolutionStep : ProjectBuildPipelineStep { _solutionFilePathWithoutFileExtension = solutionFilePathWithoutFileExtension.RemovePostFix(".sln"); } + + if (solutionFilePathWithoutFileExtension != null && solutionFilePathWithoutFileExtension.EndsWith(".slnx")) + { + _solutionFilePathWithoutFileExtension = solutionFilePathWithoutFileExtension.RemovePostFix(".slnx"); + } else { _solutionFilePathWithoutFileExtension = solutionFilePathWithoutFileExtension; From 0cbdc8c86b747ae2416d1d0b0b52d34e710d60de Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 1 Oct 2025 13:14:04 +0300 Subject: [PATCH 8/9] Update RemoveProjectFromSolutionStep.cs --- .../Building/Steps/RemoveProjectFromSolutionStep.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs index 043693a75b..4bc12a98ab 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs @@ -69,7 +69,7 @@ public class RemoveProjectFromSolutionStep : ProjectBuildPipelineStep { var document = new XmlDocument { PreserveWhitespace = true }; document.LoadXml(solutionFile.Content); - var projectNodes = document.SelectNodes("/Solution/Folder/Project"); + var projectNodes = document.SelectNodes("//Project"); if (projectNodes == null || projectNodes.Count < 1) { From 2d2196ce0ed79dcf8ae2d99dad5beece8771b114 Mon Sep 17 00:00:00 2001 From: Yunus Emre Kalkan Date: Wed, 1 Oct 2025 16:02:14 +0300 Subject: [PATCH 9/9] Update RemoveProjectFromSolutionStep.cs --- .../Building/Steps/RemoveProjectFromSolutionStep.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs index 4bc12a98ab..0e22d62480 100644 --- a/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs +++ b/framework/src/Volo.Abp.Cli.Core/Volo/Abp/Cli/ProjectBuilding/Building/Steps/RemoveProjectFromSolutionStep.cs @@ -99,7 +99,11 @@ public class RemoveProjectFromSolutionStep : ProjectBuildPipelineStep node.ParentNode!.RemoveChild(node); } - solutionFile.SetContent(document.OuterXml); + solutionFile.SetContent( + document.OuterXml + .SplitToLines() + .Where(x=> !x.Trim().Equals(string.Empty)) + .JoinAsString(Environment.NewLine)); } private void RemoveProjectFromSlnFile(FileEntry solutionFile)