mycroforge/MycroForge.Core/ProjectContext.cs
mdnapo 02a82589ae - Refactored init & features
- Extended documentation
2024-07-14 22:27:32 +02:00

134 lines
4.3 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(bool create = false)
{
if (!File.Exists(ConfigPath))
{
if (create) await CreateFile("m4g.json", "{}");
else 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);
}
}