From 2c72a1bf844ad48ff4ba01ad88ebfcbed2179d42 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Tue, 2 Apr 2024 15:16:02 -0600 Subject: [PATCH 1/3] Feature #2379 sonarqube gha (#2847) * Per #2379, testing initial GHA SonarQube setup. * Per #2379, switch to only analyzing the src directory. * Per #2379, move more config logic from sonar-project.properties into the workflow. #ci-skip-all * Per #2379, try removing + symbols * Per #2379, move projectKey into xml workflow and remove sonar-project.properties. * Per #2379, try following the instructions at https://github.com/sonarsource-cfamily-examples/linux-autotools-gh-actions-sq/blob/main/.github/workflows/build.yml ci-skip-all * Per #2379, see details of progress described in this issue comment: https://github.com/dtcenter/MET/issues/2379#issuecomment-2000242425 * Unrelated to #2379, just removing spurious space that gets flagged as a diff when re-running enum_to_string on seneca. * Per #2379, try running SonarQube through GitHub. * Per #2379, remove empty env section and also disable the testing workflow temporarily during sonarqube development. * Per #2379, fix docker image name. * Per #2379, delete unneeded script. * Per #2379, update GHA to scan Python code and push to the correct SonarQube projects. * Per #2379, update GHA SonarQube project names * Per #2379, update the build job name * Per #2379, update the comile step name * Per #2379, switch to consistent SONAR variable names. * Per #2379, fix type in sed expressions. * Per #2379, just rename the log artifact * Per #2379, use time_command wrapper instead of run_command. * Per #2379, fix bad env var name * Per #2379, switch from egrep to grep. * Per #2379, just try cat-ting the logfile * Per #2379, test whether cat-ting the log file actually works. * Per #2379, revert back * Per #2379, mention SonarQube in the PR template. Make workflow name more succinct. * Per #2379, add SONAR_REFERENCE_BRANCH setting to define the sonar.newCode.referenceBranch property. The goal is to define the comparison reference branch for each SonarQube scan. * Per #2379, have the sonarqube.yml job print the reference branch it's using * Per #2379, intentionally introduce a new code smell to see if SonarQube correctly flag it as appearing in new code. * Per #2379, trying adding the SonarQube quality gate check. * Per #2379, add logic for using the report-task.txt output files to check the quality gate status for both the python and cxx scans. * Per #2379 must use unique GHA id's * Per #2379, working on syntax for quality gate checks * Per #2379, try again. * Per #2379, try again * Per #2379, try again * Per #2379, try again * Per #2379, try again * Per #2379, try again * Per #2379, try yet again * Per #2379 * Per #2379, add more debug * Per #2379, remove -it option from docker run commands * Per #2379, again * Per #2379, now that the scan works as expected, remove the intentional SonarQube code smell as well as debug logging. --- .github/jobs/build_docker_image.sh | 2 +- .github/jobs/build_sonarqube_image.sh | 46 ++++++ .github/pull_request_template.md | 3 + .github/workflows/sonarqube.yml | 103 +++++++++++++ internal/scripts/docker/Dockerfile.sonarqube | 95 ++++++++++++ .../scripts/docker/build_met_sonarqube.sh | 136 ++++++++++++++++++ .../sonarqube/python.sonar-project.properties | 12 +- internal/scripts/sonarqube/run_sonarqube.sh | 30 ++-- .../sonarqube/sonar-project.properties | 12 +- .../vx_config/configobjecttype_to_string.cc | 2 +- 10 files changed, 415 insertions(+), 26 deletions(-) create mode 100755 .github/jobs/build_sonarqube_image.sh create mode 100644 .github/workflows/sonarqube.yml create mode 100644 internal/scripts/docker/Dockerfile.sonarqube create mode 100755 internal/scripts/docker/build_met_sonarqube.sh diff --git a/.github/jobs/build_docker_image.sh b/.github/jobs/build_docker_image.sh index 47dc46e20a..f216c0aa0e 100755 --- a/.github/jobs/build_docker_image.sh +++ b/.github/jobs/build_docker_image.sh @@ -15,7 +15,7 @@ time_command docker build -t ${DOCKERHUB_TAG} \ --build-arg MET_CONFIG_OPTS \ -f $DOCKERFILE_PATH ${GITHUB_WORKSPACE} if [ $? != 0 ]; then - cat ${GITHUB_WORKSPACE}/docker_build.log + cat ${CMD_LOGFILE} exit 1 fi diff --git a/.github/jobs/build_sonarqube_image.sh b/.github/jobs/build_sonarqube_image.sh new file mode 100755 index 0000000000..9cdeea3395 --- /dev/null +++ b/.github/jobs/build_sonarqube_image.sh @@ -0,0 +1,46 @@ +#! /bin/bash + +source ${GITHUB_WORKSPACE}/.github/jobs/bash_functions.sh + +DOCKERHUB_TAG=met-sonarqube-gha + +DOCKERFILE_PATH=${GITHUB_WORKSPACE}/internal/scripts/docker/Dockerfile.sonarqube + +CMD_LOGFILE=${GITHUB_WORKSPACE}/sonarqube_build.log + +# +# Define the $SONAR_REFERENCE_BRANCH as the +# - Target of any requests +# - Manual setting for workflow dispatch +# - Source branch for any pushes (e.g. develop) +# +if [ "${GITHUB_EVENT_NAME}" == "pull_request" ]; then + export SONAR_REFERENCE_BRANCH=${GITHUB_BASE_REF} +elif [ "${GITHUB_EVENT_NAME}" == "workflow_dispatch" ]; then + export SONAR_REFERENCE_BRANCH=${WD_REFERENCE_BRANCH} +else + export SONAR_REFERENCE_BRANCH=${SOURCE_BRANCH} +fi + +echo SONAR_REFERENCE_BRANCH=${SONAR_REFERENCE_BRANCH} + +time_command docker build -t ${DOCKERHUB_TAG} \ + --build-arg MET_BASE_REPO \ + --build-arg MET_BASE_TAG \ + --build-arg SOURCE_BRANCH \ + --build-arg MET_CONFIG_OPTS \ + --build-arg SONAR_SCANNER_VERSION \ + --build-arg SONAR_HOST_URL \ + --build-arg SONAR_TOKEN \ + --build-arg SONAR_REFERENCE_BRANCH \ + -f $DOCKERFILE_PATH ${GITHUB_WORKSPACE} +if [ $? != 0 ]; then + cat ${CMD_LOGFILE} + exit 1 +fi + +# Copy the .scannerwork directory from the image +id=$(docker create ${DOCKERHUB_TAG}) +time_command docker cp $id:/met/.scannerwork /tmp/met_scannerwork +docker rm -v $id + diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index d3a97c7a05..0ed1004546 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -22,6 +22,9 @@ If **yes**, describe the new output and/or changes to the existing output:
- [ ] Will this PR result in changes to existing METplus Use Cases? **[Yes or No]**
If **yes**, create a new **Update Truth** [METplus issue](https://github.com/dtcenter/METplus/issues/new/choose) to describe them. +- [ ] Do these changes introduce new SonarQube findings? **[Yes or No]**
+If **yes**, please describe: + - [ ] Please complete this pull request review by **[Fill in date]**.
## Pull Request Checklist ## diff --git a/.github/workflows/sonarqube.yml b/.github/workflows/sonarqube.yml new file mode 100644 index 0000000000..36c2ccc02d --- /dev/null +++ b/.github/workflows/sonarqube.yml @@ -0,0 +1,103 @@ +name: SonarQube Scan + +# Run SonarQube for Pull Requests and changes to the develop and main_vX.Y branches + +on: + + # Trigger analysis for pushes to develop and main_vX.Y branches + push: + branches: + - develop + - 'main_v**' + paths-ignore: + - 'docs/**' + - '.github/pull_request_template.md' + - '.github/ISSUE_TEMPLATE/**' + - '.github/labels/**' + - '**/README.md' + - '**/LICENSE.md' + + # Trigger analysis for pull requests to develop and main_vX.Y branches + pull_request: + types: [opened, synchronize, reopened] + branches: + - develop + - 'main_v**' + paths-ignore: + - 'docs/**' + - '.github/pull_request_template.md' + - '.github/ISSUE_TEMPLATE/**' + - '.github/labels/**' + - '**/README.md' + - '**/LICENSE.md' + + workflow_dispatch: + inputs: + reference_branch: + description: 'Reference Branch' + default: develop + type: string + +jobs: + build: + name: SonarQube Scan + runs-on: ubuntu-latest + + steps: + + - uses: actions/checkout@v4 + with: + # Disable shallow clones for better analysis + fetch-depth: 0 + + - name: Create output directories + run: mkdir -p ${RUNNER_WORKSPACE}/logs + + - name: Get branch name + id: get_branch_name + run: echo branch_name=${GITHUB_REF#refs/heads/} >> $GITHUB_OUTPUT + + - name: SonarQube Scan in Docker + run: .github/jobs/build_sonarqube_image.sh + env: + MET_BASE_REPO: met-base + MET_BASE_TAG: v3.2 + SOURCE_BRANCH: ${{ steps.get_branch_name.outputs.branch_name }} + WD_REFERENCE_BRANCH: ${{ github.event.inputs.reference_branch }} + MET_CONFIG_OPTS: '--enable-all' + SONAR_SCANNER_VERSION: 5.0.1.3006 + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + + - name: SonarQube Python Quality Gate check + id: sonarqube-python-quality-gate-check + uses: sonarsource/sonarqube-quality-gate-action@master + with: + scanMetadataReportFile: /tmp/met_scannerwork/python-report-task.txt + timeout-minutes: 5 + env: + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + + - name: SonarQube CXX Quality Gate check + id: sonarqube-cxx-quality-gate-check + uses: sonarsource/sonarqube-quality-gate-action@master + with: + scanMetadataReportFile: /tmp/met_scannerwork/cxx-report-task.txt + timeout-minutes: 5 + env: + SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} + + - name: Copy log files into logs directory + if: always() + run: cp ${GITHUB_WORKSPACE}/*.log ${RUNNER_WORKSPACE}/logs/ + + - name: Upload logs as artifact + if: always() + uses: actions/upload-artifact@v4 + with: + name: logs_sonarqube + path: ${{ runner.workspace }}/logs + if-no-files-found: ignore + diff --git a/internal/scripts/docker/Dockerfile.sonarqube b/internal/scripts/docker/Dockerfile.sonarqube new file mode 100644 index 0000000000..156fa14bf7 --- /dev/null +++ b/internal/scripts/docker/Dockerfile.sonarqube @@ -0,0 +1,95 @@ +ARG MET_BASE_REPO=met-base +ARG MET_BASE_TAG=v3.2 + +FROM dtcenter/${MET_BASE_REPO}:${MET_BASE_TAG} +MAINTAINER John Halley Gotway + +# +# This Dockerfile checks out MET from GitHub and runs the +# SonarQube static code analysis on the specified branch or tag. +# https://docs.sonarqube.org/latest/analysis/scan/sonarscanner/ +# +ARG SONAR_SCANNER_VERSION=5.0.1.3006 +ARG SONAR_HOST_URL +ARG SONAR_TOKEN +ARG SOURCE_BRANCH +ARG SONAR_REFERENCE_BRANCH + +# +# SONAR_HOST_URL is required. +# +RUN if [ "x${SONAR_HOST_URL}" = "x" ]; then \ + echo "ERROR: SONAR_HOST_URL undefined! Rebuild with \"--build-arg SONAR_HOST_URL={url}\""; \ + exit 1; \ + fi + +# +# SONAR_TOKEN is required. +# +RUN if [ "x${SONAR_TOKEN}" = "x" ]; then \ + echo "ERROR: SONAR_TOKEN undefined! Rebuild with \"--build-arg SONAR_TOKEN={token}\""; \ + exit 1; \ + fi + +# +# SOURCE_BRANCH is the branch name of the MET source code. +# +RUN if [ "x${SOURCE_BRANCH}" = "x" ]; then \ + echo "ERROR: SOURCE_BRANCH undefined! Rebuild with \"--build-arg SOURCE_BRANCH={branch name}\""; \ + exit 1; \ + else \ + echo "Build Argument SOURCE_BRANCH=${SOURCE_BRANCH}"; \ + fi + +# +# SONAR_REFERENCE_BRANCH defines to the version against which this scan should be compared. +# +RUN if [ "x${SONAR_REFERENCE_BRANCH}" = "x" ]; then \ + echo "ERROR: SONAR_REFERENCE_BRANCH undefined! Rebuild with \"--build-arg SONAR_REFERENCE_BRANCH={branch name}\""; \ + exit 1; \ + else \ + echo "Build Argument SONAR_REFERENCE_BRANCH=${SONAR_REFERENCE_BRANCH}"; \ + fi + +ENV MET_GIT_NAME ${SOURCE_BRANCH} +ENV MET_REPO_DIR /met/MET-${MET_GIT_NAME} +ENV MET_GIT_URL https://github.com/dtcenter/MET + +# +# Download and install the Sonar software. +# +RUN echo "Installing SonarQube into $HOME/.sonar" \ + && mkdir -p $HOME/.sonar \ + && curl -sSLo $HOME/.sonar/sonar-scanner.zip https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-${SONAR_SCANNER_VERSION}-linux.zip \ + && unzip -o $HOME/.sonar/sonar-scanner.zip -d $HOME/.sonar/ \ + && echo export PATH="$HOME/.sonar/sonar-scanner-${SONAR_SCANNER_VERSION}-linux/bin:\$PATH" >> $HOME/.bashrc \ + && curl -sSLo $HOME/.sonar/build-wrapper-linux-x86.zip ${SONAR_HOST_URL}/static/cpp/build-wrapper-linux-x86.zip \ + && unzip -o $HOME/.sonar/build-wrapper-linux-x86.zip -d $HOME/.sonar/ \ + && echo export PATH="$HOME/.sonar/build-wrapper-linux-x86:\$PATH" >> $HOME/.bashrc + +# +# Update the OS, as needed. +# +RUN apt update + +# +# Set the working directory. +# +WORKDIR /met + +# +# Copy MET Download and install MET. +# +RUN echo "Copying MET into ${MET_REPO_DIR}" \ + && mkdir -p ${MET_REPO_DIR} + +COPY . ${MET_REPO_DIR} + +RUN if [ ! -e "${MET_REPO_DIR}/configure.ac" ]; then \ + echo "ERROR: docker build must be run from the MET directory: `ls`"; \ + exit 1; \ + fi + +RUN cd ${MET_REPO_DIR} \ + && internal/scripts/docker/build_met_sonarqube.sh + diff --git a/internal/scripts/docker/build_met_sonarqube.sh b/internal/scripts/docker/build_met_sonarqube.sh new file mode 100755 index 0000000000..5f3c13aecc --- /dev/null +++ b/internal/scripts/docker/build_met_sonarqube.sh @@ -0,0 +1,136 @@ +#!/bin/bash +# +# Run SonarQube Source Code Analyzer within a Docker container +#======================================================================= +# +# This build_met_sonarqube.sh script must be run from the top-level +# directory of the MET repository to be analyzed. It runs SonarQube to +# scan both the Python and C/C++ MET source code. +# +# Usage: internal/scripts/docker/build_met_sonarqube.sh +# +# Required Enviornment Variables: +# SONAR_HOST_URL +# SONAR_TOKEN +# MET_GIT_NAME +# SONAR_REFERENCE_BRANCH +# +#======================================================================= + +# Check that this is being run from the top-level MET directory +if [ ! -e internal/scripts/docker/build_met_sonarqube.sh ]; then + echo "ERROR: ${0} -> must be run from the top-level MET directory" + exit 1 +fi + +echo "Running script to scan MET with SonarQube in Docker" + +# Source the docker build environment +source ~/.bashrc +source internal/scripts/environment/development.docker +source .github/jobs/bash_functions.sh + +# Check required environment variables +if [ -z ${SONAR_HOST_URL+x} ]; then + echo "ERROR: ${0} -> \$SONAR_HOST_URL not defined!" + exit 1 +fi +if [ -z ${SONAR_TOKEN+x} ]; then + echo "ERROR: ${0} -> \$SONAR_TOKEN not defined!" + exit 1 +fi +if [ -z ${MET_GIT_NAME+x} ]; then + echo "ERROR: ${0} -> \$MET_GIT_NAME not defined!" + exit 1 +fi +if [ -z ${SONAR_REFERENCE_BRANCH+x} ]; then + echo "ERROR: ${0} -> \$SONAR_REFERENCE_BRANCH not defined!" + exit 1 +fi + +# Check whether MET_CONFIG_OPTS is defined +if [ -z ${MET_CONFIG_OPTS+x} ]; then + MET_CONFIG_OPTS='--enable-all' + echo "Setting MET_CONFIG_OPTS=${MET_CONFIG_OPTS} to scan all available options." +fi + +# Locate the wrapper +WRAPPER_NAME=build-wrapper-linux-x86-64 +SONAR_WRAPPER=$(which $WRAPPER_NAME 2> /dev/null) + +if [ ! -e $SONAR_WRAPPER ]; then + echo "ERROR: ${0} -> $WRAPPER_NAME not found in the path" + exit 1 +else + echo "SONAR_WRAPPER=$SONAR_WRAPPER" +fi + +# Locate the scanner +SCANNER_NAME=sonar-scanner +SONAR_SCANNER=$(which $SCANNER_NAME 2> /dev/null) + +if [ ! -e $SONAR_SCANNER ]; then + echo "ERROR: ${0} -> $SCANNER_NAME not found in the path" + exit 1 +else + echo "SONAR_SCANNER=$SONAR_SCANNER" +fi + +# Set output directory name +if [ -z ${SONARQUBE_OUT_DIR} ]; then + export SONARQUBE_OUT_DIR=bw-outputs +fi + +# Store the full path to the scripts directory +SONAR_PROPERTIES_DIR=internal/scripts/sonarqube +SONAR_PROPERTIES=sonar-project.properties + +# Copy sonar-project.properties for Python code +[ -e $SONAR_PROPERTIES ] && rm $SONAR_PROPERTIES +sed -e "s|SONAR_TOKEN|$SONAR_TOKEN|" \ + -e "s|SONAR_HOST_URL|$SONAR_HOST_URL|" \ + -e "s|SONAR_PROJECT_KEY|MET-GHA-Python|" \ + -e "s|SONAR_PROJECT_NAME|MET GHA Python|" \ + -e "s|SONAR_BRANCH_NAME|$MET_GIT_NAME|" \ + -e "s|SONAR_REFERENCE_BRANCH|$SONAR_REFERENCE_BRANCH|" \ + $SONAR_PROPERTIES_DIR/python.sonar-project.properties > $SONAR_PROPERTIES + +# Run SonarQube scan for Python code +time_command $SONAR_SCANNER + +# Copy the Python scan report-task.txt file +mkdir -p /met/.scannerwork +cp .scannerwork/report-task.txt /met/.scannerwork/python-report-task.txt + +# Copy sonar-project.properties for C/C++ code +[ -e $SONAR_PROPERTIES ] && rm $SONAR_PROPERTIES +sed -e "s|SONAR_TOKEN|$SONAR_TOKEN|" \ + -e "s|SONAR_HOST_URL|$SONAR_HOST_URL|" \ + -e "s|SONAR_PROJECT_KEY|MET-GHA-CXX|" \ + -e "s|SONAR_PROJECT_NAME|MET GHA CXX|" \ + -e "s|SONAR_BRANCH_NAME|$MET_GIT_NAME|" \ + -e "s|SONAR_REFERENCE_BRANCH|$SONAR_REFERENCE_BRANCH|" \ + $SONAR_PROPERTIES_DIR/sonar-project.properties > $SONAR_PROPERTIES + +# Run the configure script +time_command ./configure \ + BUFRLIB_NAME=${BUFRLIB_NAME} \ + GRIB2CLIB_NAME=${GRIB2CLIB_NAME} \ + ${MET_CONFIG_OPTS} \ + CPPFLAGS="-I/usr/local/include -I/usr/local/include/freetype2 -I/usr/local/include/cairo" \ + LIBS="-ltirpc" + +# Run make clean +time_command make clean + +# Run SonarQube make +time_command $SONAR_WRAPPER --out-dir $SONARQUBE_OUT_DIR make + +# Run SonarQube scan for C/C++ code +time_command $SONAR_SCANNER + +# Copy the C/C++ scan report-task.txt file +mkdir -p /met/.scannerwork +cp .scannerwork/report-task.txt /met/.scannerwork/cxx-report-task.txt + +[ -e $SONAR_PROPERTIES ] && rm $SONAR_PROPERTIES diff --git a/internal/scripts/sonarqube/python.sonar-project.properties b/internal/scripts/sonarqube/python.sonar-project.properties index f304a07204..98b30436d7 100644 --- a/internal/scripts/sonarqube/python.sonar-project.properties +++ b/internal/scripts/sonarqube/python.sonar-project.properties @@ -1,5 +1,5 @@ -sonar.projectKey=MET_python_NB -sonar.projectName=MET python Nightly Build +sonar.projectKey=SONAR_PROJECT_KEY +sonar.projectName=SONAR_PROJECT_NAME sonar.projectVersion=1.0 sonar.sources=scripts/python,data/wrappers @@ -11,8 +11,8 @@ sonar.python.version=3.6.3 sonar.sourceEncoding=UTF-8 #----- Default SonarQube server -#sonar.host.url=http://localhost:9000 -sonar.host.url=SONAR_SERVER_URL +sonar.host.url=SONAR_HOST_URL -sonar.token=SONAR_TOKEN_VALUE -sonar.branch.name=develop +sonar.token=SONAR_TOKEN +sonar.branch.name=SONAR_BRANCH_NAME +sonar.newCode.referenceBranch=SONAR_REFERENCE_BRANCH diff --git a/internal/scripts/sonarqube/run_sonarqube.sh b/internal/scripts/sonarqube/run_sonarqube.sh index 31264f2f9b..0509a4a86d 100755 --- a/internal/scripts/sonarqube/run_sonarqube.sh +++ b/internal/scripts/sonarqube/run_sonarqube.sh @@ -111,13 +111,7 @@ run_command "git checkout ${1}" export MET_DEVELOPMENT=true # Run the configure script -run_command "./configure --prefix=`pwd` \ - --enable-grib2 \ - --enable-modis \ - --enable-mode_graphics \ - --enable-lidar2nc \ - --enable-python \ - --enable-ugrid" +run_command "./configure --prefix=`pwd` --enable-all" # Set the build id #BUILD_ID="MET-${1}" @@ -126,19 +120,31 @@ SONAR_PROPERTIES=sonar-project.properties # Copy sonar-project.properties for Python code [ -e $SONAR_PROPERTIES ] && rm $SONAR_PROPERTIES -[ -z "$SONAR_SERVER_URL" ] && SONAR_SERVER_URL="http://localhost:9000" -if [ -z "$SONAR_TOKEN_VALUE" ]; then - echo " == ERROR == SONAR_TOKEN_VALUE is not defined" +[ -z "$SONAR_HOST_URL" ] && SONAR_HOST_URL="http://localhost:9000" +if [ -z "$SONAR_TOKEN" ]; then + echo " == ERROR == SONAR_TOKEN is not defined" exit 1 else - sed -e "s|SONAR_TOKEN_VALUE|$SONAR_TOKEN_VALUE|" -e "s|SONAR_SERVER_URL|$SONAR_SERVER_URL|" $SCRIPT_DIR/python.sonar-project.properties > $SONAR_PROPERTIES + sed -e "s|SONAR_TOKEN|$SONAR_TOKEN|" \ + -e "s|SONAR_HOST_URL|$SONAR_HOST_URL|" \ + -e "s|SONAR_PROJECT_KEY|MET_python_NB|" \ + -e "s|SONAR_PROJECT_NAME|MET python Nightly Build|" \ + -e "s|SONAR_BRANCH_NAME|develop|" \ + -e "s|SONAR_REFERENCE_BRANCH|develop|" \ + $SCRIPT_DIR/python.sonar-project.properties > $SONAR_PROPERTIES # Run SonarQube scan for Python code run_command "$SONAR_SCANNER" # Copy sonar-project.properties for C/C++ code [ -e $SONAR_PROPERTIES ] && rm $SONAR_PROPERTIES - sed -e "s|SONAR_TOKEN_VALUE|$SONAR_TOKEN_VALUE|" -e "s|SONAR_SERVER_URL|$SONAR_SERVER_URL|" $SCRIPT_DIR/sonar-project.properties > $SONAR_PROPERTIES + sed -e "s|SONAR_TOKEN|$SONAR_TOKEN|" \ + -e "s|SONAR_HOST_URL|$SONAR_HOST_URL|" \ + -e "s|SONAR_PROJECT_KEY|MET_develop_NB|" \ + -e "s|SONAR_PROJECT_NAME|MET Nightly Build|" \ + -e "s|SONAR_BRANCH_NAME|develop|" \ + -e "s|SONAR_REFERENCE_BRANCH|develop|" \ + $SCRIPT_DIR/sonar-project.properties > $SONAR_PROPERTIES # Run SonarQube clean run_command "make clean" diff --git a/internal/scripts/sonarqube/sonar-project.properties b/internal/scripts/sonarqube/sonar-project.properties index ec39576c4f..f486654e21 100644 --- a/internal/scripts/sonarqube/sonar-project.properties +++ b/internal/scripts/sonarqube/sonar-project.properties @@ -1,5 +1,5 @@ -sonar.projectKey=MET_develop_NB -sonar.projectName=MET Nightly Build +sonar.projectKey=SONAR_PROJECT_KEY +sonar.projectName=SONAR_PROJECT_NAME sonar.projectVersion=1.0 sonar.sources=src @@ -11,8 +11,8 @@ sonar.cfamily.build-wrapper-output=bw-outputs sonar.sourceEncoding=UTF-8 #----- Default SonarQube server -#sonar.host.url=http://localhost:9000 -sonar.host.url=SONAR_SERVER_URL +sonar.host.url=SONAR_HOST_URL -sonar.token=SONAR_TOKEN_VALUE -sonar.branch.name=develop +sonar.token=SONAR_TOKEN +sonar.branch.name=SONAR_BRANCH_NAME +sonar.newCode.referenceBranch=SONAR_REFERENCE_BRANCH diff --git a/src/basic/vx_config/configobjecttype_to_string.cc b/src/basic/vx_config/configobjecttype_to_string.cc index d8088d406c..8bb9f296b8 100644 --- a/src/basic/vx_config/configobjecttype_to_string.cc +++ b/src/basic/vx_config/configobjecttype_to_string.cc @@ -62,7 +62,7 @@ switch ( t ) { } // switch -return ConcatString (s); +return ConcatString(s); } From a72e8c56745bc3b500ff2c088363060c70222e0c Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Tue, 2 Apr 2024 15:56:19 -0600 Subject: [PATCH 2/3] Hotfix related to #2379. The sonar.newCode.referenceBranch and sonar.branch.name cannot be set to the same string! Only add the newCode definition when they differ. --- internal/scripts/docker/build_met_sonarqube.sh | 10 ++++++++++ .../scripts/sonarqube/python.sonar-project.properties | 1 - internal/scripts/sonarqube/run_sonarqube.sh | 2 -- internal/scripts/sonarqube/sonar-project.properties | 1 - 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/internal/scripts/docker/build_met_sonarqube.sh b/internal/scripts/docker/build_met_sonarqube.sh index 5f3c13aecc..f726d8b3b9 100755 --- a/internal/scripts/docker/build_met_sonarqube.sh +++ b/internal/scripts/docker/build_met_sonarqube.sh @@ -95,6 +95,11 @@ sed -e "s|SONAR_TOKEN|$SONAR_TOKEN|" \ -e "s|SONAR_REFERENCE_BRANCH|$SONAR_REFERENCE_BRANCH|" \ $SONAR_PROPERTIES_DIR/python.sonar-project.properties > $SONAR_PROPERTIES +# The source and reference branches must differ to define new code +if [ "$MET_GIT_NAME" != "$SONAR_REFERENCE_BRANCH" ]; then + echo "sonar.newCode.referenceBranch=${SONAR_REFERENCE_BRANCH}" >> $SONAR_PROPERTIES +fi + # Run SonarQube scan for Python code time_command $SONAR_SCANNER @@ -112,6 +117,11 @@ sed -e "s|SONAR_TOKEN|$SONAR_TOKEN|" \ -e "s|SONAR_REFERENCE_BRANCH|$SONAR_REFERENCE_BRANCH|" \ $SONAR_PROPERTIES_DIR/sonar-project.properties > $SONAR_PROPERTIES +# The source and reference branches must differ to define new code +if [ "$MET_GIT_NAME" != "$SONAR_REFERENCE_BRANCH" ]; then + echo "sonar.newCode.referenceBranch=${SONAR_REFERENCE_BRANCH}" >> $SONAR_PROPERTIES +fi + # Run the configure script time_command ./configure \ BUFRLIB_NAME=${BUFRLIB_NAME} \ diff --git a/internal/scripts/sonarqube/python.sonar-project.properties b/internal/scripts/sonarqube/python.sonar-project.properties index 98b30436d7..71b6b36b71 100644 --- a/internal/scripts/sonarqube/python.sonar-project.properties +++ b/internal/scripts/sonarqube/python.sonar-project.properties @@ -15,4 +15,3 @@ sonar.host.url=SONAR_HOST_URL sonar.token=SONAR_TOKEN sonar.branch.name=SONAR_BRANCH_NAME -sonar.newCode.referenceBranch=SONAR_REFERENCE_BRANCH diff --git a/internal/scripts/sonarqube/run_sonarqube.sh b/internal/scripts/sonarqube/run_sonarqube.sh index 0509a4a86d..917158b461 100755 --- a/internal/scripts/sonarqube/run_sonarqube.sh +++ b/internal/scripts/sonarqube/run_sonarqube.sh @@ -130,7 +130,6 @@ else -e "s|SONAR_PROJECT_KEY|MET_python_NB|" \ -e "s|SONAR_PROJECT_NAME|MET python Nightly Build|" \ -e "s|SONAR_BRANCH_NAME|develop|" \ - -e "s|SONAR_REFERENCE_BRANCH|develop|" \ $SCRIPT_DIR/python.sonar-project.properties > $SONAR_PROPERTIES # Run SonarQube scan for Python code @@ -143,7 +142,6 @@ else -e "s|SONAR_PROJECT_KEY|MET_develop_NB|" \ -e "s|SONAR_PROJECT_NAME|MET Nightly Build|" \ -e "s|SONAR_BRANCH_NAME|develop|" \ - -e "s|SONAR_REFERENCE_BRANCH|develop|" \ $SCRIPT_DIR/sonar-project.properties > $SONAR_PROPERTIES # Run SonarQube clean diff --git a/internal/scripts/sonarqube/sonar-project.properties b/internal/scripts/sonarqube/sonar-project.properties index f486654e21..c09f1d31b1 100644 --- a/internal/scripts/sonarqube/sonar-project.properties +++ b/internal/scripts/sonarqube/sonar-project.properties @@ -15,4 +15,3 @@ sonar.host.url=SONAR_HOST_URL sonar.token=SONAR_TOKEN sonar.branch.name=SONAR_BRANCH_NAME -sonar.newCode.referenceBranch=SONAR_REFERENCE_BRANCH From e71debf96065a7e43e7e861258fab473f34ac382 Mon Sep 17 00:00:00 2001 From: John Halley Gotway Date: Mon, 8 Apr 2024 09:37:29 -0600 Subject: [PATCH 3/3] Feature #2379 develop sonarqube updates (#2850) * Per #2379, move rgb2ctable.py into the python utility scripts directory for better organization and to enable convenient SonarQube scanning. * Per #2379, remove point.py from the vx_python3_utils directory which cleary was inadvertenlty added during development 4 years ago. As far as I can tell it isn't being called by any other code and doesn't belong in the repository. Note that scripts/python/met/point.py has the same name but is entirely different. * Per #2379, update the GHA SonarQube scan to do a single one with Python and C++ combined. The nightly build script is still doing 2 separate scans for now. If this all works well, they could also be combined into a single one. * Per #2379, eliminate MET_CONFIG_OPTIONS from the SonarQube workflow since it doesn't need to be and probably shouldn't be configurable. * Per #2379, trying to copy report-task.txt out of the image * Per #2379, update build_met_sonarqube.sh to check the scan return status * Per #2379, fix bash assignment syntax * Per #2379, remove unused SCRIPT_DIR envvar * Per #2379, switch to a single SonarQube scan for MET's nightly build as well --- .github/jobs/build_sonarqube_image.sh | 5 +- .github/workflows/sonarqube.yml | 18 +----- internal/scripts/docker/Dockerfile.sonarqube | 1 - .../scripts/docker/build_met_sonarqube.sh | 62 +++++++------------ .../sonarqube/python.sonar-project.properties | 17 ----- internal/scripts/sonarqube/run_sonarqube.sh | 44 +++++-------- .../sonarqube/sonar-project.properties | 16 +++-- .../python/utility}/rgb2ctable.py | 0 src/libcode/vx_python3_utils/point.py | 39 ------------ 9 files changed, 49 insertions(+), 153 deletions(-) delete mode 100644 internal/scripts/sonarqube/python.sonar-project.properties rename {data/colortables/NCL_colortables => scripts/python/utility}/rgb2ctable.py (100%) delete mode 100644 src/libcode/vx_python3_utils/point.py diff --git a/.github/jobs/build_sonarqube_image.sh b/.github/jobs/build_sonarqube_image.sh index 9cdeea3395..55d558624b 100755 --- a/.github/jobs/build_sonarqube_image.sh +++ b/.github/jobs/build_sonarqube_image.sh @@ -28,7 +28,6 @@ time_command docker build -t ${DOCKERHUB_TAG} \ --build-arg MET_BASE_REPO \ --build-arg MET_BASE_TAG \ --build-arg SOURCE_BRANCH \ - --build-arg MET_CONFIG_OPTS \ --build-arg SONAR_SCANNER_VERSION \ --build-arg SONAR_HOST_URL \ --build-arg SONAR_TOKEN \ @@ -41,6 +40,6 @@ fi # Copy the .scannerwork directory from the image id=$(docker create ${DOCKERHUB_TAG}) -time_command docker cp $id:/met/.scannerwork /tmp/met_scannerwork +time_command mkdir -p /tmp/scannerwork +time_command docker cp $id:/met/.scannerwork/report-task.txt /tmp/scannerwork/report-task.txt docker rm -v $id - diff --git a/.github/workflows/sonarqube.yml b/.github/workflows/sonarqube.yml index 36c2ccc02d..6a6627fb69 100644 --- a/.github/workflows/sonarqube.yml +++ b/.github/workflows/sonarqube.yml @@ -64,26 +64,15 @@ jobs: MET_BASE_TAG: v3.2 SOURCE_BRANCH: ${{ steps.get_branch_name.outputs.branch_name }} WD_REFERENCE_BRANCH: ${{ github.event.inputs.reference_branch }} - MET_CONFIG_OPTS: '--enable-all' SONAR_SCANNER_VERSION: 5.0.1.3006 SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - - name: SonarQube Python Quality Gate check - id: sonarqube-python-quality-gate-check + - name: SonarQube Quality Gate check + id: sonarqube-quality-gate-check uses: sonarsource/sonarqube-quality-gate-action@master with: - scanMetadataReportFile: /tmp/met_scannerwork/python-report-task.txt - timeout-minutes: 5 - env: - SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} - - - name: SonarQube CXX Quality Gate check - id: sonarqube-cxx-quality-gate-check - uses: sonarsource/sonarqube-quality-gate-action@master - with: - scanMetadataReportFile: /tmp/met_scannerwork/cxx-report-task.txt + scanMetadataReportFile: /tmp/scannerwork/report-task.txt timeout-minutes: 5 env: SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }} @@ -100,4 +89,3 @@ jobs: name: logs_sonarqube path: ${{ runner.workspace }}/logs if-no-files-found: ignore - diff --git a/internal/scripts/docker/Dockerfile.sonarqube b/internal/scripts/docker/Dockerfile.sonarqube index 156fa14bf7..75dc3c952c 100644 --- a/internal/scripts/docker/Dockerfile.sonarqube +++ b/internal/scripts/docker/Dockerfile.sonarqube @@ -92,4 +92,3 @@ RUN if [ ! -e "${MET_REPO_DIR}/configure.ac" ]; then \ RUN cd ${MET_REPO_DIR} \ && internal/scripts/docker/build_met_sonarqube.sh - diff --git a/internal/scripts/docker/build_met_sonarqube.sh b/internal/scripts/docker/build_met_sonarqube.sh index f726d8b3b9..45e1d10fc5 100755 --- a/internal/scripts/docker/build_met_sonarqube.sh +++ b/internal/scripts/docker/build_met_sonarqube.sh @@ -5,7 +5,7 @@ # # This build_met_sonarqube.sh script must be run from the top-level # directory of the MET repository to be analyzed. It runs SonarQube to -# scan both the Python and C/C++ MET source code. +# scan the MET source code. # # Usage: internal/scripts/docker/build_met_sonarqube.sh # @@ -48,12 +48,6 @@ if [ -z ${SONAR_REFERENCE_BRANCH+x} ]; then exit 1 fi -# Check whether MET_CONFIG_OPTS is defined -if [ -z ${MET_CONFIG_OPTS+x} ]; then - MET_CONFIG_OPTS='--enable-all' - echo "Setting MET_CONFIG_OPTS=${MET_CONFIG_OPTS} to scan all available options." -fi - # Locate the wrapper WRAPPER_NAME=build-wrapper-linux-x86-64 SONAR_WRAPPER=$(which $WRAPPER_NAME 2> /dev/null) @@ -81,52 +75,33 @@ if [ -z ${SONARQUBE_OUT_DIR} ]; then export SONARQUBE_OUT_DIR=bw-outputs fi +# Define the version string +SONAR_PROJECT_VERSION=$(cat docs/version | cut -d'=' -f2 | tr -d '" ') + # Store the full path to the scripts directory SONAR_PROPERTIES_DIR=internal/scripts/sonarqube SONAR_PROPERTIES=sonar-project.properties -# Copy sonar-project.properties for Python code +# Configure the sonar-project.properties [ -e $SONAR_PROPERTIES ] && rm $SONAR_PROPERTIES -sed -e "s|SONAR_TOKEN|$SONAR_TOKEN|" \ +sed -e "s|SONAR_PROJECT_KEY|MET-GHA|" \ + -e "s|SONAR_PROJECT_NAME|MET GHA|" \ + -e "s|SONAR_PROJECT_VERSION|$SONAR_PROJECT_VERSION|" \ -e "s|SONAR_HOST_URL|$SONAR_HOST_URL|" \ - -e "s|SONAR_PROJECT_KEY|MET-GHA-Python|" \ - -e "s|SONAR_PROJECT_NAME|MET GHA Python|" \ + -e "s|SONAR_TOKEN|$SONAR_TOKEN|" \ -e "s|SONAR_BRANCH_NAME|$MET_GIT_NAME|" \ - -e "s|SONAR_REFERENCE_BRANCH|$SONAR_REFERENCE_BRANCH|" \ - $SONAR_PROPERTIES_DIR/python.sonar-project.properties > $SONAR_PROPERTIES + $SONAR_PROPERTIES_DIR/$SONAR_PROPERTIES > $SONAR_PROPERTIES # The source and reference branches must differ to define new code if [ "$MET_GIT_NAME" != "$SONAR_REFERENCE_BRANCH" ]; then echo "sonar.newCode.referenceBranch=${SONAR_REFERENCE_BRANCH}" >> $SONAR_PROPERTIES fi - -# Run SonarQube scan for Python code -time_command $SONAR_SCANNER - -# Copy the Python scan report-task.txt file -mkdir -p /met/.scannerwork -cp .scannerwork/report-task.txt /met/.scannerwork/python-report-task.txt - -# Copy sonar-project.properties for C/C++ code -[ -e $SONAR_PROPERTIES ] && rm $SONAR_PROPERTIES -sed -e "s|SONAR_TOKEN|$SONAR_TOKEN|" \ - -e "s|SONAR_HOST_URL|$SONAR_HOST_URL|" \ - -e "s|SONAR_PROJECT_KEY|MET-GHA-CXX|" \ - -e "s|SONAR_PROJECT_NAME|MET GHA CXX|" \ - -e "s|SONAR_BRANCH_NAME|$MET_GIT_NAME|" \ - -e "s|SONAR_REFERENCE_BRANCH|$SONAR_REFERENCE_BRANCH|" \ - $SONAR_PROPERTIES_DIR/sonar-project.properties > $SONAR_PROPERTIES -# The source and reference branches must differ to define new code -if [ "$MET_GIT_NAME" != "$SONAR_REFERENCE_BRANCH" ]; then - echo "sonar.newCode.referenceBranch=${SONAR_REFERENCE_BRANCH}" >> $SONAR_PROPERTIES -fi - -# Run the configure script +# Run the MET configure script time_command ./configure \ BUFRLIB_NAME=${BUFRLIB_NAME} \ GRIB2CLIB_NAME=${GRIB2CLIB_NAME} \ - ${MET_CONFIG_OPTS} \ + --enable-all \ CPPFLAGS="-I/usr/local/include -I/usr/local/include/freetype2 -I/usr/local/include/cairo" \ LIBS="-ltirpc" @@ -136,11 +111,18 @@ time_command make clean # Run SonarQube make time_command $SONAR_WRAPPER --out-dir $SONARQUBE_OUT_DIR make -# Run SonarQube scan for C/C++ code +# Run SonarQube scan time_command $SONAR_SCANNER +status=$? + +# Check return status +if [[ $status -ne 0 ]]; then + echo "ERROR: ${0} -> the SonarQube scan returned with non-zero status (${status})!" + exit ${status} +fi -# Copy the C/C++ scan report-task.txt file +# Copy the scan report-task.txt file mkdir -p /met/.scannerwork -cp .scannerwork/report-task.txt /met/.scannerwork/cxx-report-task.txt +cp .scannerwork/report-task.txt /met/.scannerwork/report-task.txt [ -e $SONAR_PROPERTIES ] && rm $SONAR_PROPERTIES diff --git a/internal/scripts/sonarqube/python.sonar-project.properties b/internal/scripts/sonarqube/python.sonar-project.properties deleted file mode 100644 index 71b6b36b71..0000000000 --- a/internal/scripts/sonarqube/python.sonar-project.properties +++ /dev/null @@ -1,17 +0,0 @@ -sonar.projectKey=SONAR_PROJECT_KEY -sonar.projectName=SONAR_PROJECT_NAME -sonar.projectVersion=1.0 - -sonar.sources=scripts/python,data/wrappers -sonar.python.version=3.6.3 - -# The build-wrapper output dir - -# Encoding of the source files -sonar.sourceEncoding=UTF-8 - -#----- Default SonarQube server -sonar.host.url=SONAR_HOST_URL - -sonar.token=SONAR_TOKEN -sonar.branch.name=SONAR_BRANCH_NAME diff --git a/internal/scripts/sonarqube/run_sonarqube.sh b/internal/scripts/sonarqube/run_sonarqube.sh index 917158b461..1a57b0b726 100755 --- a/internal/scripts/sonarqube/run_sonarqube.sh +++ b/internal/scripts/sonarqube/run_sonarqube.sh @@ -24,10 +24,10 @@ GIT_REPO="https://github.com/dtcenter/${GIT_REPO_NAME}" function usage { - echo - echo "USAGE: $(basename $0) name" - echo " where \"name\" specifies a branch, tag, or hash." - echo + echo + echo "USAGE: $(basename $0) name" + echo " where \"name\" specifies a branch, tag, or hash." + echo } # Check for arguments @@ -90,7 +90,6 @@ function run_command() { return ${STATUS} } - # Store the full path to the scripts directory SCRIPT_DIR=`dirname $0` if [[ ${0:0:1} != "/" ]]; then SCRIPT_DIR=$(pwd)/${SCRIPT_DIR}; fi @@ -113,48 +112,35 @@ export MET_DEVELOPMENT=true # Run the configure script run_command "./configure --prefix=`pwd` --enable-all" -# Set the build id -#BUILD_ID="MET-${1}" +# Define the version string +SONAR_PROJECT_VERSION=$(grep "^version" docs/conf.py | cut -d'=' -f2 | tr -d "\'\" ") SONAR_PROPERTIES=sonar-project.properties -# Copy sonar-project.properties for Python code +# Configure sonar-project.properties [ -e $SONAR_PROPERTIES ] && rm $SONAR_PROPERTIES [ -z "$SONAR_HOST_URL" ] && SONAR_HOST_URL="http://localhost:9000" if [ -z "$SONAR_TOKEN" ]; then echo " == ERROR == SONAR_TOKEN is not defined" exit 1 else - sed -e "s|SONAR_TOKEN|$SONAR_TOKEN|" \ - -e "s|SONAR_HOST_URL|$SONAR_HOST_URL|" \ - -e "s|SONAR_PROJECT_KEY|MET_python_NB|" \ - -e "s|SONAR_PROJECT_NAME|MET python Nightly Build|" \ - -e "s|SONAR_BRANCH_NAME|develop|" \ - $SCRIPT_DIR/python.sonar-project.properties > $SONAR_PROPERTIES - - # Run SonarQube scan for Python code - run_command "$SONAR_SCANNER" - - # Copy sonar-project.properties for C/C++ code [ -e $SONAR_PROPERTIES ] && rm $SONAR_PROPERTIES - sed -e "s|SONAR_TOKEN|$SONAR_TOKEN|" \ - -e "s|SONAR_HOST_URL|$SONAR_HOST_URL|" \ - -e "s|SONAR_PROJECT_KEY|MET_develop_NB|" \ + sed -e "s|SONAR_PROJECT_KEY|MET_NB|" \ -e "s|SONAR_PROJECT_NAME|MET Nightly Build|" \ - -e "s|SONAR_BRANCH_NAME|develop|" \ - $SCRIPT_DIR/sonar-project.properties > $SONAR_PROPERTIES + -e "s|SONAR_PROJECT_VERSION|$SONAR_PROJECT_VERSION|" \ + -e "s|SONAR_HOST_URL|$SONAR_HOST_URL|" \ + -e "s|SONAR_TOKEN|$SONAR_TOKEN|" \ + -e "s|SONAR_BRANCH_NAME|${1}|" \ + $SCRIPT_DIR/$SONAR_PROPERTIES > $SONAR_PROPERTIES # Run SonarQube clean run_command "make clean" - # Run SonarQube make + # Run SonarQube build wrapper run_command "$SONAR_WRAPPER --out-dir $SONARQUBE_OUT_DIR make" - # Run SonarQube scan for C/C++ code + # Run SonarQube scan run_command "$SONAR_SCANNER" [ -e $SONAR_PROPERTIES ] && rm $SONAR_PROPERTIES fi - -# Run SonarQube report generator to make a PDF file -#TODAY=`date +%Y%m%d` diff --git a/internal/scripts/sonarqube/sonar-project.properties b/internal/scripts/sonarqube/sonar-project.properties index c09f1d31b1..215749e75b 100644 --- a/internal/scripts/sonarqube/sonar-project.properties +++ b/internal/scripts/sonarqube/sonar-project.properties @@ -1,17 +1,15 @@ +# Project and source code settings sonar.projectKey=SONAR_PROJECT_KEY sonar.projectName=SONAR_PROJECT_NAME -sonar.projectVersion=1.0 - -sonar.sources=src +sonar.projectVersion=SONAR_PROJECT_VERSION +sonar.branch.name=SONAR_BRANCH_NAME +sonar.sources=src,scripts/python,data/wrappers +sonar.python.version=3.6.3 +sonar.sourceEncoding=UTF-8 # The build-wrapper output dir sonar.cfamily.build-wrapper-output=bw-outputs -# Encoding of the source files -sonar.sourceEncoding=UTF-8 - -#----- Default SonarQube server +# SonarQube server sonar.host.url=SONAR_HOST_URL - sonar.token=SONAR_TOKEN -sonar.branch.name=SONAR_BRANCH_NAME diff --git a/data/colortables/NCL_colortables/rgb2ctable.py b/scripts/python/utility/rgb2ctable.py similarity index 100% rename from data/colortables/NCL_colortables/rgb2ctable.py rename to scripts/python/utility/rgb2ctable.py diff --git a/src/libcode/vx_python3_utils/point.py b/src/libcode/vx_python3_utils/point.py deleted file mode 100644 index 699aa46e51..0000000000 --- a/src/libcode/vx_python3_utils/point.py +++ /dev/null @@ -1,39 +0,0 @@ - - -############################################################### - - -import sys - - -############################################################### - -print ('============= start point.py ===========') - -print (sys.argv) - - -############################################################### - - -point_data = [[ 'ADPUPA', '72365', '20070331_120000', 35.03, -106.62, 1618.0, 7, 837.0, 1618, 'NA', 1618 ], - [ 'ADPUPA', '72365', '20070331_120000', 35.03, -106.62, 1618.0, 11, 837.0, 1618, 'NA', 273.05 ], - [ 'ADPUPA', '72365', '20070331_120000', 35.03, -106.62, 1618.0, 17, 837.0, 1618, 'NA', 271.85 ], - [ 'ADPUPA', '72365', '20070331_120000', 35.03, -106.62, 1618.0, 52, 837.0, 1618, 'NA', 92 ], - [ 'ADPUPA', '72365', '20070331_120000', 35.03, -106.62, 1618.0, 53, 837.0, 1618, 'NA', 0.00417 ], - [ 'ADPUPA', '72365', '20070331_120000', 35.03, -106.62, 1618.0, 7, 826.0, 1724, 'NA', 1724 ], - [ 'ADPUPA', '72365', '20070331_120000', 35.03, -106.62, 1618.0, 11, 826.0, 1724, 'NA', 274.55 ]] - - -############################################################### - - -print (point_data) - - -print ('============= end point.py ===========') - - -############################################################### - -