using System.CommandLine; using Humanizer; using MycroForge.Core.Contract; using MycroForge.CLI.Extensions; using MycroForge.Core; namespace MycroForge.CLI.Commands; public partial class MycroForge { public partial class Generate { public class Service : Command, ISubCommandOf { private static readonly Argument NameArgument = new(name: "name", description: "The name of the service"); private static readonly Option WithSessionOption = new(name: "--with-session", description: "Create a service that uses database sessions"); private static readonly string[] DefaultTemplate = [ "class %class_name%:", "", "\tdef hello(self, name: str) -> str:", "\t\treturn f\"Hello, {str}!\"" ]; private static readonly string[] WithSessionTemplate = [ "from typing import List", "from sqlalchemy import select", $"from {Features.Db.FeatureName}.engine.async_session import async_session", $"# from {Features.Db.FeatureName}.entities.entity import Entity", "", "class %class_name%:", "", "\tasync def list(self, value: str) -> List[Entity]:", "\t\tasync with async_session() as session:", "\t\t\t# stmt = select(Entity).where(Entity.value == value)", "\t\t\t# results = (await session.scalars(stmt)).all()", "\t\t\t# return results", "\t\t\tpass", "\t\treturn []" ]; private readonly ProjectContext _context; public Service(ProjectContext context) : base("service", "Generate a service") { _context = context; AddAlias("s"); AddArgument(NameArgument); AddOption(WithSessionOption); this.SetHandler(ExecuteAsync, NameArgument, WithSessionOption); } private async Task ExecuteAsync(string name, bool withSession) { var fqn = new FullyQualifiedName(name); var folderPath = string.Empty; if (fqn.HasPath) folderPath = Path.Combine(folderPath, fqn.FolderPath); 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); } } } }