131 lines
4.2 KiB
C#
131 lines
4.2 KiB
C#
using System.Diagnostics;
|
|
using System.Text.Json;
|
|
using Humanizer;
|
|
using MycroForge.Core.Extensions;
|
|
|
|
namespace MycroForge.Core;
|
|
|
|
public class ProjectContext
|
|
{
|
|
public string RootDirectory { get; private set; } = Environment.CurrentDirectory;
|
|
public string AppName => Path.GetFileNameWithoutExtension(RootDirectory).Underscore().ToLower();
|
|
private string ConfigPath => Path.Combine(RootDirectory, "m4g.json");
|
|
|
|
|
|
public async Task<ProjectConfig> LoadConfig()
|
|
{
|
|
if (!File.Exists(ConfigPath))
|
|
throw new FileNotFoundException($"File {ConfigPath} does not exist.");
|
|
|
|
var config = await JsonSerializer.DeserializeAsync<ProjectConfig>(
|
|
File.OpenRead(ConfigPath),
|
|
Serialization.DefaultJsonSerializerOptions.CamelCasePrettyPrint
|
|
);
|
|
|
|
if (config is null)
|
|
throw new Exception($"Could not load {ConfigPath}");
|
|
|
|
return config;
|
|
}
|
|
|
|
public void ChangeRootDirectory(string path)
|
|
{
|
|
Directory.SetCurrentDirectory(path);
|
|
RootDirectory = path;
|
|
}
|
|
|
|
public void AssertDirectoryExists(string path)
|
|
{
|
|
var fullPath = Path.Combine(RootDirectory, path);
|
|
|
|
if (!Directory.Exists(fullPath))
|
|
{
|
|
throw new(string.Join('\n',
|
|
$"{fullPath} does not exist, make sure you're in the correct directory."
|
|
));
|
|
}
|
|
}
|
|
|
|
public async Task CreateFile(string path, params string[] content)
|
|
{
|
|
var fullPath = Path.Combine(RootDirectory, path);
|
|
var fileInfo = new FileInfo(fullPath);
|
|
|
|
if (fileInfo.Exists) return;
|
|
|
|
Directory.CreateDirectory(fileInfo.Directory!.FullName);
|
|
await File.WriteAllTextAsync(fullPath, string.Join("\n", content));
|
|
await Bash($"chmod 777 {fullPath}");
|
|
}
|
|
|
|
public async Task<string> ReadFile(string path)
|
|
{
|
|
var fullPath = Path.Combine(RootDirectory, path);
|
|
var fileInfo = new FileInfo(fullPath);
|
|
|
|
if (!fileInfo.Exists)
|
|
throw new Exception($"File {fullPath} does not exist.");
|
|
|
|
return await File.ReadAllTextAsync(fullPath);
|
|
}
|
|
|
|
public async Task WriteFile(string path, params string[] content)
|
|
{
|
|
var fullPath = Path.Combine(RootDirectory, path);
|
|
var fileInfo = new FileInfo(fullPath);
|
|
Directory.CreateDirectory(fileInfo.Directory!.FullName);
|
|
await File.WriteAllTextAsync(fullPath, string.Join("\n", content));
|
|
}
|
|
|
|
public async Task Bash(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}.");
|
|
}
|
|
|
|
public async Task SaveConfig(ProjectConfig config)
|
|
{
|
|
var json = await config.SerializeAsync(Serialization.DefaultJsonSerializerOptions.CamelCasePrettyPrint);
|
|
await File.WriteAllTextAsync(ConfigPath, json);
|
|
}
|
|
} |