Skip to content

Instantly share code, notes, and snippets.

@bact
Last active February 22, 2026 11:53
Show Gist options
  • Select an option

  • Save bact/5fb18cf8c5ed04f215cb41b7cf427a62 to your computer and use it in GitHub Desktop.

Select an option

Save bact/5fb18cf8c5ed04f215cb41b7cf427a62 to your computer and use it in GitHub Desktop.
Generate SPDX 3 model artifacts (RDFs, JSON-LD context, JSON Schema)
#!/usr/bin/env bash
#
# SPDX-License-Identifier: CC0-1.0
# SPDX-FileCopyrightText: 2026 Arthit Suriyawongkul
#
# Generate SPDX 3 model artifacts (RDFs, JSON-LD context, JSON Schema)
#
# This script will
# - fetch the latest version of SPDX 3 model from spdx-3-model
# - fetch a JSON-LD annotations from spdx-spec
# and
# - generate RDFs, JSON-LD context, and PlantUML diagram using spec-parser
# - generate JSON Schema using shacl2code
#
# Usage: ./gen-spdx3-model.sh <version> <output-dir>
#
# Example: ./gen-spdx3-model.sh 3.1 output
set -e
# Configurable options
REF_SPEC="${REF_SPEC:-develop}"
REF_MODEL="${REF_MODEL:-develop}"
REF_PARSER="${REF_PARSER:-main}"
if [ -z "$1" ] || [ -z "$2" ]; then
echo "Usage: $0 <version> <output-dir>"
exit 1
fi
VERSION="$1"
# Ensure output directory exists and get absolute path
mkdir -p "$2"
OUT_DIR=$(cd "$2" && pwd)
echo "Starting generation of SPDX 3 artifacts..."
echo "VERSION: $VERSION"
echo "OUT_DIR: $OUT_DIR"
# Create output subdirectories
mkdir -p "$OUT_DIR/rdf"
mkdir -p "$OUT_DIR/diagram"
# Create a temporary working directory
WORK_DIR=$(mktemp -d)
echo "Working directory: $WORK_DIR"
# Ensure cleanup on exit
cleanup() {
echo "Cleaning up temporary directory..."
rm -rf "$WORK_DIR"
}
trap cleanup EXIT
pushd "$WORK_DIR" > /dev/null
# Set up Python virtual environment
echo "=> Setting up Python virtual environment..."
python3 -m venv venv
source venv/bin/activate
pip install --upgrade pip
# 1. Fetch model Markdown files from spdx-3-model GitHub repo
echo "=> Fetching spdx-3-model (branch/tag: $REF_MODEL)..."
git clone --depth 1 -b "$REF_MODEL" https://github.com/spdx/spdx-3-model.git
# 2. Fetch spec-parser
echo "=> Fetching spec-parser (branch/tag: $REF_PARSER)..."
git clone --depth 1 -b "$REF_PARSER" https://github.com/spdx/spec-parser.git
echo "=> Installing spec-parser requirements..."
pip install -r spec-parser/requirements.txt
echo "=> Running spec-parser..."
python3 spec-parser/main.py --force \
--generate-rdf --output-rdf "$OUT_DIR/rdf" \
--generate-plantuml --output-plantuml "$OUT_DIR/diagram" \
spdx-3-model/model
if ls "$OUT_DIR/rdf/"*.dot >/dev/null 2>&1; then
mv "$OUT_DIR/rdf/"*.dot "$OUT_DIR/diagram/"
fi
# 3. Fetch spdx-spec for JSON-LD annotations
echo "=> Fetching spdx-spec (branch/tag: $REF_SPEC)..."
git clone --depth 1 -b "$REF_SPEC" https://github.com/spdx/spdx-spec.git
echo "=> Copying JSON annotations..."
cp spdx-spec/serialization/jsonld/annotations.ttl "$OUT_DIR/rdf/jsonld-annotations.ttl"
cp "$OUT_DIR/rdf/spdx-model.json-ld" "$OUT_DIR/rdf/spdx-model.jsonld"
# 4. Generate JSON Schema using shacl2code
echo "=> Generating JSON Schema using shacl2code..."
# Determine CONTEXT_URL by checking URLs in order of preference:
# 1. spdx.org (no "v" prefix, no suffix) (if not 404)
# 2. spdx.org (no "v" prefix) (if not 404)
# 3. spdx.github.io (fallback)
VER_WO_V=${VERSION#[vV]}
VER_CLEAN=$(echo "$VER_WO_V" | sed -E 's/-.*//')
URL_1="https://spdx.org/rdf/$VER_CLEAN/spdx-context.jsonld"
URL_2="https://spdx.org/rdf/$VER_WO_V/spdx-context.jsonld"
URL_3="https://spdx.github.io/spdx-spec/$VERSION/rdf/spdx-context.jsonld"
if curl --output /dev/null --silent --head --fail "$URL_1"; then
CONTEXT_URL="$URL_1"
elif [ "$URL_1" != "$URL_2" ] && curl --output /dev/null --silent --head --fail "$URL_2"; then
CONTEXT_URL="$URL_2"
else
CONTEXT_URL="$URL_3"
fi
echo "JSON-LD context document URL:"
echo "$CONTEXT_URL"
echo "=> Installing shacl2code..."
pip install shacl2code
shacl2code generate \
--input "$OUT_DIR/rdf/spdx-model.ttl" \
--input "$OUT_DIR/rdf/jsonld-annotations.ttl" \
--context-url "$OUT_DIR/rdf/spdx-context.jsonld" "$CONTEXT_URL" \
jsonschema \
--output "$OUT_DIR/rdf/schema.json"
popd > /dev/null
echo "=================================================="
echo "Artifacts generated from"
echo " - spdx-3-model (branch/tag: $REF_MODEL)"
echo " - spdx-spec (branch/tag: $REF_SPEC)"
echo "are successfully placed in:
echo "$OUT_DIR/"
echo ""
echo "JSON-LD context document URL:"
echo "$CONTEXT_URL"
echo "=================================================="
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment