feat: load application and repository configuration from env and TOML

This commit is contained in:
mahdium committed 2026-11-03 15:02:50 +03:30
commit ae8680d275
17 files changed
+301

No files matched your search

+52
View File
@@ -0,0 +1,52 @@
using DotNetEnv;
namespace ForgejoReleaseSync.Services;
public class AppConfig
{
public required string ForgejoInstacne { get; set; }
public required string ForgejoToken { get; set; }
public required ushort SyncConcurrency { get; set; }
public required string RepositoryConfigFilePath { get; set; }
}
public static class AppConfigLoader
{
public static AppConfig LoadConfigFromEnv()
{
Env.Load();
var forgejoInstance = Environment.GetEnvironmentVariable("FORGEJO_INSTANCE");
var forgejoToken = Environment.GetEnvironmentVariable("FORGEJO_TOKEN");
var syncConcurrency = Environment.GetEnvironmentVariable("SYNC_CONCURRENCY");
var repoConfigFilePath = Environment.GetEnvironmentVariable("REPO_CONFIG_FILE");
if (string.IsNullOrEmpty(forgejoInstance))
throw new Exception("FORGEJO_INSTANCE environment variable is required");
if (!string.IsNullOrEmpty(forgejoToken) && forgejoInstance.EndsWith('/'))
forgejoInstance = forgejoInstance[..^1];
if (string.IsNullOrEmpty(forgejoToken))
throw new Exception("FORGEJO_TOKEN environment variable is required");
ushort syncConcurrencyParsed = 3;
if (!string.IsNullOrEmpty(syncConcurrency))
ushort.TryParse(syncConcurrency, out syncConcurrencyParsed);
if (syncConcurrencyParsed > 10)
throw new ArgumentOutOfRangeException(nameof(syncConcurrencyParsed),
"Sync concurrency cannot be greater than 10");
if (string.IsNullOrEmpty(repoConfigFilePath))
throw new Exception("REPO_CONFIG_FILE environment variable is required");
return new AppConfig
{
ForgejoInstacne = forgejoInstance,
ForgejoToken = forgejoToken,
SyncConcurrency = syncConcurrencyParsed,
RepositoryConfigFilePath = repoConfigFilePath
};
}
}
+6
View File
@@ -0,0 +1,6 @@
namespace ForgejoReleaseSync.Services;
public class ForgejoService
{
}
+6
View File
@@ -0,0 +1,6 @@
namespace ForgejoReleaseSync.Services;
public class GithubService
{
}
+71
View File
@@ -0,0 +1,71 @@
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Logging;
using RStein.TOML;
namespace ForgejoReleaseSync.Services;
public class RepositoryConfig
{
public List<RepoSyncConfig> Repositories { get; set; } = [];
}
public class RepoSyncConfig
{
public required string Name { get; set; }
public required string GithubUrl { get; set; }
public required string ForgejoUrl { get; set; }
public required string IncludeRegex { get; set; }
public required string ExcludeRegex { get; set; }
}
public abstract class RepoConfigLoader()
{
public static async Task<RepositoryConfig> LoadConfigAsync(string configPath,CancellationToken token = default)
{
try
{
var toml = await File.ReadAllTextAsync(configPath, token);
var tables = await TomlSerializer.DeserializeAsync(toml, token);
var result = new RepositoryConfig();
foreach (var table in tables)
{
if (table.Value is not TomlArray tableValues)
continue;
foreach (var content in tableValues)
{
if (content is not TomlTable fields)
continue;
result.Repositories.Add(new RepoSyncConfig
{
Name = table.Key.ToString(),
GithubUrl = GetRequiredString(fields, "GithubUrl"),
ForgejoUrl = GetRequiredString(fields, "ForgejoUrl"),
IncludeRegex = GetRequiredString(fields, "IncludeRegex"),
ExcludeRegex = GetRequiredString(fields, "ExcludeRegex")
});
}
}
return result;
}
catch (Exception e)
{
throw new InvalidDataException("Failed to load configuration file", e);
}
}
private static string GetRequiredString(
TomlTable table,
string key)
{
return (string?)table[key]
?? throw new InvalidDataException(
$"Missing required configuration property: {key}");
}
}