Add initial run log file to track execution details

This commit is contained in:
2026-07-11 16:30:36 +02:00
parent e4d4c4eb9a
commit ff634a328a
6 changed files with 2134 additions and 14 deletions
+170 -1
View File
@@ -1,3 +1,4 @@
using System.Diagnostics;
using System.Net;
using System.Text;
using GCBoK.WebStaticBuilder;
@@ -45,6 +46,30 @@ if (Val("--cdn") is { } cdn) { /* applied to chosen env below */ }
Directories.Init(cfg, root);
// Help
if (argsList.Contains("--help") || argsList.Contains("-h") || argsList.Contains("help"))
{
PrintHelp();
return;
}
// Version
if (argsList.Contains("--version"))
{
var v = System.Reflection.Assembly.GetExecutingAssembly().GetName().Version;
Console.WriteLine($"GCBoK.WebStaticBuilder {v?.ToString() ?? "0.0.0"}");
var hash = GitShortHash(AppContext.BaseDirectory);
if (hash != null) Console.WriteLine($"commit: {hash}");
return;
}
// Self-update (Hermes-Konzept: lokale Aenderungen stashen, pull, mergen, rebuild)
if (argsList.Contains("update"))
{
UpdateSelf(verbose);
return;
}
// Subcommand: translate
if (argsList.Contains("translate"))
{
@@ -93,6 +118,150 @@ if (verbose) Console.WriteLine($"GCBoK.WebStaticBuilder — building (env={envNa
Builder.Build(cfg, env, envName, verbose, dryRun);
Console.WriteLine("Build completed successfully.");
static void PrintHelp()
{
Console.WriteLine(@"GCBoK.WebStaticBuilder — Statischer, mehrsprachiger Website-Generator
Aufruf:
webstatic build [Optionen] Website bauen
webstatic serve [--port N] Lokalen Server starten (Vorschau)
webstatic init <name> Beispiel-Site anlegen
webstatic translate --check Fehlende Übersetzungen melden
webstatic translate --draft Übersetzungs-Entwürfe erzeugen
webstatic --version Version (Assembly + Git-Commit) anzeigen
webstatic --help | -h Diese Hilfe
Build-Optionen:
--env <name> Umgebung: development | staging | deploy
--preview|--work|--review Alias für --env development
--staging Alias für --env staging
--deploy Alias für --env deploy
--root <dir> Site-Stammverzeichnis (Default: cwd)
--config <file> Pfad zu webstatic.json
--content/--templates/--assets/--output <dir> Pfade überschreiben
--default-lang <lang> Standardsprache (Default: de)
--langs de,en Nur diese Sprachen bauen
--base-url <url> / --cdn <url> Environment-Werte überschreiben
--verbose | -v Ausführliche Ausgabe
--dry-run | -n Nichts schreiben, nur anzeigen
Der Build liest <root>/webstatic.json (CLI-Flags haben Vorrang).");
}
static string? GitShortHash(string startDir)
{
var repo = FindRepoRoot(startDir);
if (repo == null) return null;
try
{
var psi = new ProcessStartInfo
{
FileName = "git",
Arguments = "rev-parse --short HEAD",
WorkingDirectory = repo,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
using var p = Process.Start(psi);
if (p == null) return null;
var outp = p.StandardOutput.ReadToEnd().Trim();
p.WaitForExit();
return p.ExitCode == 0 && outp.Length > 0 ? outp : null;
}
catch
{
return null;
}
}
static string? FindRepoRoot(string startDir)
{
var dir = new DirectoryInfo(Path.GetFullPath(startDir));
while (dir != null)
{
if (Directory.Exists(Path.Combine(dir.FullName, ".git"))) return dir.FullName;
dir = dir.Parent;
}
return null;
}
static int RunProcess(string fileName, string args, string? workDir = null)
{
var psi = new ProcessStartInfo
{
FileName = fileName,
Arguments = args,
WorkingDirectory = workDir,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
using var p = Process.Start(psi)
?? throw new InvalidOperationException($"Could not start {fileName}.");
p.OutputDataReceived += (_, e) => { if (e.Data != null) Console.WriteLine(e.Data); };
p.ErrorDataReceived += (_, e) => { if (e.Data != null) Console.WriteLine(e.Data); };
p.BeginOutputReadLine();
p.BeginErrorReadLine();
p.WaitForExit();
return p.ExitCode;
}
static void UpdateSelf(bool verbose)
{
var repo = FindRepoRoot(AppContext.BaseDirectory);
if (repo == null)
{
Console.WriteLine("UPDATE nicht möglich: kein Git-Repo gefunden (Copy-Installation?).");
Console.WriteLine("Bitte neu installieren: ./install.sh");
return;
}
Console.WriteLine($"== Update (Hermes): {repo} ==");
var dirty = !string.IsNullOrWhiteSpace(Capture("git", "status --porcelain", repo));
bool stashed = false;
if (dirty)
{
Console.WriteLine("Lokale Änderungen -> git stash");
RunProcess("git", "stash", repo);
stashed = true;
}
try
{
Console.WriteLine("== git pull ==");
var rc = RunProcess("git", "pull", repo);
if (rc != 0) Console.WriteLine("HINWEIS: git pull lieferte Fehler (evtl. Netzwerk/Upstream). Stash wird trotzdem zurückgespielt.");
}
finally
{
if (stashed)
{
Console.WriteLine("== git stash pop ==");
RunProcess("git", "stash pop", repo);
}
}
Console.WriteLine("== Baue Release ==");
RunProcess("dotnet", $"build \"{Path.Combine(repo, "GCBoK.WebStaticBuilder.csproj")}\" -c Release -v minimal", repo);
Console.WriteLine("Update abgeschlossen.");
}
static string Capture(string fileName, string args, string workDir)
{
var psi = new ProcessStartInfo
{
FileName = fileName,
Arguments = args,
WorkingDirectory = workDir,
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false
};
using var p = Process.Start(psi)
?? throw new InvalidOperationException($"Could not start {fileName}.");
var outp = p.StandardOutput.ReadToEnd() + p.StandardError.ReadToEnd();
p.WaitForExit();
return outp;
}
static string FindExampleDir()
{
var candidates = new[]
@@ -122,7 +291,7 @@ static void InitSite(string name, string rootDir)
}
CopyDir(example, target);
Console.WriteLine($"Initialized site scaffold at {target}");
Console.WriteLine($"Next: cd {name} && webstatic build --env work");
Console.WriteLine($"Next: cd {name} && webstatic build --env development");
}
static void CopyDir(string src, string dst)