]> juplo.de Git - maven-thymeleaf-skin/commitdiff
Add import-in-astro.sh for importing Maven site output into Astro
authorKai Moritz <kai.milan.moritz@googlemail.com>
Mon, 15 Jun 2026 18:27:00 +0000 (18:27 +0000)
committerKai Moritz <kai.milan.moritz@googlemail.com>
Mon, 15 Jun 2026 18:27:00 +0000 (18:27 +0000)
Replaces import-in-hugo.sh for the new Astro-based website. Key
differences vs. the Hugo version:
- Content → src/content/projects/PROJECT/VERSION/ (HTML + YAML frontmatter)
- Routing → src/pages/PROJECT/ (current) or src/pages/projects/P/V/ (archived)
- Static  → public/projects/PROJECT/VERSION/
- No Hugo shortcode transformation for <pre> blocks
- Relative generated-doc dir links (apidocs/, xref/ etc.) are rewritten
  to absolute /projects/X/Y/DIR/index.html URLs, because these dirs always
  live under /projects/ regardless of whether the content page is served
  from the visible (/<project>/) or archived (/projects/X/Y/) URL

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
src/main/resources/import-in-astro.sh [new file with mode: 0755]

diff --git a/src/main/resources/import-in-astro.sh b/src/main/resources/import-in-astro.sh
new file mode 100755 (executable)
index 0000000..942504e
--- /dev/null
@@ -0,0 +1,236 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+USAGE=$(
+  echo "Usage: $0 <ASTRO_ROOT> [--project <name>] [ [--current [<url>]] | [--archived [<url>] [--canonical <url>]] ]";
+  cat << EOF
+
+  Imports a Maven site generated with the sili-skin into an Astro project.
+  Run this script from the Maven site output directory (where index.html lives).
+
+--project   : Overrides the project name used for URL and directory paths
+              (Default: artifactId from the Maven project metadata).
+--current   : [DEFAULT]
+              Marks this version as the current (visible) release.
+              Content URL: /<project>/page.html
+              Routing:     src/pages/<project>/
+              If <url> is given, it overrides the URL base (default: /<project>/).
+--archived  : Marks this version as archived/snapshot (not visible by default).
+              Content URL: /projects/<project>/<version>/page.html
+              Routing:     src/pages/projects/<project>/<version>/
+              params.canonical points to the corresponding page of the current version.
+              If <url> is given, it overrides the URL base.
+--canonical : Explicitly sets the canonical URL base for --archived mode.
+              Default: /<project>
+              Only valid with --archived.
+EOF
+)
+
+if [ $# -lt 1 ]; then
+  echo "$USAGE"
+  exit 1
+fi
+
+SCRIPT_DIR=$( cd -- "$( dirname -- "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )
+
+ASTRO_ROOT="${1%%/}"
+shift
+
+PROJECT=""
+CURRENT=0
+ARCHIVED=0
+URL_BASE=""
+CANONICAL=""
+
+command -v jq >/dev/null 2>&1 || { echo "ERROR -- jq is required"; exit 1; }
+
+if [[ ! -f "$ASTRO_ROOT/package.json" ]]; then
+  echo "ERROR -- $ASTRO_ROOT does not look like an Astro project root (no package.json found)"
+  exit 1
+fi
+
+JSON=$(sed -n '/<script id="sili-json" type="application\/json">/,/<\/script>/p' "${SCRIPT_DIR}/index.html" | sed '1d;$d')
+echo "$JSON" | jq -C .
+
+while [[ $# -gt 0 ]]; do
+  case "$1" in
+    --project)
+      if [[ $# -lt 2 ]]; then echo "ERROR -- Parameter for --project is missing!"; exit 1; fi
+      PROJECT="${2%%/}"; PROJECT="${PROJECT##/}"; shift 2
+      ;;
+    --current)
+      CURRENT=1
+      if [[ $# -ge 2 && ! "$2" =~ ^-- ]]; then
+        URL_BASE="/${2%%/}"; URL_BASE="${URL_BASE//\/\//\/}"; shift 2
+      else
+        shift
+      fi
+      ;;
+    --archived)
+      ARCHIVED=1
+      if [[ $# -ge 2 && ! "$2" =~ ^-- ]]; then
+        URL_BASE="/${2%%/}"; URL_BASE="${URL_BASE//\/\//\/}"; shift 2
+      else
+        shift
+      fi
+      ;;
+    --canonical)
+      if [[ $# -lt 2 ]]; then echo "ERROR -- Parameter for --canonical is missing!"; exit 1; fi
+      CANONICAL="/${2%%/}"; CANONICAL="${CANONICAL//\/\//\/}"; shift 2
+      ;;
+    *)
+      echo "ERROR -- Unknown parameter: $1"; echo; echo "$USAGE"; exit 1
+      ;;
+  esac
+done
+
+if [[ "$CURRENT" -eq 1 && "$ARCHIVED" -eq 1 ]]; then
+  echo "ERROR -- Only one of --current and --archived can be specified!"
+  echo; echo "$USAGE"; exit 1
+fi
+if [[ -n "$CANONICAL" && "$ARCHIVED" -eq 0 ]]; then
+  echo "ERROR -- --canonical can only be used with --archived!"
+  echo; echo "$USAGE"; exit 1
+fi
+if [[ "$CURRENT" -eq 0 && "$ARCHIVED" -eq 0 ]]; then
+  CURRENT=1
+fi
+[[ "$CURRENT" -eq 1 ]] && CURRENT_BOOL="true" || CURRENT_BOOL="false"
+
+[[ -z "$PROJECT" ]] && PROJECT=$(echo "$JSON" | jq -r '.artifactId')
+VERSION=$(echo "$JSON" | jq -r '.version')
+
+if [[ -z "$URL_BASE" ]]; then
+  if [[ "$CURRENT_BOOL" == "true" ]]; then
+    URL_BASE="/$PROJECT"
+  else
+    URL_BASE="/projects/$PROJECT/$VERSION"
+  fi
+fi
+URL_BASE="${URL_BASE%/}"
+
+[[ -z "$CANONICAL" ]] && CANONICAL="/$PROJECT"
+CANONICAL="${CANONICAL%/}"
+
+CONTENT_BASE="$ASTRO_ROOT/src/content/projects/$PROJECT/$VERSION"
+PUBLIC_BASE="$ASTRO_ROOT/public/projects/$PROJECT/$VERSION"
+
+if [[ "$CURRENT_BOOL" == "true" ]]; then
+  PAGES_BASE="$ASTRO_ROOT/src/pages/$PROJECT"
+  IMPORT_DEPTH="../../"
+else
+  PAGES_BASE="$ASTRO_ROOT/src/pages/projects/$PROJECT/$VERSION"
+  IMPORT_DEPTH="../../../../"
+fi
+
+echo ""
+echo "Project:   $PROJECT"
+echo "Version:   $VERSION"
+echo "Current:   $CURRENT_BOOL"
+echo "URL base:  $URL_BASE"
+[[ "$CURRENT_BOOL" == "false" ]] && echo "Canonical: $CANONICAL"
+echo ""
+
+# Generated-doc subdirectory names (must match GENERATED_DOC_NAMES in projects.ts)
+GENERATED_DOC_DIRS="apidocs testapidocs xref xref-test"
+
+for SOURCE in $(find "$SCRIPT_DIR" -maxdepth 1 -mindepth 1 -type f -name '*.html'); do
+  FILE=$(basename "$SOURCE")
+  PAGE_ENTRY=$(echo "$JSON" | jq '.pages|to_entries[]|select(.value.href == "'"$FILE"'")')
+
+  if [[ -z "$PAGE_ENTRY" ]]; then
+    echo "WARN: No page entry for $FILE — skipping"
+    continue
+  fi
+
+  PAGE=$(echo "$PAGE_ENTRY" | jq '.value')
+  WEIGHT=$(echo "$PAGE_ENTRY" | jq -r '.key')
+  # path field: pre-computed by site.vm as crumbs joined with .html→/ substitution
+  # e.g. "" for top-level, "project-reports/" for children of project-reports, etc.
+  PATH_PREFIX=$(echo "$PAGE" | jq -r '.path')
+  [[ -n "$PATH_PREFIX" && "${PATH_PREFIX: -1}" != "/" ]] && PATH_PREFIX="${PATH_PREFIX}/"
+  NUM_CHILDS=$(echo "$PAGE" | jq '.childs | length')
+  # Use jq to produce a JSON/YAML-safe double-quoted title string
+  TITLE_YAML=$(echo "$PAGE" | jq '.name')
+
+  if [[ "$FILE" == "index.html" ]]; then
+    CONTENT_REL="_index.html"
+    PAGE_URL="${URL_BASE}/"
+    ROUTING_FILE="index.astro"
+    CANONICAL_URL="${CANONICAL}/"
+  else
+    HREF="$FILE"
+    if [[ "$NUM_CHILDS" -gt 0 ]]; then
+      # Section node: becomes a subdirectory with _index.html
+      CONTENT_REL="${PATH_PREFIX}${HREF%.html}/_index.html"
+    else
+      CONTENT_REL="${PATH_PREFIX}${HREF}"
+    fi
+    # URLs are always flat (no nesting) — mirrors Maven's own flat site structure
+    PAGE_URL="${URL_BASE}/${HREF}"
+    ROUTING_FILE="${HREF%.html}.html.astro"
+    CANONICAL_URL="${CANONICAL}/${HREF}"
+  fi
+
+  CONTENT_TARGET="$CONTENT_BASE/$CONTENT_REL"
+  mkdir -p "$(dirname "$CONTENT_TARGET")"
+
+  {
+    echo "---"
+    echo "title: $TITLE_YAML"
+    echo "weight: $WEIGHT"
+    echo "url: $PAGE_URL"
+    echo "params:"
+    echo "  current: $CURRENT_BOOL"
+    if [[ "$CURRENT_BOOL" == "false" ]]; then
+      echo "  canonical: $CANONICAL_URL"
+    fi
+    echo "---"
+    # Extract body: strip the <h1 id="sili-title"> line (tail -n +2),
+    # and stop before the sili-json <script> block (only present in index.html).
+    sed -n '/<script id="sili-json" type="application\/json">/q;p' "$SOURCE" \
+      | tail -n +2
+  } > "$CONTENT_TARGET"
+
+  # Convert relative generated-doc directory links to absolute URLs with explicit
+  # /index.html, because these dirs live under /projects/X/Y/ regardless of whether
+  # the containing page is served from the visible URL (/<project>/...) or the
+  # archived URL (/projects/X/Y/...), so relative links cannot work for both.
+  for dir in $GENERATED_DOC_DIRS; do
+    sed -i \
+      -e "s|href=\"${dir}/\"|href=\"/projects/${PROJECT}/${VERSION}/${dir}/index.html\"|g" \
+      -e "s|href=\"${dir}/index\.html\"|href=\"/projects/${PROJECT}/${VERSION}/${dir}/index.html\"|g" \
+      "$CONTENT_TARGET"
+  done
+
+  echo "Content:  $CONTENT_TARGET"
+
+  ROUTING_TARGET="$PAGES_BASE/$ROUTING_FILE"
+  mkdir -p "$(dirname "$ROUTING_TARGET")"
+
+  ENTRY_ID="$PROJECT/$VERSION/$CONTENT_REL"
+
+  {
+    echo "---"
+    printf "import ProjectPage from '%scomponents/ProjectPage.astro';\n" "$IMPORT_DEPTH"
+    echo "---"
+    printf '<ProjectPage entryId="%s" />\n' "$ENTRY_ID"
+  } > "$ROUTING_TARGET"
+
+  echo "Routing:  $ROUTING_TARGET"
+done
+
+# Copy all subdirectories (apidocs, xref, css, images, …) to public/projects/X/Y/
+# generatedDocNodes() in projects.ts auto-detects the known ones as nav entries.
+mkdir -p "$PUBLIC_BASE"
+for DIR_PATH in $(find "$SCRIPT_DIR" -maxdepth 1 -mindepth 1 -type d); do
+  DIR=$(basename "$DIR_PATH")
+  echo "Static:   $DIR_PATH → $PUBLIC_BASE/$DIR"
+  cp -av "$DIR_PATH" "$PUBLIC_BASE/"
+done
+
+echo ""
+echo "Done! Imported $PROJECT $VERSION (current=$CURRENT_BOOL)"
+echo "  Content:  $CONTENT_BASE"
+echo "  Routing:  $PAGES_BASE"
+echo "  Static:   $PUBLIC_BASE"