2a6f5f81b7
1. 新增`ms`微服务模板,包含共享项目、微服务、网关、应用等完整架构 2. 为`hua new`命令添加`ms`模板选项并更新文档 3. 将模板文件嵌入CLI项目输出目录 4. 实现微服务模板的项目构建逻辑,自动安装并使用dotnet自定义模板创建项目
130 lines
4.0 KiB
C#
130 lines
4.0 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Reflection;
|
|
using System.Threading.Tasks;
|
|
using Volo.Abp.Cli.ProjectBuilding.Building;
|
|
using Volo.Abp.Cli.Utils;
|
|
using Volo.Abp.DependencyInjection;
|
|
|
|
namespace Volo.Abp.Cli.ProjectBuilding;
|
|
|
|
public class TemplateProjectBuilder : ITransientDependency
|
|
{
|
|
protected ISourceCodeStore SourceCodeStore { get; }
|
|
protected TemplateProjectBuildPipelineBuilder PipelineBuilder { get; }
|
|
protected ICmdHelper CmdHelper { get; }
|
|
|
|
public TemplateProjectBuilder(
|
|
ISourceCodeStore sourceCodeStore,
|
|
TemplateProjectBuildPipelineBuilder pipelineBuilder,
|
|
ICmdHelper cmdHelper)
|
|
{
|
|
SourceCodeStore = sourceCodeStore;
|
|
PipelineBuilder = pipelineBuilder;
|
|
CmdHelper = cmdHelper;
|
|
}
|
|
|
|
public async Task BuildAsync(ProjectBuildArgs args)
|
|
{
|
|
if (args.DryRun)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (args.Template.Name == "ms")
|
|
{
|
|
await BuildMicroserviceAsync(args);
|
|
return;
|
|
}
|
|
|
|
var templatePath = await SourceCodeStore.GetAsync(
|
|
args.Template.Name, args.Version);
|
|
|
|
var context = new ProjectBuildContext(
|
|
args.ProjectName,
|
|
args.Template.Name,
|
|
args.Version,
|
|
args.OutputDirectory,
|
|
args.DatabaseProvider,
|
|
args.UiFramework,
|
|
args.ConnectionString,
|
|
args.CreateSolutionFolder,
|
|
args.NoRandomPort,
|
|
templatePath);
|
|
|
|
var pipeline = PipelineBuilder.Build(context);
|
|
await pipeline.ExecuteAsync();
|
|
}
|
|
|
|
private async Task BuildMicroserviceAsync(ProjectBuildArgs args)
|
|
{
|
|
var templateDir = ResolveTemplateDirectory();
|
|
|
|
if (!Directory.Exists(templateDir))
|
|
{
|
|
throw new FileNotFoundException(
|
|
$"Microservice template not found at: {templateDir}. " +
|
|
"Ensure the 'templates/ms' directory exists alongside the tool.");
|
|
}
|
|
|
|
// Install the template
|
|
var installResult = await CmdHelper.RunAsync($"dotnet new install \"{templateDir}\"");
|
|
if (!installResult.IsSuccess)
|
|
{
|
|
throw new InvalidOperationException(
|
|
$"Failed to install microservice template: {installResult.Error}");
|
|
}
|
|
|
|
try
|
|
{
|
|
// Run dotnet new with the template
|
|
var outputDir = args.OutputDirectory;
|
|
var projectName = args.ProjectName;
|
|
|
|
var newResult = await CmdHelper.RunAsync(
|
|
$"dotnet new hua-ms -n \"{projectName}\" -o \"{outputDir}\"");
|
|
|
|
if (!newResult.IsSuccess)
|
|
{
|
|
throw new InvalidOperationException(
|
|
$"Failed to create project: {newResult.Error}");
|
|
}
|
|
}
|
|
finally
|
|
{
|
|
// Uninstall the template to clean up
|
|
await CmdHelper.RunAsync($"dotnet new uninstall \"{templateDir}\"");
|
|
}
|
|
}
|
|
|
|
private static string ResolveTemplateDirectory()
|
|
{
|
|
var assemblyDir = Path.GetDirectoryName(
|
|
Assembly.GetExecutingAssembly().Location) ?? ".";
|
|
|
|
// First, check relative to the assembly directory (works for published output
|
|
// where templates/ms is copied alongside the assembly via CopyToOutputDirectory)
|
|
var assemblyRelativePath = Path.Combine(assemblyDir, "templates", "ms");
|
|
if (Directory.Exists(assemblyRelativePath))
|
|
{
|
|
return assemblyRelativePath;
|
|
}
|
|
|
|
// Fall back to upward traversal (works in development when templates/ms
|
|
// lives in the repository root above bin/Debug/net9.0)
|
|
var directory = new DirectoryInfo(assemblyDir);
|
|
while (directory != null)
|
|
{
|
|
var templatePath = Path.Combine(directory.FullName, "templates", "ms");
|
|
if (Directory.Exists(templatePath))
|
|
{
|
|
return templatePath;
|
|
}
|
|
|
|
directory = directory.Parent;
|
|
}
|
|
|
|
return assemblyRelativePath;
|
|
}
|
|
}
|