SHA256
Add initial run log file to track execution details
This commit is contained in:
@@ -49,6 +49,18 @@ Siehe `webstatic.example/webstatic.json` und `docs/getting-started.md`.
|
||||
./install.sh # -> /opt/GitCover/webstatic, Symlink /usr/local/bin/webstatic
|
||||
```
|
||||
|
||||
## Version & Update
|
||||
|
||||
```bash
|
||||
webstatic --version # Assembly-Version + Git-Commit des Installations-Repos
|
||||
webstatic update # Selbstaktualisierung (Clone-Installation): lokale
|
||||
# Änderungen werden gestasht, git pull, gemerged, neu gebaut
|
||||
```
|
||||
|
||||
`webstatic update` setzt eine Clone-Installation voraus (siehe `install.sh`,
|
||||
Default `WEBSTATIC_INSTALL_MODE=clone`). Bei einer Copy-Installation erfolgt das
|
||||
Update via erneutem `./install.sh`.
|
||||
|
||||
## Machine Translation (optional)
|
||||
|
||||
```bash
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
=== Build Started: 2026-07-11 16:11:56.657 ===
|
||||
ENV: development
|
||||
BASE_URL: http://localhost:8000
|
||||
CDN_ASSETS: /assets
|
||||
ROOT: /mnt/brx5/work/OSS/build_webstatic
|
||||
|
||||
+1887
File diff suppressed because it is too large
Load Diff
+57
-13
@@ -1,26 +1,59 @@
|
||||
#!/usr/bin/env bash
|
||||
# GCBoK.WebStaticBuilder — Installationsskript
|
||||
# Installiert das Tool nach /opt/GitCover/webstatic und legt einen Symlink
|
||||
# `webstatic` nach /usr/local/bin. Idempotent.
|
||||
# Installiert das Tool per-user (Default: ~/.local/share/GitCover/webstatic) und
|
||||
# legt einen ausfuehrbaren Wrapper `webstatic` nach ~/.local/bin. Idempotent.
|
||||
# Kein sudo noetig (Spiegelbild des hermes-agent-Update-Konzepts: user-owned
|
||||
# Installationsziel -> `webstatic update` laeuft als normaler User).
|
||||
#
|
||||
# Modi (WEBSTATIC_INSTALL_MODE):
|
||||
# clone (Default) — klont das Quell-Repo inkl. .git nach /opt/GitCover/webstatic.
|
||||
# clone (Default) — klont das Quell-Repo inkl. .git nach INSTALL_DIR.
|
||||
# Ermoeglicht spaeter `git pull` + lokale Anpassungen stashen/mergen
|
||||
# (Hermes-Update-Konzept). Das Ziel ist ein echtes Git-Repo.
|
||||
# copy — kopiert nur das gebaute Binary + Beispiel + Docs (kein .git).
|
||||
#
|
||||
# Hinweis: /opt ist root-owned. Das Script sinnvollerweise als root ausfuehren,
|
||||
# z.B. `sudo env PATH="$PATH" ./install.sh`, damit `dotnet` im PATH bleibt.
|
||||
# Umgebungsvariablen (optional):
|
||||
# WEBSTATIC_INSTALL_MODE clone|copy (Default: clone)
|
||||
# WEBSTATIC_INSTALL_DIR Zielverzeichnis
|
||||
# (Default: $XDG_DATA_HOME/GitCover/webstatic bzw.
|
||||
# ~/.local/share/GitCover/webstatic)
|
||||
# WEBSTATIC_BIN_DIR Verzeichnis fuer den Launcher
|
||||
# (Default: $XDG_BIN_HOME bzw. ~/.local/bin;
|
||||
# nur bei System-Install fallback /usr/local/bin via sudo)
|
||||
#
|
||||
# System-weite Installation nach /opt/GitCover/webstatic (root-owned):
|
||||
# sudo env PATH="$PATH" \
|
||||
# WEBSTATIC_INSTALL_DIR=/opt/GitCover/webstatic \
|
||||
# WEBSTATIC_BIN_DIR=/usr/local/bin ./install.sh
|
||||
set -euo pipefail
|
||||
|
||||
INSTALL_MODE="${WEBSTATIC_INSTALL_MODE:-clone}"
|
||||
INSTALL_DIR="${WEBSTATIC_INSTALL_DIR:-/opt/GitCover/webstatic}"
|
||||
BIN_LINK="/usr/local/bin/webstatic"
|
||||
INSTALL_DIR="${WEBSTATIC_INSTALL_DIR:-${XDG_DATA_HOME:-$HOME/.local/share}/GitCover/webstatic}"
|
||||
BIN_DIR="${WEBSTATIC_BIN_DIR:-${XDG_BIN_HOME:-$HOME/.local/bin}}"
|
||||
BIN_LINK="$BIN_DIR/webstatic"
|
||||
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
echo "== GCBoK.WebStaticBuilder Installer =="
|
||||
echo "Modus: $INSTALL_MODE"
|
||||
echo "Installationsziel: $INSTALL_DIR"
|
||||
echo "Launcher: $BIN_LINK"
|
||||
|
||||
# 0) Update-Modus (--update)
|
||||
if [ "${1:-}" = "--update" ]; then
|
||||
echo "== Update =="
|
||||
if [ -d "$INSTALL_DIR/.git" ]; then
|
||||
cd "$INSTALL_DIR"
|
||||
[ -n "$(git status --porcelain)" ] && git stash
|
||||
git pull
|
||||
{ [ -n "$(git stash list)" ] && git stash pop; } || true
|
||||
dotnet build "$INSTALL_DIR/GCBoK.WebStaticBuilder.csproj" -c Release -v minimal
|
||||
else
|
||||
dotnet build "$REPO_DIR/GCBoK.WebStaticBuilder.csproj" -c Release -v minimal
|
||||
rm -rf "$INSTALL_DIR/bin"
|
||||
cp -r "$REPO_DIR/bin/Release/net10.0/." "$INSTALL_DIR/"
|
||||
fi
|
||||
echo "Update abgeschlossen."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 1) .NET 10 pruefen
|
||||
if ! command -v dotnet >/dev/null 2>&1; then
|
||||
@@ -33,6 +66,7 @@ echo "Gefunden: dotnet $(dotnet --version 2>/dev/null || echo unbekannt)"
|
||||
# 2) Quelle beschaffen
|
||||
if [ "$INSTALL_MODE" = "clone" ]; then
|
||||
echo "== Clone-Modus: bereite $INSTALL_DIR vor =="
|
||||
mkdir -p "$(dirname "$INSTALL_DIR")"
|
||||
if [ -d "$INSTALL_DIR/.git" ]; then
|
||||
echo "Bereits ein Git-Repo — ueberspringe Clone (git pull ist beim Update noetig)."
|
||||
else
|
||||
@@ -70,13 +104,22 @@ fi
|
||||
echo "== Baue Release =="
|
||||
dotnet build "$BUILD_PROJECT" -c Release -v minimal
|
||||
|
||||
# 4) Symlink
|
||||
echo "== Verknuepfe $BIN_LINK -> $DLL =="
|
||||
# 4) Ausfuehrbare Wrapper-Datei (kein direkter Symlink auf die .dll —
|
||||
# eine .dll ist unter Linux nicht ausfuehrbar; der Wrapper ruft dotnet auf)
|
||||
mkdir -p "$BIN_DIR" 2>/dev/null || sudo mkdir -p "$BIN_DIR"
|
||||
echo "== Erzeuge Wrapper $BIN_LINK -> $DLL =="
|
||||
WRAPPER_CONTENT="#!/usr/bin/env bash
|
||||
exec dotnet \"$DLL\" \"\$@\"
|
||||
"
|
||||
if [ -w "$(dirname "$BIN_LINK")" ]; then
|
||||
ln -sf "$DLL" "$BIN_LINK"
|
||||
rm -f "$BIN_LINK"
|
||||
printf '%s' "$WRAPPER_CONTENT" > "$BIN_LINK"
|
||||
chmod +x "$BIN_LINK"
|
||||
else
|
||||
echo "Hinweis: $BIN_LINK benoetigt Schreibrechte; erstelle Link via sudo."
|
||||
sudo ln -sf "$DLL" "$BIN_LINK"
|
||||
echo "Hinweis: $BIN_LINK benoetigt Schreibrechte; erstelle via sudo."
|
||||
rm -f "$BIN_LINK" 2>/dev/null || sudo rm -f "$BIN_LINK"
|
||||
printf '%s' "$WRAPPER_CONTENT" | sudo tee "$BIN_LINK" >/dev/null
|
||||
sudo chmod +x "$BIN_LINK"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
@@ -85,4 +128,5 @@ echo "Beispiel-Seite erzeugen: webstatic init mysite && cd mysite && webstatic b
|
||||
echo "GCBoK bauen: webstatic build --root www --env development"
|
||||
echo "Umgebungsvariable (optional): WEBSTATIC_BUILDER=$DLL"
|
||||
echo ""
|
||||
echo "Update (Clone-Modus): cd $INSTALL_DIR && git stash && git pull && git stash pop && dotnet build -c Release"
|
||||
echo "Update (Clone-Modus, ohne sudo): webstatic update"
|
||||
echo " (alternativ: cd $INSTALL_DIR && git stash && git pull && git stash pop && dotnet build -c Release)"
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
=== Run Started: 2026-07-11 16:11:56.696 ===
|
||||
+170
-1
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user