using System.CommandLine; using Humanizer; using MycroForge.CLI.Commands.Interfaces; using MycroForge.CLI.Extensions; 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(User).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 folderPath = string.Empty; if (name.FullyQualifiedName() is { Length: 2} fullName) { folderPath = Path.Combine(folderPath, fullName[0]); name = fullName[1]; } 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); await _context.CreateFile(filePath, code); } } } }