blob: f155f7aaa77bb408c5ccc8a794a9cd224ddb056e [file]
#!/bin/bash
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
# Builds TinkerPop documentation using the gremlin-docs AsciidoctorJ extension.
# The extension delegates Gremlin code execution to a real Gremlin Console process,
# then generates language variant tabs via the ANTLR-based GremlinTranslator.
#
# Usage:
# bin/process-docs.sh # full build with live gremlin execution
# bin/process-docs.sh --dry-run # skip gremlin execution (fast, for layout checks)
set -e
PROJECT_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
cd "${PROJECT_ROOT}"
TP_VERSION=$(cat pom.xml | grep -A1 '<artifactId>tinkerpop</artifactId>' | grep '<version>' | sed -e 's/.*<version>//' -e 's/<\/version>.*//')
if [ -z "${TP_VERSION}" ]; then
echo "ERROR: Could not determine TinkerPop version from pom.xml"
exit 1
fi
ASCIIDOC_ATTRS=""
DRYRUN=false
if [ "$1" = "--dry-run" ]; then
DRYRUN=true
ASCIIDOC_ATTRS="-Dasciidoctor.attributes.gremlin-docs-dryrun=true"
echo "Dry-run mode: gremlin blocks will not be executed"
fi
echo "Building docs for TinkerPop ${TP_VERSION}..."
echo "Source: docs/src/"
echo "Output: target/docs/htmlsingle/"
# build and install the gremlin-docs extension (not part of the main reactor)
echo "Installing gremlin-docs extension..."
mvn install -f gremlin-docs/pom.xml -DskipTests -Denforcer.skip=true -q
GREMLIN_SERVER_PID=""
GEPHI_MOCK_PID=""
function cleanup() {
if [ -n "${GREMLIN_SERVER_PID}" ]; then
echo "Stopping Gremlin Server (PID ${GREMLIN_SERVER_PID})..."
kill ${GREMLIN_SERVER_PID} 2>/dev/null || true
wait ${GREMLIN_SERVER_PID} 2>/dev/null || true
fi
if [ -n "${GEPHI_MOCK_PID}" ]; then
kill ${GEPHI_MOCK_PID} 2>/dev/null || true
wait ${GEPHI_MOCK_PID} 2>/dev/null || true
fi
# clean up conf/hadoop from console home if we created it
if [ -n "${CONSOLE_HOME}" ] && [ -d "${CONSOLE_HOME}/conf/hadoop" ]; then
rm -rf "${CONSOLE_HOME}/conf/hadoop"
fi
}
trap cleanup EXIT
if [ "${DRYRUN}" = "false" ]; then
# locate the console distribution (must be built already via mvn install -pl :gremlin-console -am)
CONSOLE_HOME=$(ls -d "${PROJECT_ROOT}"/gremlin-console/target/apache-tinkerpop-gremlin-console-*-standalone 2>/dev/null | head -1)
if [ -z "${CONSOLE_HOME}" ] || [ ! -d "${CONSOLE_HOME}" ]; then
echo "ERROR: Gremlin Console distribution not found."
echo "Build it first: mvn clean install -pl :gremlin-console -am -DskipTests"
exit 1
fi
echo "Using console: ${CONSOLE_HOME}"
# install plugins needed for doc examples
# NOTE: neo4j-gremlin is excluded by default because its Spark jars conflict with
# spark-gremlin on the classpath. Neo4j examples will fall back to dry-run output.
# The old AWK pipeline handled this by swapping plugins per-document.
PLUGIN_DIR="${CONSOLE_HOME}/ext"
plugins=("hadoop-gremlin" "spark-gremlin" "sparql-gremlin")
for pluginName in "${plugins[@]}"; do
if [ ! -d "${PLUGIN_DIR}/${pluginName}" ]; then
echo "Installing plugin: ${pluginName}..."
pushd "${CONSOLE_HOME}" > /dev/null
bin/gremlin.sh -e <(echo ":install org.apache.tinkerpop ${pluginName} ${TP_VERSION}") 2>/dev/null || true
popd > /dev/null
else
echo "Plugin already installed: ${pluginName}"
fi
done
# activate plugins in plugins.txt if not already present
for pluginName in "${plugins[@]}"; do
# derive class name: hadoop-gremlin -> HadoopGremlinPlugin
className=""
for part in $(tr '-' '\n' <<< "${pluginName}"); do
className="${className}$(tr '[:lower:]' '[:upper:]' <<< "${part:0:1}")${part:1}"
done
pluginClassFile=$(find . -name "${className}Plugin.java" 2>/dev/null | head -1)
if [ -n "${pluginClassFile}" ]; then
pluginClass=$(sed -e 's@.*src/main/java/@@' -e 's/\.java$//' <<< "${pluginClassFile}" | tr '/' '.')
if ! grep -q "${pluginClass}" "${PLUGIN_DIR}/plugins.txt" 2>/dev/null; then
echo "${pluginClass}" >> "${PLUGIN_DIR}/plugins.txt"
fi
fi
done
# start Gremlin Server for remote connection examples
SERVER_HOME=$(ls -d "${PROJECT_ROOT}"/gremlin-server/target/apache-tinkerpop-gremlin-server-*-standalone 2>/dev/null | head -1)
if [ -n "${SERVER_HOME}" ] && [ -d "${SERVER_HOME}" ]; then
# check for port conflict before starting
if nc -z localhost 8182 2>/dev/null; then
echo "ERROR: Port 8182 is already in use. Stop the process using it before building docs."
exit 1
fi
echo "Starting Gremlin Server..."
mkdir -p target/docs-logs
pushd "${SERVER_HOME}" > /dev/null
bin/gremlin-server.sh conf/gremlin-server-modern.yaml > "${PROJECT_ROOT}/target/docs-logs/gremlin-server.log" 2>&1 &
GREMLIN_SERVER_PID=$!
popd > /dev/null
# wait for server to be ready (up to 30 seconds)
echo -n "Waiting for Gremlin Server on port 8182"
for i in $(seq 1 30); do
if nc -z localhost 8182 2>/dev/null; then
echo " ready."
break
fi
echo -n "."
sleep 1
done
if ! nc -z localhost 8182 2>/dev/null; then
echo " WARNING: Gremlin Server may not have started. Remote connection examples may fail."
fi
else
echo "WARNING: Gremlin Server distribution not found. Remote connection examples will fail."
echo "Build it first: mvn clean install -pl :gremlin-server -am -DskipTests"
fi
# set up conf/hadoop inside the console home so GraphFactory.open('conf/hadoop/...') resolves
# (the console process runs with CONSOLE_HOME as its working directory)
mkdir -p "${CONSOLE_HOME}/conf/hadoop"
cp "${PROJECT_ROOT}"/hadoop-gremlin/conf/* "${CONSOLE_HOME}/conf/hadoop/" 2>/dev/null || true
# start Gephi mock server for Gephi plugin examples (listens on port 8080)
if ! nc -z localhost 8080 2>/dev/null; then
"${PROJECT_ROOT}/bin/gephi-mock.py" > /dev/null 2>&1 &
GEPHI_MOCK_PID=$!
fi
HADOOP_LIBS="${CONSOLE_HOME}/ext/tinkergraph-gremlin/lib"
ASCIIDOC_ATTRS="${ASCIIDOC_ATTRS} -Dasciidoctor.attributes.gremlin-docs-console-home=${CONSOLE_HOME}"
ASCIIDOC_ATTRS="${ASCIIDOC_ATTRS} -Dasciidoctor.attributes.gremlin-docs-hadoop-libs=${HADOOP_LIBS}"
fi
# copy static assets that live outside docs/src/ into the staging area
mkdir -p target/doc-source
cp -r docs/static target/doc-source/ 2>/dev/null || true
cp -r docs/stylesheets target/doc-source/ 2>/dev/null || true
# run asciidoctor with the gremlin-docs extension
mvn process-resources \
-Dasciidoc \
-Drat.skip=true \
${ASCIIDOC_ATTRS}
# post-process: replace version placeholder
echo "Post-processing: replacing x.y.z with ${TP_VERSION}..."
find target/docs/htmlsingle -name '*.html' | while IFS= read -r f; do
sed "s/x\.y\.z/${TP_VERSION}/g" "$f" > "$f.tmp" && mv "$f.tmp" "$f"
done
echo "Done. Output in target/docs/htmlsingle/"