diff --git a/MycroForge.CLI/ArgsContext.cs b/MycroForge.CLI/ArgsContext.cs deleted file mode 100644 index 9295203..0000000 --- a/MycroForge.CLI/ArgsContext.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace MycroForge.CLI; - -public class ArgsContext -{ - public string[] Args { get; init; } = Array.Empty(); -} \ No newline at end of file diff --git a/MycroForge.CLI/Bash.cs b/MycroForge.CLI/Bash.cs deleted file mode 100644 index 2e79381..0000000 --- a/MycroForge.CLI/Bash.cs +++ /dev/null @@ -1,52 +0,0 @@ -using System.Diagnostics; - -namespace MycroForge.CLI; - -public static class Bash -{ - public static async Task ExecuteAsync(params string[] script) - { - var info = new ProcessStartInfo - { - FileName = "bash", - UseShellExecute = false, - CreateNoWindow = true, - RedirectStandardInput = true, - RedirectStandardOutput = true, - RedirectStandardError = true, - }; - - using var process = Process.Start(info); - - if (process is null) - throw new NullReferenceException("Could not initialize bash process."); - - process.OutputDataReceived += (sender, args) => - { - // Only print data when it's not empty to prevent noise in the shell - if (!string.IsNullOrEmpty(args.Data)) - Console.WriteLine(args.Data); - }; - process.BeginOutputReadLine(); - - process.ErrorDataReceived += (sender, args) => - { - // Only print data when it's not empty to prevent noise in the shell - if (!string.IsNullOrEmpty(args.Data)) - Console.WriteLine(args.Data); - }; - process.BeginErrorReadLine(); - - await using var input = process.StandardInput; - foreach (var line in script) - await input.WriteLineAsync(line); - - await input.FlushAsync(); - input.Close(); - - await process.WaitForExitAsync(); - - if (process.ExitCode != 0) - Console.WriteLine($"Process finished with exit code {process.ExitCode}."); - } -} \ No newline at end of file diff --git a/MycroForge.CLI/Commands/MycroForge.Api.Run.cs b/MycroForge.CLI/Commands/MycroForge.Api.Run.cs index 9ebb578..0e2af61 100644 --- a/MycroForge.CLI/Commands/MycroForge.Api.Run.cs +++ b/MycroForge.CLI/Commands/MycroForge.Api.Run.cs @@ -9,14 +9,17 @@ public partial class MycroForge { public class Run : Command, ISubCommandOf { - public Run() : base("run", "Run your app") + private readonly ProjectContext _context; + + public Run(ProjectContext context) : base("run", "Run your app") { + _context = context; this.SetHandler(ExecuteAsync); } private async Task ExecuteAsync() { - await Bash.ExecuteAsync([ + await _context.Bash([ "source .venv/bin/activate", "uvicorn main:app --reload" ]); diff --git a/MycroForge.CLI/Commands/MycroForge.Init.cs b/MycroForge.CLI/Commands/MycroForge.Init.cs index bc5a2c2..6a80e33 100644 --- a/MycroForge.CLI/Commands/MycroForge.Init.cs +++ b/MycroForge.CLI/Commands/MycroForge.Init.cs @@ -50,13 +50,12 @@ public partial class MycroForge // 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")}"); + await _context.Bash($"python3 -m venv {Path.Combine(projectRoot, ".venv")}"); // Initialize default features foreach (var feature in _features.Where(f => DefaultFeatures.Contains(f.Name))) @@ -77,7 +76,7 @@ public partial class MycroForge Directory.CreateDirectory(directory); - await Bash.ExecuteAsync($"chmod -R 777 {directory}"); + await _context.Bash($"chmod -R 777 {directory}"); return directory; } diff --git a/MycroForge.CLI/Commands/MycroForge.Install.cs b/MycroForge.CLI/Commands/MycroForge.Install.cs index f63976e..7ccb461 100644 --- a/MycroForge.CLI/Commands/MycroForge.Install.cs +++ b/MycroForge.CLI/Commands/MycroForge.Install.cs @@ -10,8 +10,12 @@ public partial class MycroForge private static readonly Argument> PackagesArgument = new(name: "packages", description: "The names of the packages to install"); - public Install() : base("install", "Install packages and update the requirements.txt") + private readonly ProjectContext _context; + + public Install(ProjectContext context) : + base("install", "Install packages and update the requirements.txt") { + _context = context; AddAlias("i"); AddArgument(PackagesArgument); this.SetHandler(ExecuteAsync, PackagesArgument); @@ -19,7 +23,7 @@ public partial class MycroForge private async Task ExecuteAsync(IEnumerable packages) { - await Bash.ExecuteAsync( + await _context.Bash( "source .venv/bin/activate", $"pip install {string.Join(' ', packages)}", "pip freeze > requirements.txt" diff --git a/MycroForge.CLI/Commands/MycroForge.Orm.Generate.Migration.cs b/MycroForge.CLI/Commands/MycroForge.Orm.Generate.Migration.cs index a8bb919..b08dc95 100644 --- a/MycroForge.CLI/Commands/MycroForge.Orm.Generate.Migration.cs +++ b/MycroForge.CLI/Commands/MycroForge.Orm.Generate.Migration.cs @@ -14,8 +14,11 @@ public partial class MycroForge private static readonly Argument NameArgument = new(name: "name", description: "The name of the migration"); - public Migration() : base("migration", "Generate a migration") + private readonly ProjectContext _context; + + public Migration(ProjectContext context) : base("migration", "Generate a migration") { + _context = context; AddAlias("m"); AddArgument(NameArgument); this.SetHandler(ExecuteAsync, NameArgument); @@ -23,7 +26,7 @@ public partial class MycroForge private async Task ExecuteAsync(string name) { - await Bash.ExecuteAsync( + await _context.Bash( "source .venv/bin/activate", $"alembic revision --autogenerate -m \"{name}\" --rev-id $(date -u +\"%Y%m%d%H%M%S\")" ); diff --git a/MycroForge.CLI/Commands/MycroForge.Orm.Migrate.cs b/MycroForge.CLI/Commands/MycroForge.Orm.Migrate.cs index 9f2fc10..f1040e7 100644 --- a/MycroForge.CLI/Commands/MycroForge.Orm.Migrate.cs +++ b/MycroForge.CLI/Commands/MycroForge.Orm.Migrate.cs @@ -9,14 +9,17 @@ public partial class MycroForge { public class Migrate : Command, ISubCommandOf { - public Migrate() : base("migrate", "Apply migrations to the database") + private readonly ProjectContext _context; + + public Migrate(ProjectContext context) : base("migrate", "Apply migrations to the database") { + _context = context; this.SetHandler(ExecuteAsync); } private async Task ExecuteAsync() { - await Bash.ExecuteAsync([ + await _context.Bash([ "source .venv/bin/activate", "alembic upgrade head" ]); diff --git a/MycroForge.CLI/Commands/MycroForge.Orm.Rollback.cs b/MycroForge.CLI/Commands/MycroForge.Orm.Rollback.cs index e17a0de..0b03edb 100644 --- a/MycroForge.CLI/Commands/MycroForge.Orm.Rollback.cs +++ b/MycroForge.CLI/Commands/MycroForge.Orm.Rollback.cs @@ -9,14 +9,17 @@ public partial class MycroForge { public class Rollback : Command, ISubCommandOf { - public Rollback() : base("rollback", "Rollback the last migration") + private readonly ProjectContext _context; + + public Rollback(ProjectContext context) : base("rollback", "Rollback the last migration") { + _context = context; this.SetHandler(ExecuteAsync); } private async Task ExecuteAsync() { - await Bash.ExecuteAsync([ + await _context.Bash([ "source .venv/bin/activate", "alembic downgrade -1" ]); diff --git a/MycroForge.CLI/Commands/MycroForge.Script.Run.cs b/MycroForge.CLI/Commands/MycroForge.Script.Run.cs new file mode 100644 index 0000000..0a3a71e --- /dev/null +++ b/MycroForge.CLI/Commands/MycroForge.Script.Run.cs @@ -0,0 +1,82 @@ +using System.CommandLine; +using System.Dynamic; +using System.Text; +using IronPython.Hosting; +using MycroForge.CLI.Commands.Interfaces; + +namespace MycroForge.CLI.Commands; + +public partial class MycroForge +{ + public partial class Script + { + public class Run : Command, ISubCommandOf