Last active
February 22, 2026 11:53
-
-
Save bact/5fb18cf8c5ed04f215cb41b7cf427a62 to your computer and use it in GitHub Desktop.
Generate SPDX 3 model artifacts (RDFs, JSON-LD context, JSON Schema)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/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