Refactored FullyQualifiedName functionality
This commit is contained in:
parent
02a82589ae
commit
be6b3691b4
@ -20,7 +20,7 @@ public class CrudRouterGenerator
|
||||
"",
|
||||
"@router.get(\"/\")",
|
||||
"async def list(",
|
||||
"\tservice: Annotated[%service_class_name%, Depends(%service_class_name%)]",
|
||||
"\tservice: Annotated[%service_class_name%, Depends()]",
|
||||
"):",
|
||||
"\ttry:",
|
||||
"\t\tresult = await service.list()",
|
||||
@ -32,7 +32,7 @@ public class CrudRouterGenerator
|
||||
"@router.get(\"/{id}\")",
|
||||
"async def get_by_id(",
|
||||
"\tid: int,",
|
||||
"\tservice: Annotated[%service_class_name%, Depends(%service_class_name%)]",
|
||||
"\tservice: Annotated[%service_class_name%, Depends()]",
|
||||
"):",
|
||||
"\ttry:",
|
||||
"\t\tresult = await service.get_by_id(id)",
|
||||
@ -44,7 +44,7 @@ public class CrudRouterGenerator
|
||||
"@router.post(\"/\")",
|
||||
"async def create(",
|
||||
"\trequest: Create%entity_class_name%Request,",
|
||||
"\tservice: Annotated[%service_class_name%, Depends(%service_class_name%)]",
|
||||
"\tservice: Annotated[%service_class_name%, Depends()]",
|
||||
"):",
|
||||
"\ttry:",
|
||||
"\t\tawait service.create(request.model_dump())",
|
||||
@ -57,7 +57,7 @@ public class CrudRouterGenerator
|
||||
"async def update(",
|
||||
"\tid: int,",
|
||||
"\trequest: Update%entity_class_name%Request,",
|
||||
"\tservice: Annotated[%service_class_name%, Depends(%service_class_name%)]",
|
||||
"\tservice: Annotated[%service_class_name%, Depends()]",
|
||||
"):",
|
||||
"\ttry:",
|
||||
"\t\tupdated = await service.update(id, request.model_dump(exclude_unset=True))",
|
||||
@ -69,7 +69,7 @@ public class CrudRouterGenerator
|
||||
"@router.delete(\"/{id}\")",
|
||||
"async def delete(",
|
||||
"\tid: int,",
|
||||
"\tservice: Annotated[%service_class_name%, Depends(%service_class_name%)]",
|
||||
"\tservice: Annotated[%service_class_name%, Depends()]",
|
||||
"):",
|
||||
"\ttry:",
|
||||
"\t\tdeleted = await service.delete(id)",
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Humanizer;
|
||||
using MycroForge.CLI.Commands;
|
||||
using MycroForge.Core;
|
||||
|
||||
namespace MycroForge.CLI.CodeGen;
|
||||
@ -143,16 +144,14 @@ public partial class EntityLinker
|
||||
|
||||
private async Task<EntityModel> LoadEntity(string name)
|
||||
{
|
||||
var fqn = new FullyQualifiedName(name);
|
||||
var path = $"{Features.Db.FeatureName}/entities";
|
||||
|
||||
if (name.Split(':').Select(s => s.Trim()).ToArray() is { Length: 2 } fullName)
|
||||
{
|
||||
path = Path.Combine(path, fullName[0]);
|
||||
name = fullName[1];
|
||||
}
|
||||
if (fqn.HasPath)
|
||||
path = Path.Combine(path, fqn.Path);
|
||||
|
||||
path = Path.Combine(path, $"{name.Underscore().ToLower()}.py");
|
||||
var entity = new EntityModel(name, path, await _context.ReadFile(path));
|
||||
path = Path.Combine(path, $"{fqn.SnakeCasedName}.py");
|
||||
var entity = new EntityModel(fqn.PascalizedName, path, await _context.ReadFile(path));
|
||||
entity.Initialize();
|
||||
return entity;
|
||||
}
|
||||
|
28
MycroForge.CLI/Commands/FullyQualifiedName.cs
Normal file
28
MycroForge.CLI/Commands/FullyQualifiedName.cs
Normal file
@ -0,0 +1,28 @@
|
||||
using Humanizer;
|
||||
|
||||
namespace MycroForge.CLI.Commands;
|
||||
|
||||
public class FullyQualifiedName
|
||||
{
|
||||
public string Path { get; }
|
||||
public string PascalizedName { get; }
|
||||
public string SnakeCasedName { get; }
|
||||
|
||||
public bool HasPath => Path.Length > 0;
|
||||
|
||||
|
||||
public FullyQualifiedName(string name)
|
||||
{
|
||||
var path = string.Empty;
|
||||
|
||||
if (name.Split(':').Select(s => s.Trim()).ToArray() is { Length: 2 } fullName)
|
||||
{
|
||||
path = fullName[0];
|
||||
name = fullName[1];
|
||||
}
|
||||
|
||||
Path = path;
|
||||
PascalizedName = name.Pascalize();
|
||||
SnakeCasedName = name.Underscore().ToLower();
|
||||
}
|
||||
}
|
@ -28,17 +28,12 @@ public partial class MycroForge
|
||||
|
||||
private async Task ExecuteAsync(string entity)
|
||||
{
|
||||
var path = string.Empty;
|
||||
if (entity.Split(':').Select(s => s.Trim()).ToArray() is { Length: 2 } fullName)
|
||||
{
|
||||
path = fullName[0];
|
||||
entity = fullName[1];
|
||||
}
|
||||
var fqn = new FullyQualifiedName(entity);
|
||||
|
||||
await new CrudServiceGenerator(_context).Generate(path, entity);
|
||||
await new RequestClassGenerator(_context).Generate(path, entity, RequestClassGenerator.Type.Create);
|
||||
await new RequestClassGenerator(_context).Generate(path, entity, RequestClassGenerator.Type.Update);
|
||||
await new CrudRouterGenerator(_context).Generate(path, entity);
|
||||
await new CrudServiceGenerator(_context).Generate(fqn.Path, fqn.PascalizedName);
|
||||
await new RequestClassGenerator(_context).Generate(fqn.Path, fqn.PascalizedName, RequestClassGenerator.Type.Create);
|
||||
await new RequestClassGenerator(_context).Generate(fqn.Path, fqn.PascalizedName, RequestClassGenerator.Type.Update);
|
||||
await new CrudRouterGenerator(_context).Generate(fqn.Path, fqn.PascalizedName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
using System.CommandLine;
|
||||
using Humanizer;
|
||||
using MycroForge.CLI.CodeGen;
|
||||
using MycroForge.Core.Contract;
|
||||
using MycroForge.CLI.Extensions;
|
||||
using MycroForge.Core;
|
||||
@ -42,30 +43,31 @@ public partial class MycroForge
|
||||
|
||||
private async Task ExecuteAsync(string name)
|
||||
{
|
||||
var fqn = new FullyQualifiedName(name);
|
||||
var folderPath = $"{Features.Api.FeatureName}/routers";
|
||||
|
||||
_context.AssertDirectoryExists(folderPath);
|
||||
|
||||
if (name.FullyQualifiedName() is { Length: 2 } fullName)
|
||||
{
|
||||
folderPath = Path.Combine(folderPath, fullName[0]);
|
||||
name = fullName[1];
|
||||
}
|
||||
|
||||
var moduleImportPath = folderPath.Replace('\\', '.').Replace('/', '.');
|
||||
var moduleName = name.Underscore().ToLower();
|
||||
var fileName = $"{moduleName}.py";
|
||||
if (fqn.HasPath)
|
||||
folderPath = Path.Combine(folderPath, fqn.Path);
|
||||
|
||||
var fileName = $"{fqn.SnakeCasedName}.py";
|
||||
var filePath = Path.Combine(folderPath, fileName);
|
||||
|
||||
await _context.CreateFile(filePath, Template);
|
||||
|
||||
var moduleImportPath = folderPath
|
||||
.Replace('\\', '.')
|
||||
.Replace('/', '.');
|
||||
|
||||
var main = await _context.ReadFile("main.py");
|
||||
|
||||
main += string.Join('\n',
|
||||
$"\n\nfrom {moduleImportPath} import {moduleName}",
|
||||
$"app.include_router(prefix=\"/{name.Kebaberize()}\", router={moduleName}.router)"
|
||||
);
|
||||
|
||||
|
||||
main = new MainModifier(main)
|
||||
.Initialize()
|
||||
.Import(from: moduleImportPath, import: fqn.SnakeCasedName)
|
||||
.IncludeRouter(prefix: name.Kebaberize(), router: fqn.SnakeCasedName)
|
||||
.Rewrite();
|
||||
|
||||
await _context.WriteFile("main.py", main);
|
||||
}
|
||||
}
|
||||
|
@ -69,28 +69,25 @@ public partial class MycroForge
|
||||
|
||||
private async Task ExecuteAsync(string name, IEnumerable<string> columns)
|
||||
{
|
||||
var fqn = new FullyQualifiedName(name);
|
||||
var folderPath = $"{Features.Db.FeatureName}/entities";
|
||||
|
||||
_context.AssertDirectoryExists(Features.Db.FeatureName);
|
||||
|
||||
if (name.FullyQualifiedName() is { Length: 2 } fullName)
|
||||
{
|
||||
folderPath = Path.Combine(folderPath, fullName[0]);
|
||||
name = fullName[1];
|
||||
}
|
||||
if (fqn.HasPath)
|
||||
folderPath = Path.Combine(folderPath, fqn.Path);
|
||||
|
||||
var _columns = GetColumnDefinitions(columns.ToArray());
|
||||
var className = name.Underscore().Pascalize();
|
||||
var typeImports = string.Join(", ", _columns.Select(c => c.OrmType.Split('(').First()).Distinct());
|
||||
var columnDefinitions = string.Join("\n\t", _columns.Select(ColumnToString));
|
||||
|
||||
var code = string.Join('\n', Template);
|
||||
code = code.Replace("%type_imports%", typeImports);
|
||||
code = code.Replace("%class_name%", className);
|
||||
code = code.Replace("%table_name%", name.Underscore().ToLower().Pluralize());
|
||||
code = code.Replace("%class_name%", fqn.PascalizedName);
|
||||
code = code.Replace("%table_name%", fqn.SnakeCasedName.Pluralize());
|
||||
code = code.Replace("%column_definitions%", columnDefinitions);
|
||||
|
||||
var fileName = $"{name.Underscore().ToLower()}.py";
|
||||
var fileName = $"{fqn.SnakeCasedName}.py";
|
||||
var filePath = Path.Combine(folderPath, fileName);
|
||||
await _context.CreateFile(filePath, code);
|
||||
|
||||
@ -104,11 +101,11 @@ public partial class MycroForge
|
||||
.ToLower();
|
||||
|
||||
var env = await _context.ReadFile($"{Features.Db.FeatureName}/env.py");
|
||||
env = new DbEnvModifier(env, importPath, className).Rewrite();
|
||||
env = new DbEnvModifier(env, importPath, fqn.PascalizedName).Rewrite();
|
||||
await _context.WriteFile($"{Features.Db.FeatureName}/env.py", env);
|
||||
|
||||
var main = await _context.ReadFile("main.py");
|
||||
main = new MainModifier(main).Initialize().Import(importPath, className).Rewrite();
|
||||
main = new MainModifier(main).Initialize().Import(importPath, fqn.PascalizedName).Rewrite();
|
||||
await _context.WriteFile("main.py", main);
|
||||
}
|
||||
|
||||
|
@ -57,18 +57,16 @@ public partial class MycroForge
|
||||
|
||||
private async Task ExecuteAsync(string name, bool withSession)
|
||||
{
|
||||
var fqn = new FullyQualifiedName(name);
|
||||
var folderPath = string.Empty;
|
||||
|
||||
if (name.FullyQualifiedName() is { Length: 2} fullName)
|
||||
{
|
||||
folderPath = Path.Combine(folderPath, fullName[0]);
|
||||
name = fullName[1];
|
||||
}
|
||||
if (fqn.HasPath)
|
||||
folderPath = Path.Combine(folderPath, fqn.Path);
|
||||
|
||||
var filePath = Path.Combine(folderPath, $"{name.Underscore().ToLower()}.py");
|
||||
var className = Path.GetFileName(name).Pascalize();
|
||||
var code = string.Join('\n', withSession ? WithSessionTemplate : DefaultTemplate)
|
||||
.Replace("%class_name%", className);
|
||||
var filePath = Path.Combine(folderPath, $"{fqn.SnakeCasedName}.py");
|
||||
var template = withSession ? WithSessionTemplate : DefaultTemplate;
|
||||
var code = string.Join('\n', template)
|
||||
.Replace("%class_name%", fqn.PascalizedName);
|
||||
|
||||
await _context.CreateFile(filePath, code);
|
||||
}
|
||||
|
@ -2,11 +2,6 @@
|
||||
|
||||
public static class StringExtensions
|
||||
{
|
||||
public static string[] FullyQualifiedName(this string name)
|
||||
{
|
||||
return name.Split(':').Select(s => s.Trim()).ToArray();
|
||||
}
|
||||
|
||||
public static string DeduplicateDots(this string path)
|
||||
{
|
||||
while (path.Contains(".."))
|
||||
|
@ -23,11 +23,10 @@ public sealed partial class Api : IFeature
|
||||
private static readonly string[] MainTemplate =
|
||||
[
|
||||
"from fastapi import FastAPI",
|
||||
"",
|
||||
$"from {FeatureName}.routers import hello",
|
||||
"",
|
||||
"app = FastAPI()",
|
||||
"",
|
||||
$"from {FeatureName}.routers import hello",
|
||||
"app.include_router(prefix=\"/hello\", router=hello.router)"
|
||||
];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user