You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openwhisk.apache.org by cs...@apache.org on 2018/04/27 16:01:13 UTC

[incubator-openwhisk] branch master updated: Use scanCode from utilities repo. using ASF Release configuration. (#3569)

This is an automated email from the ASF dual-hosted git repository.

csantanapr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/incubator-openwhisk.git


The following commit(s) were added to refs/heads/master by this push:
     new 166b421  Use scanCode from utilities repo. using ASF Release configuration. (#3569)
166b421 is described below

commit 166b421c3bd6fc9625f2be5d5c40990782481e09
Author: Matt Rutkowski <mr...@us.ibm.com>
AuthorDate: Fri Apr 27 11:01:09 2018 -0500

    Use scanCode from utilities repo. using ASF Release configuration. (#3569)
---
 tools/build/ASFLicenseHeader.txt       |  16 -
 tools/build/ApacheIBMLicenseHeader.txt |  15 -
 tools/build/README.md                  |  16 +-
 tools/build/scanCode.cfg               |  57 ----
 tools/build/scanCode.py                | 541 ---------------------------------
 tools/travis/build.sh                  |   4 +-
 6 files changed, 10 insertions(+), 639 deletions(-)

diff --git a/tools/build/ASFLicenseHeader.txt b/tools/build/ASFLicenseHeader.txt
deleted file mode 100644
index d973dce..0000000
--- a/tools/build/ASFLicenseHeader.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
\ No newline at end of file
diff --git a/tools/build/ApacheIBMLicenseHeader.txt b/tools/build/ApacheIBMLicenseHeader.txt
deleted file mode 100644
index 565488e..0000000
--- a/tools/build/ApacheIBMLicenseHeader.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Copyright 2015-2016 IBM Corporation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
\ No newline at end of file
diff --git a/tools/build/README.md b/tools/build/README.md
index 7e5e83d..6313034 100644
--- a/tools/build/README.md
+++ b/tools/build/README.md
@@ -1,16 +1,16 @@
 <!--
 #
-# Licensed to the Apache Software Foundation (ASF) under one or more contributor 
-# license agreements.  See the NOTICE file distributed with this work for additional 
+# Licensed to the Apache Software Foundation (ASF) under one or more contributor
+# license agreements.  See the NOTICE file distributed with this work for additional
 # information regarding copyright ownership.  The ASF licenses this file to you
-# under the Apache License, Version 2.0 (the # "License"); you may not use this 
-# file except in compliance with the License.  You may obtain a copy of the License 
+# under the Apache License, Version 2.0 (the # "License"); you may not use this
+# file except in compliance with the License.  You may obtain a copy of the License
 # at:
 #
 # http://www.apache.org/licenses/LICENSE-2.0
 #
-# Unless required by applicable law or agreed to in writing, software distributed 
-# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR 
+# Unless required by applicable law or agreed to in writing, software distributed
+# under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 # CONDITIONS OF ANY KIND, either express or implied.  See the License for the
 # specific language governing permissions and limitations under the License.
 #
@@ -19,8 +19,6 @@
 # Build helper scripts
 
 This directory contains the following utilities.
-- `scanCode.py`: checks all code for conformance with respect to certain conventions.
-   - Please note that this utility has been moved to the incubator-openwhisk-utilities repository so that all Apache OpenWhisk repositories may more easily reference it. This version will be removed once all other repositories in the project correctly reference it in its new location.
 - `redo`: a wrapper around Ansible and Gradle commands, for which examples are given below,
 - `citool`: allows for command line monitoring of Jenkins and Travis CI builds.
 
@@ -90,7 +88,7 @@ citool -i -b B cat -s -g "tid_124" whisk/logs N
 
 OpenWhisk builds on CI setups have [Gradle Build Scan](https://gradle.com/build-scans) integrated. Each build on travis pushes scan reports to
 [Gradle Scan Community Hosted Server](https://scans.gradle.com). To see the scan report you need to check the travis build logs for lines like
-below 
+below
 
 ```
 Publishing build scan...
diff --git a/tools/build/scanCode.cfg b/tools/build/scanCode.cfg
deleted file mode 100644
index b71c217..0000000
--- a/tools/build/scanCode.cfg
+++ /dev/null
@@ -1,57 +0,0 @@
-# scanCode.py configuration file
-
-# List of filenames containing the text of valid license (headers)
-# These files SHOULD be in the same directory path where scanCode.py
-# resides.
-[Licenses]
-ASFLicenseHeader.txt
-ApacheIBMLicenseHeader.txt
-
-# Filters (path/filename) with wildcards and associated scan checks
-# that are to be run against them.  The checks are actual valid
-# function names found in scanCode.py.
-[Includes]
-*=is_not_symlink
-*.scala=has_block_license, no_tabs, no_trailing_spaces, eol_at_eof
-*.py=no_tabs, no_trailing_spaces, eol_at_eof
-*.java=has_block_license, no_tabs, no_trailing_spaces, eol_at_eof
-*.js=no_tabs, no_trailing_spaces, eol_at_eof
-*.gradle=no_tabs, no_trailing_spaces, eol_at_eof
-*.md=no_tabs, eol_at_eof
-*.go=has_block_license, no_trailing_spaces, eol_at_eof
-build.xml=no_tabs, no_trailing_spaces, eol_at_eof
-deploy.xml=no_tabs, no_trailing_spaces, eol_at_eof
-
-# List of paths (inclusive of subdirectories) to exlude from code scanning
-[Excludes]
-# General exclusions
-.tox
-.git
-# OpenWhisk exclusions
-bin
-tests/build/reports
-tests/dat
-tools/dev/build
-# openwhisk-catalog exclusions (Python samples)
-packages/samples/hello
-# The following repos. have so far been identified as having scanning errors
-# and will be excluded until their owners have completed updates to add Travis
-# support, run scancode and become compliant.
-openwhisk-debugger
-openwhisk-client-python
-openwhisk-client-go
-openwhisk-client-js
-openwhisk-vscode
-openwhisk-devtools
-openwhisk-package-jira
-openwhisk-sample-matos
-openwhisk-GitHubSlackBot
-
-[Options]
-# Not all code files allow licenses to appear starting at the first character
-# of the file. This option tells the scan to allow licenses to appear starting
-# within first 'x' characters of each code file (as provided by this option's
-# value).
-LICENSE_SLACK_LENGTH=500
-
-[Regex]
\ No newline at end of file
diff --git a/tools/build/scanCode.py b/tools/build/scanCode.py
deleted file mode 100755
index 4eadf4d..0000000
--- a/tools/build/scanCode.py
+++ /dev/null
@@ -1,541 +0,0 @@
-#!/usr/bin/env python
-"""Executable Python script for scanning source code for compliance.
-
-   This script checks some (simple) conventions:
-   - no symlinks
-   - no tabs
-   - no trailing whitespace
-   - files end with EOL
-   - valid license headers in source files (where applicable)
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-"""
-import argparse
-import collections
-try:
-    import configparser
-except ImportError:
-    import ConfigParser as configparser
-import fnmatch
-import itertools
-import os
-import platform
-import re
-import sys
-import textwrap
-
-VERBOSE = False
-
-# Terminal colors
-BLUE = '\033[94m'
-CYAN = '\033[36m'
-GREEN = '\033[92m'
-RED = '\033[91m'
-YELLOW = '\033[33m'
-
-# Translatable messages (error and general)
-ERR_GENERAL = "an unspecified error was detected."
-ERR_INVALID_CONFIG_FILE = "Invalid configuration file [%s]: %s.\n"
-ERR_LICENSE = "file does not include required license header."
-ERR_NO_EOL_AT_EOF = "file does not end with EOL."
-ERR_PATH_IS_NOT_DIRECTORY = "%s: [%s] is not a valid directory.\n"
-ERR_REQUIRED_SECTION = "Configuration file missing required section: [%s]"
-ERR_SYMBOLIC_LINK = "file is a symbolic link."
-ERR_TABS = "line contains tabs."
-ERR_TRAILING_WHITESPACE = "line has trailing whitespaces."
-ERR_LICENSE_FILE_NOT_FOUND = "License file [%s] could not be found."
-ERR_INVALID_SCAN_FUNCTION = "Config. file filter [%s] lists invalid " \
-                            "function [%s]."
-HELP_CONFIG_FILE = "provide custom configuration file"
-HELP_DISPLAY_EXCLUSIONS = "display path exclusion information"
-HELP_ROOT_DIR = "starting directory for the scan"
-HELP_VERBOSE = "enable verbose output"
-MSG_CHECKING_FILE = "  [%s]..."
-MSG_CHECKS_PASSED = "All checks passed."
-MSG_CONFIG_ADDING_LICENSE_FILE = "Adding valid license from: [%s], value:\n%s"
-MSG_ERROR_SUMMARY = "Scan detected %d error(s) in %d file(s):"
-MSG_READING_CONFIGURATION = "Reading configuration file [%s]..."
-MSG_READING_LICENSE_FILE = "Reading license file [%s]..."
-MSG_RUNNING_FILE_CHECKS = "    Running File Check [%s]"
-MSG_RUNNING_LINE_CHECKS = "    Running Line Check [%s]"
-MSG_SCANNING_FILTER = "Scanning files with filter: [%s]:"
-MSG_SCANNING_STARTED = "Scanning files starting at [%s]..."
-WARN_CONFIG_SECTION_NOT_FOUND = "Configuration file section [%s] not found."
-WARN_SCAN_EXCLUDED_PATH_SUMMARY = "Scan excluded (%s) directories:"
-WARN_SCAN_EXCLUDED_FILE_SUMMARY = "Scan excluded (%s) files:"
-WARN_SCAN_EXCLUDED_FILE = "  Excluded file: %s"
-WARN_SCAN_EXCLUDED_PATH = "  Excluded path: %s"
-MSG_DESCRIPTION = "Scans all source code under specified directory for " \
-                  "project compliance using provided configuration."
-
-# Default values for command line arguments
-DEFAULT_ROOT_DIR = "."
-DEFAULT_PROGRAM_PATH = "./"
-DEFAULT_CONFIG_FILE = "scanCode.cfg"
-DEFAULT_LICENSE_SEARCH_SLACK = 500
-
-# Configuration file sections
-SECTION_LICENSE = "Licenses"
-SECTION_EXCLUDE = "Excludes"
-SECTION_INCLUDE = "Includes"
-SECTION_OPTIONS = "Options"
-
-# Configuration Options known keys
-OPT_LICENSE_SLACK_LEN = "license_slack_length"
-
-# Globals
-"""Hold valid license headers within an array strings."""
-valid_licenses = []
-exclusion_paths = []
-exclusion_files_set = set()
-license_search_slack_len = DEFAULT_LICENSE_SEARCH_SLACK
-FILE_CHECK_FUNCTIONS = dict()
-LINE_CHECK_FUNCTIONS = dict()
-FILTERS_WITH_CHECK_FUNCTIONS = []
-
-
-def print_error(msg):
-    """Print error message to stderr."""
-    sys.stderr.write(col.red(msg) + "\n")
-
-
-def print_warning(msg):
-    """Print warning message to stdout."""
-    print(col.yellow(msg))
-
-
-def print_status(msg):
-    """Print status message to stdout."""
-    print(msg)
-
-
-def print_success(msg):
-    """Print success message to stdout."""
-    print(col.green(msg))
-
-
-def print_highlight(msg):
-    """Print highlighted message to stdout."""
-    print(col.cyan(msg))
-
-
-def vprint(s):
-    """Conditional print (stdout)."""
-    if VERBOSE:
-        print_status(s)
-
-
-def get_config_section_dict(config, section):
-    """Retrieve key-value(s) for requested section of a config. file."""
-    dict1 = {}
-    try:
-        options = config.options(section)
-        # print_warning("options for section: %s\n%s" % (section, options))
-        for option in options:
-            try:
-                dict1[option] = config.get(section, option)
-            except:
-                dict1[option] = None
-    except:
-        print_warning(WARN_CONFIG_SECTION_NOT_FOUND % section)
-        return None
-    return dict1
-
-
-def find_license_on_path(filename, path):
-    """Find the specified filename in path; return it or raise error."""
-    filename = os.path.join(path, filename)
-
-    if not os.path.exists(filename):
-        raise Exception(ERR_LICENSE_FILE_NOT_FOUND %
-                        filename)
-    return filename
-
-
-def read_license_files(config):
-    """Read the license files to use when scanning source files."""
-    file_dict = get_config_section_dict(config, SECTION_LICENSE)
-    # vprint("file_dict: " + str(file_dict))
-    if file_dict is not None:
-        # for each key (license filename) in license section
-        for license_filename in file_dict:
-            # Read and append text of each license (header) to a global array.
-            # Each 'key' should be a filename containing license text.
-            try:
-
-                # if the file is not in current directory, try to find
-                # it in the path this script is being executed from.
-                if not os.path.exists(license_filename):
-                    license_filename = find_license_on_path(
-                        license_filename,
-                        DEFAULT_PROGRAM_PATH)
-
-                with open(license_filename, 'r') as temp_file:
-                    vprint(MSG_READING_LICENSE_FILE % license_filename)
-                    str1 = str(temp_file.read())
-                    valid_licenses.append(str(str1))
-                    vprint(MSG_CONFIG_ADDING_LICENSE_FILE % (license_filename,
-                                                             str1))
-            except Exception as e:
-                raise e
-    else:
-        raise Exception(ERR_REQUIRED_SECTION % SECTION_LICENSE)
-
-
-def read_path_exclusions(config):
-    """Read the list of paths to exclude from the scan."""
-    path_dict = get_config_section_dict(config, SECTION_EXCLUDE)
-    # vprint("path_dict: " + str(path_dict))
-    if path_dict is not None:
-        # each 'key' is an exclusion path
-        for key in path_dict:
-            if key is not None:
-                exclusion_paths.append(key)
-    else:
-        raise Exception(ERR_REQUIRED_SECTION % SECTION_LICENSE)
-
-
-def read_scan_options(config):
-    """Read the Options from the configuration file."""
-    options_dict = get_config_section_dict(config, SECTION_OPTIONS)
-    # vprint("options_dict: " + str(options_dict))
-    if options_dict is not None:
-        # Check for license scan slack length option
-        # Set global variable to value found in config.
-        if OPT_LICENSE_SLACK_LEN in options_dict:
-            global license_search_slack_len
-            license_search_slack_len = int(options_dict[OPT_LICENSE_SLACK_LEN])
-    else:
-        raise Exception(ERR_REQUIRED_SECTION % SECTION_OPTIONS)
-
-
-def read_config_file(file):
-    """Read in and validate configuration file."""
-    try:
-        print_highlight(MSG_READING_CONFIGURATION % file.name)
-        # Provide for sections that have simply values (not key=value)
-        config = configparser.ConfigParser(allow_no_value=True)
-        # This option prevents options from being normalized to lowercase
-        # by allowing the raw string in the config. to be passed through
-        config.optionxform = str
-        config.readfp(file)
-        read_license_files(config)
-        read_path_inclusions(config)
-        read_path_exclusions(config)
-        read_scan_options(config)
-    except Exception as e:
-        print_error(e)
-        return -1
-    return 0
-
-
-def no_tabs(line):
-    """Assert line does not contains a TAB character."""
-    if re.match("\t", line):
-        return ERR_TABS
-    else:
-        return None
-
-
-def no_trailing_spaces(line):
-    """Assert line does not have trailing whitespace."""
-    if len(line) > 0 and line[-1] == '\n':
-        line = line[:-1]
-
-    if re.match("""^.*\s$""", line):
-        return ERR_TRAILING_WHITESPACE
-    else:
-        return None
-
-
-def eol_at_eof(line):
-    """Assert line at End of File is an End of Line character."""
-    if len(line) == 0 or line[-1] != '\n':
-        return ERR_NO_EOL_AT_EOF
-    else:
-        return None
-
-
-def has_block_license(path):
-    """Open file and verify it contains a valid license header."""
-    with open(path) as fp:
-        for license in valid_licenses:
-            # Assure license string is normalized to remove indentations
-            # caused by declaration (above) as a string literal.
-            normalized_license = textwrap.dedent(license)
-            # Search for license at start of file,
-            # allowing for some "slack" length
-            file_head = fp.read(len(normalized_license) +
-                                license_search_slack_len)
-
-            if file_head is None:
-                return [(1, ERR_LICENSE)]
-            elif normalized_license in file_head:
-                return []
-            # reset and try finding the next license
-            fp.seek(0)
-    return [(1, ERR_LICENSE)]
-
-
-def is_not_symlink(path):
-    """Assert a file is not a symbolic link."""
-    if os.path.islink(path):
-        return [(0, ERR_SYMBOLIC_LINK)]
-    else:
-        return None
-
-
-# Note: this function must appear after all "check" functions are defined
-def read_path_inclusions(config):
-    """Read the list of paths to include in scan tests."""
-    inclusion_dict = get_config_section_dict(config, SECTION_INCLUDE)
-    # vprint("inclusion_dict: " + str(inclusion_dict))
-
-    for key in inclusion_dict:
-        all_checks = inclusion_dict[key]
-        # strip off all whitespace, regardless of index
-        all_checks = all_checks.replace(' ', '')
-        # retrieve the names of all functions to scan for
-        # the respective filename (wildcards allowed)
-        function_names = all_checks.split(',')
-        file_check_fxs = []
-        line_check_fxs = []
-        for fname in function_names:
-            try:
-                fx = globals()[fname]
-                if fname in FILE_CHECK_FUNCTIONS:
-                    file_check_fxs.append(fx)
-                elif fname in LINE_CHECK_FUNCTIONS:
-                    line_check_fxs.append(fx)
-            except Exception:
-                print_error(ERR_INVALID_SCAN_FUNCTION % (key, fname))
-                sys.exit(1)
-
-        a_tuple = (key, file_check_fxs, line_check_fxs)
-        FILTERS_WITH_CHECK_FUNCTIONS.append(a_tuple)
-    # vprint("filters(checks):" + str(FILTERS_WITH_CHECK_FUNCTIONS))
-
-
-def run_file_checks(file_path, checks):
-    """Run a series of file-by-file checks."""
-    errors = []
-    # if VERBOSE (True) then print filename being checked
-    vprint(MSG_CHECKING_FILE % file_path)
-    for check in checks:
-        vprint(col.cyan(MSG_RUNNING_FILE_CHECKS % check.__name__))
-        errs = check(file_path)
-        if errs:
-            errors += errs
-    return errors
-
-
-def run_line_checks(file_path, checks):
-    """."""
-    errors = []
-    line_number = 0
-    # For each line in the file, run all "line checks"
-    with open(file_path) as fp:
-        for line in fp:
-            line_number += 1
-            for check in checks:
-                if line_number == 1:
-                    vprint(col.cyan(MSG_RUNNING_LINE_CHECKS %
-                                    check.__name__))
-                err = check(line)
-                if err is not None:
-                    errors.append((line_number, err))
-    return errors
-
-
-def all_paths(root_dir):
-    """Generator that returns files with known extensions that can be scanned.
-
-    Iteration is recursive beginning at the passed root directory and
-    skipping directories that are listed as exception paths.
-    """
-    # For every file in every directory (path) starting at "root_dir"
-    for dir_path, dir_names, files in os.walk(root_dir):
-        for f in files:
-            # Map will contain a boolean for each exclusion path tested
-            # as input to the lambda function.
-            # only if all() values in the Map are "True" (meaning the file is
-            # not excluded) then it should yield the filename to run checks on.
-            # not dir_path.endswith(p) and
-            if all(map(lambda p: p not in dir_path,
-                       exclusion_paths)):
-                yield os.path.join(dir_path, f)
-            else:
-                exclusion_files_set.add(os.path.join(dir_path, f))
-
-
-def colors():
-    """Create a collection of helper functions to colorize strings."""
-    ansi = hasattr(sys.stderr, "isatty") and platform.system() != "Windows"
-
-    def colorize(code, string):
-        # Enable ANSI terminal color only around string provided (if valid)
-        return "%s%s%s" % (code, string, '\033[0m') if ansi else string
-
-    def cyan(s):
-        return colorize(CYAN, s)
-
-    def green(s):
-        return colorize(GREEN, s)
-
-    def red(s):
-        return colorize(RED, s)
-
-    def yellow(s):
-        return colorize(YELLOW, s)
-
-    return collections.namedtuple(
-        "Colorizer",
-        "cyan green red yellow")(cyan, green, red, yellow)
-
-# Script entrypoint.
-if __name__ == "__main__":
-
-    # Prepare message colorization methods
-    col = colors()
-
-    # Parser helpers
-    def is_dir(path):
-        """Check if path is a directory."""
-        return os.path.isdir(root_dir)
-
-    # identify the path (directory) where scanCode.py is located
-    # Use this as default for finding default configuration
-    DEFAULT_PROGRAM_PATH = os.path.split(os.path.abspath(__file__))[0]
-    # vprintf("DEFAULT_PROGRAM_PATH: =[%s]" % DEFAULT_PROGRAM_PATH)
-    DEFAULT_CONFIG_FILE = os.path.join(DEFAULT_PROGRAM_PATH,
-                                       DEFAULT_CONFIG_FILE)
-
-    # create / configure our argument parser
-    # Note: ArgumentParser catches all errors and outputs a message
-    # to override this behavior you would need to subclass it.
-    parser = argparse.ArgumentParser(description=MSG_DESCRIPTION)
-    parser.add_argument("-v", "--verbose",
-                        action="store_true",
-                        dest="verbose",
-                        default=False,
-                        help=HELP_VERBOSE)
-    parser.add_argument("-x",
-                        action="store_true",
-                        dest="display_exclusions",
-                        default=False,
-                        help=HELP_DISPLAY_EXCLUSIONS)
-    parser.add_argument("--config",
-                        type=argparse.FileType('r'),
-                        action="store",
-                        dest="config",
-                        default=DEFAULT_CONFIG_FILE,
-                        help=HELP_CONFIG_FILE)
-    parser.add_argument("root_directory",
-                        type=str,
-                        default=DEFAULT_ROOT_DIR,
-                        help=HELP_ROOT_DIR)
-
-    # Invoke parser, assign argument values to locals
-    args = parser.parse_args()
-    root_dir = args.root_directory
-    VERBOSE = args.verbose
-
-    # Config file at this point is an actual file object
-    config_file = args.config
-
-    # Assign supported scan functions to either file or line globals
-    # These checks run once per-file
-    FILE_CHECK_FUNCTIONS.update({
-        "is_not_symlink": is_not_symlink,
-        "has_block_license": has_block_license
-    })
-
-    # These checks run once per-line, per-file
-    LINE_CHECK_FUNCTIONS.update({
-        "no_tabs": no_tabs,
-        "no_trailing_spaces": no_trailing_spaces,
-        "eol_at_eof": eol_at_eof
-    })
-
-    # Read / load configuration file from file (pointer)
-    if read_config_file(config_file) == -1:
-        exit(1)
-
-    # Verify starting path parameter is valid
-    if not is_dir(root_dir):
-        print_error(ERR_PATH_IS_NOT_DIRECTORY % (sys.argv[0], root_dir))
-        parser.print_help()
-        exit(1)
-
-    # Positive feedback to caller that scanning has started
-    print_highlight(MSG_SCANNING_STARTED % root_dir)
-
-    # Runs all listed checks on all relevant files.
-    all_errors = []
-
-    for fltr, chks1, chks2 in FILTERS_WITH_CHECK_FUNCTIONS:
-        # print_error(col.cyan(MSG_SCANNING_FILTER % fltr))
-        # print_error("chks1=" + str(chks1))
-        # print_error("chks2=" + str(chks2))
-        for path in fnmatch.filter(all_paths(root_dir), fltr):
-            errors = run_file_checks(path, chks1)
-            errors += run_line_checks(path, chks2)
-            all_errors += map(lambda p: (path, p[0], p[1]), errors)
-
-    # Display path and file exclusion details
-    if args.display_exclusions or VERBOSE:
-        print_warning(WARN_SCAN_EXCLUDED_PATH_SUMMARY % len(exclusion_paths))
-        # Display all paths that were excluded (by configuration)
-        for excluded_path in exclusion_paths:
-            print_warning(WARN_SCAN_EXCLUDED_PATH % excluded_path)
-
-        # Inform caller which files where excluded from these paths
-        print_warning(WARN_SCAN_EXCLUDED_FILE_SUMMARY %
-                      len(exclusion_files_set))
-        for excluded_file in exclusion_files_set:
-            print_warning(WARN_SCAN_EXCLUDED_FILE % excluded_file)
-
-    def sort_key(p):
-        """Define sort key for error listing as the filename."""
-        # Filename is the 0th entry in tuple
-        return p[0]
-
-    if all_errors:
-        # Group / sort errors by filename
-        error_listing = ""
-        files_with_errors = 0
-        for path, triples in itertools.groupby(sorted(all_errors,
-                                                      key=sort_key),
-                                               key=sort_key):
-            files_with_errors += 1
-            error_listing += "  [%s]:\n" % path
-
-            pairs = sorted(map(lambda t: (t[1], t[2]), triples),
-                           key=lambda p: p[0])
-            for line, msg in pairs:
-                error_listing += col.red("    %4d: %s\n" % (line, msg))
-
-        # Summarize errors
-        summary = MSG_ERROR_SUMMARY % (len(all_errors), files_with_errors)
-        print_highlight(summary)
-        print(error_listing)
-        print_error(summary)
-        sys.exit(1)
-    else:
-        print_success(MSG_CHECKS_PASSED)
-sys.exit(0)
diff --git a/tools/travis/build.sh b/tools/travis/build.sh
index 60df1da..2a03a48 100755
--- a/tools/travis/build.sh
+++ b/tools/travis/build.sh
@@ -23,13 +23,15 @@ set -e
 SCRIPTDIR=$(cd $(dirname "$0") && pwd)
 ROOTDIR="$SCRIPTDIR/../.."
 HOMEDIR="$SCRIPTDIR/../../../"
+UTILDIR="$HOMEDIR/incubator-openwhisk-utilities/"
 
 # clone the openwhisk utilities repo.
 cd $HOMEDIR
 git clone https://github.com/apache/incubator-openwhisk-utilities.git
 
 # run the scancode util. against project source code starting at its root
-incubator-openwhisk-utilities/scancode/scanCode.py $ROOTDIR --config $ROOTDIR/tools/build/scanCode.cfg
+cd $UTILDIR
+scancode/scanCode.py --config scancode/ASF-Release.cfg $ROOTDIR
 
 # run scalafmt checks
 cd $ROOTDIR

-- 
To stop receiving notification emails like this one, please contact
csantanapr@apache.org.