using System.CommandLine; using MycroForge.CLI.Commands.Interfaces; using MycroForge.CLI.Features; namespace MycroForge.CLI.Commands; public partial class MycroForge { public class Init : Command, ISubCommandOf { private static readonly string[] DefaultFeatures = [ Features.Git.FeatureName, Features.Api.FeatureName, Features.Orm.FeatureName ]; private static readonly Argument NameArgument = new(name: "name", description: "The name of your project"); private static readonly Option> WithoutOption = new Option>(name: "--without", description: "Features to exclude") .FromAmong(DefaultFeatures); private readonly ProjectContext _context; private readonly List _features; public Init(ProjectContext context, IEnumerable features) : base("init", "Initialize a new project") { _context = context; _features = features.ToList(); AddArgument(NameArgument); AddOption(WithoutOption); this.SetHandler(ExecuteAsync, NameArgument, WithoutOption); } private async Task ExecuteAsync(string name, IEnumerable without) { // Validate excluded features var withoutList = without.ToList(); foreach (var feature in withoutList) if (_features.All(f => f.Name != feature)) throw new Exception($"Feature {feature} does not exist."); // Create the project directory and change the directory for the ProjectContext var projectRoot = await CreateDirectory(name); _context.ChangeDirectory(projectRoot); // Create the config file and initialize the config await _context.CreateFile("m4g.json", "{}"); // Create the entrypoint file await _context.CreateFile("main.py"); // Create the venv await _context.Bash($"python3 -m venv {Path.Combine(projectRoot, ".venv")}"); // Initialize default features foreach (var feature in _features.Where(f => DefaultFeatures.Contains(f.Name))) if (!withoutList.Contains(feature.Name)) await feature.ExecuteAsync(_context); Console.WriteLine($"Directory {projectRoot} was successfully initialized"); } private async Task CreateDirectory(string name) { var directory = Path.Combine(Directory.GetCurrentDirectory(), name); if (Directory.Exists(directory)) throw new Exception($"Directory {directory} already exists."); Console.WriteLine($"Creating directory {directory}"); Directory.CreateDirectory(directory); await _context.Bash($"chmod -R 777 {directory}"); return directory; } } }