diff --git a/.github/workflows/runSchematronValidation.yml b/.github/workflows/runSchematronValidation.yml index 6ee59a13a..eda0b407e 100644 --- a/.github/workflows/runSchematronValidation.yml +++ b/.github/workflows/runSchematronValidation.yml @@ -25,6 +25,15 @@ jobs: steps: # Check-out the repository under $GITHUB_WORKSPACE - uses: actions/checkout@v2 + + - name: Cache + uses: actions/cache@v2.1.3 + with: + path: | + ~/resources/validations/lib/ + ~/oscal/ + /tmp/saxon/ + key: ${{ runner.os }}-${{ hashFiles('**/lockfiles') }} # Check-out submodules - name: Checkout submodules @@ -45,6 +54,7 @@ jobs: # convert schematron to xsl and validate file with converted xsl - name: Convert to XSL run: | + export SAXON_CP=/tmp/saxon/Saxon-HE-10.2.jar echo "convert to xsl" # compute name without .sch qualifiedSchematronName=${{ github.event.inputs.schematronFileName }} @@ -55,16 +65,25 @@ jobs: schematronRoot=${schematronName%.*} echo "schematronRoot: ${schematronRoot}" echo "schematron code ${{ github.workspace }}/resources/validations/lib/schematron/trunk/schematron/code/iso_svrl_for_xslt2.xsl" - mkdir /tmp/target - rm -rf /tmp/target/*.xsl; - `java -cp ${SAXON_CP} net.sf.saxon.Transform -o:/tmp/target/${schematronRoot}.xsl -s:${{ github.workspace }}${qualifiedSchematronName} ${{ github.workspace }}/resources/validations/lib/schematron/trunk/schematron/code/iso_svrl_for_xslt2.xsl` - + rm -rf ${{ github.workspace }}/resources/validations/target/*.xsl + + java -cp ${SAXON_CP} net.sf.saxon.Transform \ + -o:"${{ github.workspace }}/resources/validations/target/${schematronRoot}".xsl \ + -s:"${{ github.workspace }}/${qualifiedSchematronName}" \ + ${{ github.workspace }}/resources/validations/lib/schematron/trunk/schematron/code/iso_svrl_for_xslt2.xsl \ + allow-foreign=true + + reportName=${{ github.workspace }}/resources/validations/report/schematron${{ github.event.inputs.DOC_TO_VALIDATE }}__${schematronRoot}.results.xml + echo "delete pre-existing SVRL and HTML results" rm -rf "${reportName}" "${htmlReportName}" echo "validating doc: ${{ github.event.inputs.DOC_TO_VALIDATE }} with ${qualifiedSchematronName} output found in ${reportName}" + echo source + echo `ls -ltr ${{ github.workspace }}${{ github.event.inputs.DOC_TO_VALIDATE }}` java -cp "${SAXON_CP}" net.sf.saxon.Transform \ - -o:"${reportName}" -s:"${{ github.workspace }}/${{ github.event.inputs.DOC_TO_VALIDATE }}" \ - target/"${schematronRoot}".xsl \ - allow-foreign=true + -o:${reportName} \ + -s:${{ github.workspace }}${{ github.event.inputs.DOC_TO_VALIDATE }} \ + ${{ github.workspace }}/resources/validations/target/${schematronRoot}.xsl \ + allow-foreign=true \ No newline at end of file diff --git a/.gitignore b/.gitignore index 8568f3f84..fe26465f4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,6 @@ utils resources/validations/src/ssp.xsl resources/validations/report -resources/validations/target \ No newline at end of file +resources/validations/target +*.DS_Store +resources/validations/lib/**.jar diff --git a/resources/validations/README.md b/resources/validations/README.md index 092d86f11..7d2f6f993 100644 --- a/resources/validations/README.md +++ b/resources/validations/README.md @@ -17,23 +17,36 @@ project structure To validate xml files using schematron --- -example +*Prerequesite +if you haven't done it previously: to add the needed dependencies (declared by .gitmodules), run the following:* -`./validate_with_schematron.sh test/demo/FedRAMP-SSP-OSCAL-Template.xml` +`-f` *\* is the input file to be tested. ex: `-f test/demo/FedRAMP-SSP-OSCAL-Template.xml` -you must pass in a file name you want validated as argument `$1`. by default it will compile and validate the input with all `src/*.sch` files. +`-s` *\* schematron directory used to validate the file. Each .sch found within the specified directory will be compliled and generate a separate report. defaults to src relative to this script. ex: `-o ~/mySchematronDirectory` -if you wish to override the default version (currently 10.2) of `SAXON HE`, you may pass it as the argument `$2` +`-o` *\* is an the root of the report output. ex: `-o ~/dev` +`-v` *\* if you wish to override the default version (currently 10.2) of `SAXON HE`, that is downloaded and used if $SAXON_CP is not specified. ex: `-v 10.2.2` *Note, SAXON_CP is set as an Environment Variable. and `-v` is specified, the script will terminate due to inability to determine priority.* +example: + +`./bin/validate_with_schematron.sh -f test/demo/FedRAMP-SSP-OSCAL-Template.xml -o ~/dev -v 10.2.2` To Run Tests --- +*Prerequesite +if you haven't done it previously: to add the needed dependencies (declared by .gitmodules), run the following:* + +`git submodule update --init --recursive` + ```sh cd /path/to/fedramp-automation/resources/validations +#if you have a preferred version of a saxon jar downloaded export SAXON_CP as so export SAXON_CP=yourpath/Saxon-HE-X.Y.Z.jar +#set the test directory relative to project path, you may change if you prefer somehere else export TEST_DIR=$(pwd)/report/test +#execute xpec with the test harness that runs all tests lib/xspec/bin/xspec.sh -s -j test/test_all.xspec ``` diff --git a/resources/validations/bin/validate_with_schematron.sh b/resources/validations/bin/validate_with_schematron.sh index 45df19bdb..efbccc80a 100755 --- a/resources/validations/bin/validate_with_schematron.sh +++ b/resources/validations/bin/validate_with_schematron.sh @@ -1,33 +1,126 @@ #!/usr/bin/env bash - set -o pipefail -if [ ! -e "$1" ]; then +usage() { + if test -n "$1"; then + echo "$1" + echo + fi + echo "Usage: validate_with_schematron.sh [-s directoryName|-o reportDirectory|-v saxonVersionNumber|-h] -f file" + echo + echo " -f fileName the input file to be tested." + echo " -s directoryName schematron directory containing .sch files used to validate" + echo " -o rootDirectory is an the root of the report output." + echo " -v saxonVersionNumber if you wish to override the default version to be downloaded" + echo " -h display this help message" +} + +# output root defaults to report folder relative to this script +OUTPUT_ROOT="report/schematron" +# schematron directory validate the file with each .sch found defaults to src/*.sch relative to this script +SCHEMA_LOCATION_DIR="src" +## +## options ################################################################### +## +while echo "$1" | grep -- ^- > /dev/null 2>&1; do + case "$1" in + # input file to validate + -f) + shift + DOC_TO_VALIDATE="$1" + ;; + # saxon version + -v) + if test -n "$SAXON_CP"; then + echo "SAXON_CP is set to ${SAXON_CP} as an environment variable setting version using -v is invalid" + exit 1 + else + shift + SAXON_VERSION="$1" + fi + ;; + # schema directory location + -s) + shift + SCHEMA_LOCATION_DIR="$1" + ;; + # output directory root + -o) + shift + OUTPUT_ROOT="$1" + ;; + # Help! + -h) + usage + exit 0 + ;; + # Unknown option! + -*) + usage "Error: Unknown option: $1" + exit 1 + ;; + esac + shift +done + +echo output dir "${OUTPUT_ROOT}" +echo to val "$DOC_TO_VALIDATE"; +if test ! -e "$DOC_TO_VALIDATE" ; then echo "no file input for report, exiting" exit 1 +else + echo "doc requested to be validated: ${DOC_TO_VALIDATE}" fi -DOC_TO_VALIDATE="$1" -echo "doc requested to be validated: ${DOC_TO_VALIDATE}" # Delete pre-existing XSLT report rm -rf target/*.xsl; -SAXON_VERSION=$2 +#if version not specified default SAXON_VERSION=${SAXON_VERSION:-10.2} SAXON_OPTS="${SAXON_OPTS:-allow-foreign=true}" echo "using saxon version ${SAXON_VERSION}" -mvn -q org.apache.maven.plugins:maven-dependency-plugin:2.1:get \ - -DrepoUrl=https://mvnrepository.com/ \ - -DartifactId=Saxon-HE \ - -DgroupId=net.sf.saxon \ - -Dversion="${SAXON_VERSION}" +saxonLocation=saxon/Saxon-HE/"${SAXON_VERSION}"/Saxon-HE-"${SAXON_VERSION}".jar +if test -n "$SAXON_CP" ; then + echo SAXON_CP env variable used is "${SAXON_CP}" +elif command -v mvn &> /dev/null ;then + mvn -q org.apache.maven.plugins:maven-dependency-plugin:2.1:get \ + -DrepoUrl=https://mvnrepository.com/ \ + -DartifactId=Saxon-HE \ + -DgroupId=net.sf.saxon \ + -Dversion="${SAXON_VERSION}" + SAXON_CP=~/.m2/repository/net/sf/${saxonLocation} +elif command -v curl &> /dev/null; then + SAXON_CP=lib/Saxon-HE-"${SAXON_VERSION}".jar + curl -H "Accept: application/zip" -o "${SAXON_CP}" https://repo1.maven.org/maven2/net/sf/"${saxonLocation}" +else + echo "SAXON_CP environment variable is not set. mvn or curl is required to download dependencies, neither found, please install one and retry" + exit 1 +fi + + +if test -f "${SAXON_CP}" ; then + java -cp "${SAXON_CP}" net.sf.saxon.Transform -? + retval=$? + echo retVal: $retval + if test $retval -eq 0 ; then + echo Saxon JAR at classpath "${SAXON_CP}" is valid + else + echo Saxon JAR at classpath "${SAXON_CP}" does not contain net.sf.saxon.Transform + exit 1 + fi +else + echo Saxon JAR at classpath "${SAXON_CP}" is not present + exit 1 +fi # Delete pre-existing SVRL report -rm -rf report/schematron/*.results.xml +rm -rf "${OUTPUT_ROOT}/report/schematron/*.results.xml" +rm -rf "${OUTPUT_ROOT}/report/schematron/*.results.html" -for qualifiedSchematronName in src/*.sch; do +#in the future replace the for loop with an optional passed in directory or single schema file -f +for qualifiedSchematronName in "${SCHEMA_LOCATION_DIR}"/*.sch; do [ -e "${qualifiedSchematronName}" ] || continue # compute name without .sch @@ -35,9 +128,8 @@ for qualifiedSchematronName in src/*.sch; do schematronRoot=${schematronName%.*} # Use Saxon XSL transform to convert our Schematron to pure XSL 2.0 stylesheet - saxon_jar=~/.m2/repository/net/sf/saxon/Saxon-HE/"${SAXON_VERSION}"/Saxon-HE-"${SAXON_VERSION}".jar - - java -cp "${saxon_jar}" net.sf.saxon.Transform \ + # shellcheck disable=2086 + java -cp "${SAXON_CP}" net.sf.saxon.Transform \ -o:target/"${schematronRoot}".xsl \ -s:"${qualifiedSchematronName}" \ lib/schematron/trunk/schematron/code/iso_svrl_for_xslt2.xsl \ @@ -47,20 +139,22 @@ for qualifiedSchematronName in src/*.sch; do # Use Saxon XSL transform to use XSL-ified Schematron rules to analyze full FedRAMP-SSP-OSCAL template # and dump the result into reports. - reportName="report/schematron/${DOC_TO_VALIDATE}__${schematronRoot}.results.xml" - htmlReportName="report/html/${DOC_TO_VALIDATE}__${schematronRoot}.results.html" + reportName="${OUTPUT_ROOT}/${DOC_TO_VALIDATE}__${schematronRoot}.results.xml" + htmlReportName="${OUTPUT_ROOT}/${DOC_TO_VALIDATE}__${schematronRoot}.results.html" - echo "delete pre-existing SVRL and HTML results" rm -rf "${reportName}" "${htmlReportName}" echo "validating doc: ${DOC_TO_VALIDATE} with ${qualifiedSchematronName} output found in ${reportName}" - java -cp "${saxon_jar}" net.sf.saxon.Transform \ - -o:"${reportName}" -s:"${DOC_TO_VALIDATE}" \ + # shellcheck disable=2086 + java -cp "${SAXON_CP}" net.sf.saxon.Transform \ + -o:"${reportName}" \ + -s:"${DOC_TO_VALIDATE}" \ target/"${schematronRoot}".xsl \ $SAXON_OPTS - java -cp "${saxon_jar}" net.sf.saxon.Transform \ + # shellcheck disable=2086 + java -cp "${SAXON_CP}" net.sf.saxon.Transform \ -o:"${htmlReportName}" \ -s:"${reportName}" \ lib/svrl2html.xsl \