mirror of
https://github.com/Smaug123/gitea-repo-config
synced 2025-10-11 10:18:40 +00:00
Subcommands (#62)
This commit is contained in:
116
Gitea.Declarative/Reconcile.fs
Normal file
116
Gitea.Declarative/Reconcile.fs
Normal file
@@ -0,0 +1,116 @@
|
||||
namespace Gitea.Declarative
|
||||
|
||||
open System
|
||||
open System.IO
|
||||
open System.Net.Http
|
||||
open Argu
|
||||
open Microsoft.Extensions.Logging.Console
|
||||
open Microsoft.Extensions.Options
|
||||
open Microsoft.Extensions.Logging
|
||||
|
||||
type RunArgsFragment =
|
||||
| [<ExactlyOnce ; EqualsAssignmentOrSpaced>] Config_File of string
|
||||
| [<ExactlyOnce ; EqualsAssignmentOrSpaced>] Gitea_Host of string
|
||||
| [<ExactlyOnce ; EqualsAssignmentOrSpaced ; CustomAppSettings "GITEA_ADMIN_API_TOKEN">] Gitea_Admin_Api_Token of
|
||||
string
|
||||
| [<Unique ; EqualsAssignmentOrSpaced ; CustomAppSettings "GITHUB_API_TOKEN">] GitHub_Api_Token of string
|
||||
| Dry_Run
|
||||
|
||||
interface IArgParserTemplate with
|
||||
member s.Usage =
|
||||
match s with
|
||||
| Config_File _ ->
|
||||
"a config file, JSON, conforming to GiteaConfig.schema.json, specifying the desired Gitea configuration"
|
||||
| Gitea_Host _ -> "the Gitea host, e.g. https://gitea.mydomain.com"
|
||||
| Gitea_Admin_Api_Token _ ->
|
||||
"a Gitea admin user's API token; can be read from the environment variable GITEA_ADMIN_API_TOKEN"
|
||||
| GitHub_Api_Token _ ->
|
||||
"a GitHub API token with read access to every desired sync-from-GitHub repo; can be read from the environment variable GITHUB_API_TOKEN"
|
||||
| Dry_Run _ -> "don't actually perform the reconciliation"
|
||||
|
||||
type RunArgs =
|
||||
{
|
||||
ConfigFile : FileInfo
|
||||
GiteaHost : Uri
|
||||
GiteaAdminApiToken : string
|
||||
GitHubApiToken : string option
|
||||
DryRun : bool
|
||||
}
|
||||
|
||||
static member OfParse (parsed : ParseResults<RunArgsFragment>) : Result<RunArgs, ArguParseException> =
|
||||
try
|
||||
{
|
||||
ConfigFile = parsed.GetResult RunArgsFragment.Config_File |> FileInfo
|
||||
GiteaHost = parsed.GetResult RunArgsFragment.Gitea_Host |> Uri
|
||||
GiteaAdminApiToken = parsed.GetResult RunArgsFragment.Gitea_Admin_Api_Token
|
||||
GitHubApiToken = parsed.TryGetResult RunArgsFragment.GitHub_Api_Token
|
||||
DryRun = parsed.TryGetResult RunArgsFragment.Dry_Run |> Option.isSome
|
||||
}
|
||||
|> Ok
|
||||
with :? ArguParseException as e ->
|
||||
Error e
|
||||
|
||||
[<RequireQualifiedAccess>]
|
||||
module Reconcile =
|
||||
|
||||
let private getUserInput (s : string) : string =
|
||||
Console.Write s
|
||||
Console.ReadLine ()
|
||||
|
||||
let run (args : RunArgs) : Async<int> =
|
||||
|
||||
let config = GiteaConfig.get args.ConfigFile
|
||||
|
||||
let options =
|
||||
let options = ConsoleLoggerOptions ()
|
||||
|
||||
{ new IOptionsMonitor<ConsoleLoggerOptions> with
|
||||
member _.Get _ = options
|
||||
member _.CurrentValue = options
|
||||
|
||||
member _.OnChange _ =
|
||||
{ new IDisposable with
|
||||
member _.Dispose () = ()
|
||||
}
|
||||
}
|
||||
|
||||
async {
|
||||
use loggerProvider = new ConsoleLoggerProvider (options)
|
||||
let logger = loggerProvider.CreateLogger "Gitea.Declarative"
|
||||
|
||||
use client = new HttpClient ()
|
||||
client.BaseAddress <- args.GiteaHost
|
||||
client.DefaultRequestHeaders.Add ("Authorization", $"token {args.GiteaAdminApiToken}")
|
||||
|
||||
let client = Gitea.Client client |> IGiteaClient.fromReal
|
||||
|
||||
logger.LogInformation "Checking users..."
|
||||
let! userErrors = Gitea.checkUsers config client
|
||||
|
||||
match userErrors, args.DryRun with
|
||||
| Ok (), _ -> ()
|
||||
| Error errors, false -> do! Gitea.reconcileUserErrors logger getUserInput client errors
|
||||
| Error errors, true ->
|
||||
logger.LogError (
|
||||
"Differences encountered in user configuration, but not reconciling them due to --dry-run. Errors may occur while checking repo configuration. {UserErrors}",
|
||||
errors
|
||||
)
|
||||
|
||||
logger.LogInformation "Checking repos..."
|
||||
let! repoErrors = Gitea.checkRepos logger config client
|
||||
|
||||
match repoErrors, args.DryRun with
|
||||
| Ok (), _ -> ()
|
||||
| Error errors, false -> do! Gitea.reconcileRepoErrors logger client args.GitHubApiToken errors
|
||||
| Error errors, true ->
|
||||
logger.LogError (
|
||||
"Differences encountered in repo configuration, but not reconciling them due to --dry-run. {RepoErrors}",
|
||||
errors
|
||||
)
|
||||
|
||||
match userErrors, repoErrors with
|
||||
| Ok (), Ok () -> return 0
|
||||
| Ok (), Error _ -> return 1
|
||||
| Error _, Ok () -> return 2
|
||||
| Error _, Error _ -> return 3
|
||||
}
|
Reference in New Issue
Block a user