mycroforge/MycroForge.CLI/Commands/MycroForge.Init.cs

85 lines
3.1 KiB
C#

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<MycroForge>
{
private static readonly string[] DefaultFeatures =
[
Features.Git.FeatureName,
Features.Api.FeatureName,
Features.Orm.FeatureName
];
private static readonly Argument<string> NameArgument =
new(name: "name", description: "The name of your project");
private static readonly Option<IEnumerable<string>> WithoutOption =
new Option<IEnumerable<string>>(name: "--without", description: "Features to exclude")
.FromAmong(DefaultFeatures);
private readonly ProjectContext _context;
private readonly List<IFeature> _features;
public Init(ProjectContext context, IEnumerable<IFeature> 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<string> 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", "{}");
await _context.LoadConfig(force: true);
// Create the entrypoint file
await _context.CreateFile("main.py");
// Create the venv
await Bash.ExecuteAsync($"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<string> 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 Bash.ExecuteAsync($"chmod -R 777 {directory}");
return directory;
}
}
}