From 4d9048a99a9824ab7cb719771699a92c582b5bf2 Mon Sep 17 00:00:00 2001 From: Gilbert Roulot Date: Wed, 6 Jun 2018 15:21:06 +0000 Subject: First version --- .gitlab-ci.yml | 215 ++++++++++++++++++++++++++++++++++++ Dockerfile | 15 +++ README.md | 48 +++++++- VERSION | 2 +- html2json.js | 80 ++++++++++++++ run.sh | 159 +++++++++++++++++++++++++++ test/results/ruby-bundler.json | 242 +++++++++++++++++++++++++++++++++++++++++ test/test.sh | 25 +++++ 8 files changed, 782 insertions(+), 4 deletions(-) create mode 100644 .gitlab-ci.yml create mode 100644 Dockerfile create mode 100644 html2json.js create mode 100755 run.sh create mode 100644 test/results/ruby-bundler.json create mode 100755 test/test.sh diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml new file mode 100644 index 0000000..f19fc2b --- /dev/null +++ b/.gitlab-ci.yml @@ -0,0 +1,215 @@ +image: alpine:latest + +stages: + - build + - test + - release + +build: + stage: build + image: docker:stable-git + services: + - docker:stable-dind + variables: + DOCKER_DRIVER: overlay2 + script: + - setup_docker + - build + only: + - branches + +test: + stage: test + image: docker:stable + services: + - docker:stable-dind + script: + - docker run "$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG:$CI_COMMIT_SHA" test + only: + - branches + +release-latest: + stage: release + image: docker:stable + services: + - docker:stable-dind + variables: + DOCKER_DRIVER: overlay2 + script: + - setup_docker + - echo "Logging to GitLab Container Registry with CI credentials..." + - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY" + - echo "Pulling Docker image..." + - docker pull "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG" + - echo "Tagging image" + - docker tag "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG" "$CI_REGISTRY_IMAGE:latest" + - echo "Pushing to GitLab Container Registry..." + - docker push "$CI_REGISTRY_IMAGE:latest" + only: + - master + +release-stable: + stage: release + image: docker:stable + services: + - docker:stable-dind + variables: + DOCKER_DRIVER: overlay2 + script: + - setup_docker + - echo "Logging to GitLab Container Registry with CI credentials..." + - docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY" + - echo "Pulling Docker image..." + - docker pull "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG" + - echo "Tagging image" + - docker tag "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG" "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" + - echo "Pushing to GitLab Container Registry..." + - docker push "$CI_REGISTRY_IMAGE:$CI_COMMIT_REF_SLUG" + only: + - /^\d+-\d+-stable$/ + +code_quality: + image: docker:stable + variables: + DOCKER_DRIVER: overlay2 + allow_failure: true + services: + - docker:stable-dind + script: + - setup_docker + - codeclimate + artifacts: + paths: [gl-code-quality-report.json] + +container_scanning: + image: docker:stable + variables: + DOCKER_DRIVER: overlay2 + allow_failure: true + services: + - docker:stable-dind + script: + - setup_docker + - sast_container + artifacts: + paths: [gl-container-scanning-report.json] + +# --------------------------------------------------------------------------- + +.auto_devops: &auto_devops | + # Auto DevOps variables and functions + [[ "$TRACE" ]] && set -x + auto_database_url=postgres://${POSTGRES_USER}:${POSTGRES_PASSWORD}@${CI_ENVIRONMENT_SLUG}-postgres:5432/${POSTGRES_DB} + export DATABASE_URL=${DATABASE_URL-$auto_database_url} + export CI_APPLICATION_REPOSITORY=$CI_REGISTRY_IMAGE/$CI_COMMIT_REF_SLUG + export CI_APPLICATION_TAG=$CI_COMMIT_SHA + export CI_CONTAINER_NAME=ci_job_build_${CI_JOB_ID} + export TILLER_NAMESPACE=$KUBE_NAMESPACE + # Extract "MAJOR.MINOR" from CI_SERVER_VERSION and generate "MAJOR-MINOR-stable" for Security Products + export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/') + + function sast_container() { + if [[ -n "$CI_REGISTRY_USER" ]]; then + echo "Logging to GitLab Container Registry with CI credentials..." + docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY" + echo "" + fi + + docker run -d --name db arminc/clair-db:latest + docker run -p 6060:6060 --link db:postgres -d --name clair --restart on-failure arminc/clair-local-scan:v2.0.1 + apk add -U wget ca-certificates + docker pull ${CI_APPLICATION_REPOSITORY}:${CI_APPLICATION_TAG} + wget https://github.com/arminc/clair-scanner/releases/download/v8/clair-scanner_linux_amd64 + mv clair-scanner_linux_amd64 clair-scanner + chmod +x clair-scanner + touch clair-whitelist.yml + retries=0 + echo "Waiting for clair daemon to start" + while( ! wget -T 10 -q -O /dev/null http://docker:6060/v1/namespaces ) ; do sleep 1 ; echo -n "." ; if [ $retries -eq 10 ] ; then echo " Timeout, aborting." ; exit 1 ; fi ; retries=$(($retries+1)) ; done + ./clair-scanner -c http://docker:6060 --ip $(hostname -i) -r gl-sast-container-report.json -l clair.log -w clair-whitelist.yml ${CI_APPLICATION_REPOSITORY}:${CI_APPLICATION_TAG} || true + } + + function codeclimate() { + docker run --env SOURCE_CODE="$PWD" \ + --volume "$PWD":/code \ + --volume /var/run/docker.sock:/var/run/docker.sock \ + "registry.gitlab.com/gitlab-org/security-products/codequality:$SP_VERSION" /code + } + + function sast() { + case "$CI_SERVER_VERSION" in + *-ee) + + # Deprecation notice for CONFIDENCE_LEVEL variable + if [ -z "$SAST_CONFIDENCE_LEVEL" -a "$CONFIDENCE_LEVEL" ]; then + SAST_CONFIDENCE_LEVEL="$CONFIDENCE_LEVEL" + echo "WARNING: CONFIDENCE_LEVEL is deprecated and MUST be replaced with SAST_CONFIDENCE_LEVEL" + fi + + docker run --env SAST_CONFIDENCE_LEVEL="${SAST_CONFIDENCE_LEVEL:-3}" \ + --volume "$PWD:/code" \ + --volume /var/run/docker.sock:/var/run/docker.sock \ + "registry.gitlab.com/gitlab-org/security-products/sast:$SP_VERSION" /app/bin/run /code + ;; + *) + echo "GitLab EE is required" + ;; + esac + } + + function dependency_scanning() { + case "$CI_SERVER_VERSION" in + *-ee) + docker run --env DEP_SCAN_DISABLE_REMOTE_CHECKS="${DEP_SCAN_DISABLE_REMOTE_CHECKS:-false}" \ + --volume "$PWD:/code" \ + --volume /var/run/docker.sock:/var/run/docker.sock \ + "registry.gitlab.com/gitlab-org/security-products/dependency-scanning:$SP_VERSION" /code + ;; + *) + echo "GitLab EE is required" + ;; + esac + } + + function setup_docker() { + if ! docker info &>/dev/null; then + if [ -z "$DOCKER_HOST" -a "$KUBERNETES_PORT" ]; then + export DOCKER_HOST='tcp://localhost:2375' + fi + fi + } + + function build() { + + if [[ -n "$CI_REGISTRY_USER" ]]; then + echo "Logging to GitLab Container Registry with CI credentials..." + docker login -u "$CI_REGISTRY_USER" -p "$CI_REGISTRY_PASSWORD" "$CI_REGISTRY" + echo "" + fi + + if [[ -f Dockerfile ]]; then + echo "Building Dockerfile-based application..." + docker build -t "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG" . + else + echo "Building Heroku-based application using gliderlabs/herokuish docker image..." + docker run -i --name="$CI_CONTAINER_NAME" -v "$(pwd):/tmp/app:ro" gliderlabs/herokuish /bin/herokuish buildpack build + docker commit "$CI_CONTAINER_NAME" "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG" + docker rm "$CI_CONTAINER_NAME" >/dev/null + echo "" + + echo "Configuring $CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG docker image..." + docker create --expose 5000 --env PORT=5000 --name="$CI_CONTAINER_NAME" "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG" /bin/herokuish procfile start web + docker commit "$CI_CONTAINER_NAME" "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG" + docker rm "$CI_CONTAINER_NAME" >/dev/null + echo "" + fi + + echo "Pushing to GitLab Container Registry..." + docker push "$CI_APPLICATION_REPOSITORY:$CI_APPLICATION_TAG" + echo "" + } + +before_script: + - *auto_devops + + diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..9ff5519 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,15 @@ +FROM licensefinder/license_finder:5.1.0 +MAINTAINER GitLab + +RUN npm install npm-install-peers cheerio + +# Don't let Rubygem fail with the numerous projects using PG or MySQL +RUN apt-get update && apt-get install -y libpq-dev libmysqlclient-dev && rm -rf /var/lib/apt/lists/* + +COPY run.sh html2json.js / +COPY test /test + +# Don't load RVM automatically, it doesn't work with GitLab-CI +RUN mv /etc/profile.d/rvm.sh /rvm.sh + +ENTRYPOINT ["/run.sh"] diff --git a/README.md b/README.md index 5930586..d58ebf8 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # GitLab License Management -[![pipeline status](https://gitlab.com/gitlab-org/security-products/license_management/badges/master/pipeline.svg)](https://gitlab.com/gitlab-org/security-products/license_management/commits/master) -[![coverage report](https://gitlab.com/gitlab-org/security-products/license_management/badges/master/coverage.svg)](https://gitlab.com/gitlab-org/security-products/license_management/commits/master) +[![pipeline status](https://gitlab.com/gitlab-org/security-products/license-management/badges/master/pipeline.svg)](https://gitlab.com/gitlab-org/security-products/license-management/commits/master) +[![coverage report](https://gitlab.com/gitlab-org/security-products/license-management/badges/master/coverage.svg)](https://gitlab.com/gitlab-org/security-products/license-management/commits/master) GitLab tool for detecting licenses of the dependencies used by the provided source. It is currently based on License Finder only, but this may change in the future. @@ -14,11 +14,53 @@ It is currently based on License Finder only, but this may change in the future. ```sh docker run \ --volume "$PWD":/code \ - registry.gitlab.com/gitlab-org/security-products/license_management:latest /code + --rm \ + registry.gitlab.com/gitlab-org/security-products/license-management:latest analyze /code ``` 1. The results will be stored in the `gl-license-management-report.json` file in the application directory. `gl-license-management-report.html` is also available with a human readable report. +## Development + +### Running the application + +License Management is a Docker image, you can build it like any Docker image like so in the +project root: + +```sh +docker build -t license-management . +``` + +You can then run License Management on some target directory: + +```sh +docker run --rm --volume "/path/to/my/project":/code license-management analyze /code +``` + +You can run integration tests on the image like this: + +```sh +docker run --rm license-management /test/test.sh +``` + +## Supported languages and package managers + +The following table shows which languages and package managers are supported. + +| Language | Package managers | +|------------|-------------------------------------------------------------------| +| JavaScript | [Bower](https://bower.io/), [npm](https://www.npmjs.com/) | +| Go | [Godep](https://github.com/tools/godep), go get | +| Java | [Gradle](https://gradle.org/), [Maven](https://maven.apache.org/) | +| .NET | [Nuget](https://www.nuget.org/) | +| Python | [pip](https://pip.pypa.io/en/stable/) | +| Ruby | [gem](https://rubygems.org/) | + + +## Versioning and release process + +Please check the [Release Process documentation](https://gitlab.com/gitlab-org/security-products/release/blob/master/docs/release_process.md). + # Contributing If you want to help, read the [contribution guidelines](CONTRIBUTING.md). diff --git a/VERSION b/VERSION index 2dbc24b..b743821 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -11.0 +11-0-stable diff --git a/html2json.js b/html2json.js new file mode 100644 index 0000000..841149a --- /dev/null +++ b/html2json.js @@ -0,0 +1,80 @@ +var cheerio = require('cheerio') +var path = require('path') + +// Read the HTML report +fs = require('fs') +var htmlContent; +try { + htmlContent = fs.readFileSync(process.argv[2], 'utf8'); +} catch(e) { + console.log('Error:', e.stack); +} + +// Get the directory containing the results to make pathes relative to it later. +report_directory = path.dirname(process.argv[2]) + +const $ = cheerio.load(htmlContent) + +// Extract licenses and the number of occurences. +var licenses = []; +$('div.summary div.row').children().first().find('ul li').each(function(i, doc) { + tmp = $(this).text(); + matches = tmp.match(/^([0-9]+) ((\s|\S)*)/m) + licenses.push({ + count: parseInt(matches[1], 10), + name: matches[2] + }) +}) + +// Extract dependencies info. +var dependencies = [] +$('div.dependencies div').each(function(i, doc) { + // Get license name. + license = $(this).find('blockquote p').text().trim(); + license = license.split("\n")[0]; + + // Get URL. + license_url = $(this).find('blockquote p a[href]').attr('href'); + + // Get dependency name. + dependency_name = $(this).find('h2').text().trim(); + dependency_name = dependency_name.split("\n")[0]; + + // Get dependency URL. + dependency_url = $(this).find('h2 a[href]').attr('href'); + + // Get dependency description. + dependency_description = $(this).find('dl').first().next().text().trim(); + + // Get dependency location relative to the project root path + dependency_pathes = [] + $(this).find('dl').first().find('dd').each(function(i, doc) { + dependency_path = path.relative(report_directory, $(this).text().trim()); + + // Whitespace path means current directory + if (!dependency_path) { + dependency_path = "."; + } + + dependency_pathes.push(dependency_path); + }) + dependencies.push({ + license: { + name: license, + url: license_url + }, + dependency: { + name: dependency_name, + url: dependency_url, + description: dependency_description, + pathes: dependency_pathes + } + }) +}) + +console.log(JSON.stringify({ + licenses: licenses, + dependencies: dependencies}, null, 4)) + + + diff --git a/run.sh b/run.sh new file mode 100755 index 0000000..e5433e2 --- /dev/null +++ b/run.sh @@ -0,0 +1,159 @@ +#!/bin/bash -l + +set -e + +usage=" +$(basename "$0") [-h] + +$(basename "$0") analyze PROJECT_PATH + +$(basename "$0") test + +where: + -h show this help text + PROJECT_PATH = the path of the project to be analyzed for licenses usage." + +if [ $# -eq 0 ] ; then + echo "$usage" + exit 1 +fi + +while getopts 'h' option; do + case "$option" in + h) echo "$usage" + exit + ;; + :) printf "missing argument for -%s\n" "$OPTARG" >&2 + echo "$usage" >&2 + exit 1 + ;; + \?) printf "illegal option: -%s\n" "$OPTARG" >&2 + echo "$usage" >&2 + exit 1 + ;; + esac +done +shift $((OPTIND - 1)) + +COMMAND=$1 +shift + +# "/run.sh" as a command means the user want the "analyze" command. +if [ "$COMMAND" = "/run.sh" ] ; then + COMMAND="analyze" +fi +if [ "$COMMAND" = "analyse" ] ; then + COMMAND="analyze" +fi + +# "/test/test.sh" as a command means the user want the "test" command. +if [ "$COMMAND" = "/test/test.sh" ] ; then + COMMAND="test" +fi + +# Check number of arguments + +if [ "$COMMAND" = "analyze" -a $# -ne 1 ] ; then + echo "$usage" + exit 1 +fi + +if [ "$COMMAND" = "test" -a $# -ne 0 ] ; then + echo "$usage" + exit 1 +fi + +# Run command +case "$COMMAND" in + test) + # Run integration tests. + exec /test/test.sh + ;; + + analyze) + # Analyze project + + # Load RVM + source /rvm.sh + + # Change current directory to the project path. + APP_PATH=$1 + shift + pushd $APP_PATH + + # Before running license_finder, we need to install dependencies for the project. + if test -f Gemfile ; then + if test -n "$rvm_recommended_ruby" ; then + # Install the Ruby version RVM found in the project files + # This always end in the cryptic "bash: Searching: command not found" error but Ruby is installed + # So we ignore the error. + $($rvm_recommended_ruby) 2>/dev/null || true + rvm use . + gem install bundler + # We need to install the license_finder gem into this Ruby version too. + gem install license_finder + fi + + # Ignore test and development dependencies. + license_finder ignored_groups add development + license_finder ignored_groups add test + bundle install --without "development test" + fi + + if test -f requirements.txt ; then + # Install Python Pip packages. + pip install -r requirements.txt + fi + + if test -f package.json ; then + # Install NPM packages. + npm install --production + # Try to install Peer packages too, npm install doesn't do it anymore. + /node_modules/.bin/npm-install-peers + fi + + if test -f bower.json ; then + # Install Bower packages. + bower install + fi + + # Symlink the project into GOPATH to allow fetching dependencies. + ln -s $APP_PATH /gopath/src/app + + if test -f Godeps/Godeps.json ; then + # Install Go dependencies with Godeps. + pushd /gopath/src/app + godep restore + popd + elif find . -name "*.go" -printf "found" -quit |grep found >/dev/null ; then + # Install Go dependencies with go get. + pushd /gopath/src/app + go get + popd + fi + + if test -f pom.xml ; then + # Install Java Maven dependencies. + mvn install + fi + + if test -f build.gradle ; then + # Install Java Gradle dependencies. + gradle build + fi + + # Run License Finder. + echo "Running license_finder $@ in $PWD" + license_finder report --format=html --save=gl-license-management-report.html + popd + + # Extract data from the HTML report and put it into a JSON file + node /html2json.js $APP_PATH/gl-license-management-report.html > $APP_PATH/gl-license-management-report.json + ;; + + *) + # Unknown command + echo "Unknown command: $COMMAND" + echo "$usage" + exit 1 +esac diff --git a/test/results/ruby-bundler.json b/test/results/ruby-bundler.json new file mode 100644 index 0000000..c1d20fa --- /dev/null +++ b/test/results/ruby-bundler.json @@ -0,0 +1,242 @@ +{ + "licenses": [ + { + "count": 13, + "name": "MIT" + }, + { + "count": 2, + "name": "New BSD" + }, + { + "count": 1, + "name": "LGPL" + } + ], + "dependencies": [ + { + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { + "name": "bundler", + "url": "http://bundler.io", + "description": "The best way to manage your application's dependencies", + "pathes": [ + "." + ] + } + }, + { + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { + "name": "concurrent-ruby", + "url": "http://www.concurrent-ruby.com", + "description": "Modern concurrency tools for Ruby. Inspired by Erlang, Clojure, Scala, Haskell, F#, C#, Java, and classic concurrency patterns.", + "pathes": [ + "." + ] + } + }, + { + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { + "name": "connection_pool", + "url": "https://github.com/mperham/connection_pool", + "description": "Generic connection pool for Ruby", + "pathes": [ + "." + ] + } + }, + { + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { + "name": "mini_portile2", + "url": "http://github.com/flavorjones/mini_portile", + "description": "Simplistic port-like solution for developers", + "pathes": [ + "." + ] + } + }, + { + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { + "name": "mustermann", + "url": "https://github.com/sinatra/mustermann", + "description": "Your personal string matching expert.", + "pathes": [ + "." + ] + } + }, + { + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { + "name": "nokogiri", + "url": "http://nokogiri.org", + "description": "Nokogiri (鋸) is an HTML, XML, SAX, and Reader parser", + "pathes": [ + "." + ] + } + }, + { + "license": { + "name": "New BSD", + "url": "http://opensource.org/licenses/BSD-3-Clause" + }, + "dependency": { + "name": "pg", + "url": "https://bitbucket.org/ged/ruby-pg", + "description": "Pg is the Ruby interface to the {PostgreSQL RDBMS}[http://www.postgresql.org/]", + "pathes": [ + "." + ] + } + }, + { + "license": { + "name": "New BSD", + "url": "http://opensource.org/licenses/BSD-3-Clause" + }, + "dependency": { + "name": "puma", + "url": "http://puma.io", + "description": "Puma is a simple, fast, threaded, and highly concurrent HTTP 1.1 server for Ruby/Rack applications", + "pathes": [ + "." + ] + } + }, + { + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { + "name": "rack", + "url": "https://rack.github.io/", + "description": "a modular Ruby webserver interface", + "pathes": [ + "." + ] + } + }, + { + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { + "name": "rack-protection", + "url": "http://github.com/sinatra/sinatra/tree/master/rack-protection", + "description": "Protect against typical web attacks, works with all Rack apps, including Rails.", + "pathes": [ + "." + ] + } + }, + { + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { + "name": "redis", + "url": "https://github.com/redis/redis-rb", + "description": "A Ruby client library for Redis", + "pathes": [ + "." + ] + } + }, + { + "license": { + "name": "LGPL", + "url": "http://www.gnu.org/licenses/lgpl.txt" + }, + "dependency": { + "name": "sidekiq", + "url": "http://sidekiq.org", + "description": "Simple, efficient background processing for Ruby", + "pathes": [ + "." + ] + } + }, + { + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { + "name": "sinatra", + "url": "http://www.sinatrarb.com/", + "description": "Classy web-development dressed in a DSL", + "pathes": [ + "." + ] + } + }, + { + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { + "name": "slim", + "url": "http://slim-lang.com/", + "description": "Slim is a template language.", + "pathes": [ + "." + ] + } + }, + { + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { + "name": "temple", + "url": "https://github.com/judofyr/temple", + "description": "Template compilation framework in Ruby", + "pathes": [ + "." + ] + } + }, + { + "license": { + "name": "MIT", + "url": "http://opensource.org/licenses/mit-license" + }, + "dependency": { + "name": "tilt", + "url": "http://github.com/rtomayko/tilt/", + "description": "Generic interface to multiple Ruby template engines", + "pathes": [ + "." + ] + } + } + ] +} diff --git a/test/test.sh b/test/test.sh new file mode 100755 index 0000000..c77ec1d --- /dev/null +++ b/test/test.sh @@ -0,0 +1,25 @@ +#!/bin/bash + +set -e + +# Clone the Ruby Bundler test repository. +echo "Cloning the test repository https://gitlab.com/gitlab-org/security-products/tests/ruby-bundler.git" +git clone https://gitlab.com/gitlab-org/security-products/tests/ruby-bundler.git /code + +# Run license management on it. +echo "Running license management on the cloned repository" +cd /code +/run.sh analyze . + +# Compare results with expected results. +set +e +diff /code/gl-license-management-report.json /test/results/ruby-bundler.json > /diff.txt + +if [ -s /diff.txt ] ; then + echo "Unexpected result. Here is the diff between actual results and those expected :" + cat /diff.txt + exit 1 +else + echo "All tests are OK." +fi + -- cgit v1.2.3