Skip to content

Commit

Permalink
Adds scan build to Github Actions (#324)
Browse files Browse the repository at this point in the history
  • Loading branch information
agalbachicar authored Dec 1, 2020
1 parent 157afcd commit 5c4bd25
Show file tree
Hide file tree
Showing 2 changed files with 240 additions and 0 deletions.
115 changes: 115 additions & 0 deletions .github/run_scan_build
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
#!/usr/bin/python3
# Copyright 2020 Toyota Research Institute

import os
import sys

EXTRA_EXCLUDE_ARGS = " --exclude src/pybind11 --exclude /usr/include/eigen3 "

def get_package_dependencies_names(packages_up_to = None):
'''
Returns a set of dependencies by name of all the `packages-up-to` argument.
When None is provided, all the packages are returned.
'''
stream = os.popen('colcon graph') if not packages_up_to else os.popen('colcon graph --packages-up-to ' + packages_up_to)

colcon_graph = stream.read().splitlines()
result = set()
for line in colcon_graph:
result.add(line[:line.find(' ')])
return result

def get_exclusion_paths_from_file(filepath, store):
'''
Get the paths located in the `filepath` and save them in the `store` set.
'''
if(os.path.exists(filepath)):
with open(filepath) as fp:
for line in fp.readlines():
store.add(line.replace('\n', ' '))

def convert_in_exclude_argument(paths):
'''
Convert a set of paths in a `--exclude`s arguments of scan-build command.
'''
final_string = ''
for path in paths:
final_string = final_string + " --exclude " + str(path)
return final_string

def get_effective_key(args):
class Key:
def __init__(self, name):
self.name = name
self.counter = 0
self.index = 0

keys = [Key("--packages-select"), Key("--packages-up-to")]
for i, potential_key in enumerate(keys):
keys[i].counter = args.count(potential_key.name)
if (keys[i].counter > 0):
keys[i].index = args.index(potential_key.name)

if (keys[0].counter == 0 and keys[1].counter == 0):
return ''
elif (keys[0].counter == keys[1].counter):
# When there are two keys present, it just cares about the first one as colcon does.
return keys[0].name if keys[0].index < keys[1].index else keys[1].name
else:
return keys[0].name if keys[0].counter else keys[1].name

def is_colcon_option(arg):
return True if (arg[0:2] == '--') else False

def get_packages_from_args(args):
key = get_effective_key(args)
if not key:
return set()
index_of_key = args.index(key)

packages = set()
indexer = 1
while (len(args) > (index_of_key + indexer)) and (not is_colcon_option(args[index_of_key + indexer])):
packages.add(args[index_of_key + indexer])
indexer += 1
return packages

def get_packages_to_get_excludes_file_of(packages):
packages_to_get_exclude_file_of = set()
if not packages:
packages_to_get_exclude_file_of = packages_to_get_exclude_file_of.union(get_package_dependencies_names())
else:
for package_from_arg in packages:
packages_to_get_exclude_file_of = packages_to_get_exclude_file_of.union(get_package_dependencies_names(package_from_arg))
return packages_to_get_exclude_file_of


def generate_exclude_args(argv):
packages_from_arg = get_packages_from_args(argv)
packages_to_get_exclude_file_of = get_packages_to_get_excludes_file_of(packages_from_arg)

exclusion_paths = set()
for package in packages_to_get_exclude_file_of:
package_path = os.popen('colcon list --packages-select ' + package + ' --paths-only')
command = 'find ' + package_path.read().splitlines()[0] + ' -name scan_build.supp'
find = os.popen(command)
supp_filepaths = find.read().splitlines()
for filepath in supp_filepaths:
get_exclusion_paths_from_file(filepath, exclusion_paths)
return convert_in_exclude_argument(exclusion_paths)

def main(argv):
excludes_args = generate_exclude_args(argv)
excludes_args += EXTRA_EXCLUDE_ARGS

colcon_extra_build_args = " ".join(argv[1:]) if(len(argv) > 1) else ""
cmd = "scan-build-8 --status-bugs --use-cc=clang --use-c++=clang++ {} colcon build {} ".format(excludes_args, colcon_extra_build_args)
print("scan-build command...\n--> " + cmd)
return_code = os.system(cmd)
if return_code > 255 :
sys.exit(1)
else:
sys.exit(0)

if __name__ == "__main__":
main(sys.argv)
125 changes: 125 additions & 0 deletions .github/workflows/scan_build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
name: scan_build

on:
push:
branches:
- master
pull_request:

env:
PACKAGE_NAME: delphyne-gui
EXTRA_PACKAGE_NAME: delphyne-demos
ROS_DISTRO: dashing
ROS_WS: maliput_ws

jobs:
static_analysis:
name: Static analysis
runs-on: ubuntu-18.04
container:
image: ubuntu:18.04
steps:
# setup-ros first since it installs git, which is needed to fetch all branches from actions/checkout
- uses: ros-tooling/[email protected]
# install git from ppa since git 2.18+ is needed to fetch all branches from actions/checkout
# this step can be removed on 20.04
- name: install git from ppa
shell: bash
run: |
apt update;
apt install -y software-properties-common;
add-apt-repository -y -u ppa:git-core/ppa;
apt install -y git;
- uses: actions/checkout@v2
with:
path: ${{ env.ROS_WS }}/src/${{ env.PACKAGE_NAME }}
# clone private dependencies
- uses: actions/checkout@v2
with:
repository: ToyotaResearchInstitute/maliput
fetch-depth: 0
path: ${{ env.ROS_WS }}/src/maliput
token: ${{ secrets.MALIPUT_TOKEN }}
- uses: actions/checkout@v2
with:
repository: ToyotaResearchInstitute/maliput-dragway
fetch-depth: 0
path: ${{ env.ROS_WS }}/src/maliput_dragway
token: ${{ secrets.MALIPUT_TOKEN }}
- uses: actions/checkout@v2
with:
repository: ToyotaResearchInstitute/maliput-multilane
fetch-depth: 0
path: ${{ env.ROS_WS }}/src/maliput_multilane
token: ${{ secrets.MALIPUT_TOKEN }}
- uses: actions/checkout@v2
with:
repository: ToyotaResearchInstitute/malidrive
fetch-depth: 0
path: ${{ env.ROS_WS }}/src/malidrive
token: ${{ secrets.MALIPUT_TOKEN }}
- uses: actions/checkout@v2
with:
repository: ToyotaResearchInstitute/delphyne
fetch-depth: 0
path: ${{ env.ROS_WS }}/src/delphyne
token: ${{ secrets.MALIPUT_TOKEN }}
- uses: actions/checkout@v2
with:
repository: ToyotaResearchInstitute/drake-vendor
fetch-depth: 0
path: ${{ env.ROS_WS }}/src/drake_vendor
token: ${{ secrets.MALIPUT_TOKEN }}
- uses: actions/checkout@v2
with:
repository: ToyotaResearchInstitute/dsim-repos-index
fetch-depth: 0
path: dsim-repos-index
token: ${{ secrets.MALIPUT_TOKEN }}
- name: check if dependencies have a matching branch
shell: bash
working-directory: ${{ env.ROS_WS }}/src
run: ./${PACKAGE_NAME}/.github/try_vcs_checkout ${GITHUB_HEAD_REF:-${GITHUB_REF#refs/heads/}} .
# install drake_vendor prereqs using dsim-repos-index/tools/prereqs.lib
- name: install drake_vendor prereqs
shell: bash
working-directory: ${{ env.ROS_WS }}/src/drake_vendor
run: ${GITHUB_WORKSPACE}/dsim-repos-index/tools/prereqs-install -t drake .
# install delphyne prereqs using dsim-repos-index/tools/prereqs.lib
- name: install delphyne prereqs
shell: bash
working-directory: ${{ env.ROS_WS }}/src/delphyne
run: ${GITHUB_WORKSPACE}/dsim-repos-index/tools/prereqs-install -t ignition .
# install delphyne-gui prereqs using dsim-repos-index/tools/prereqs.lib
- name: install delphyne-gui prereqs
shell: bash
working-directory: ${{ env.ROS_WS }}/src/delphyne-gui
run: ${GITHUB_WORKSPACE}/dsim-repos-index/tools/prereqs-install -t ignition .
- name: clang 8 install
shell: bash
run: ${{ env.ROS_WS }}/src/${PACKAGE_NAME}/.github/clang_suite_installation.sh
# clone public dependencies
- name: vcs import
shell: bash
working-directory: ${{ env.ROS_WS }}
run: vcs import src < src/${PACKAGE_NAME}/.github/dependencies.repos
- run: colcon graph
shell: bash
working-directory: ${{ env.ROS_WS }}
- name: rosdep install
shell: bash
working-directory: ${{ env.ROS_WS }}
run: |
rosdep update;
rosdep install -i -y --rosdistro ${ROS_DISTRO} \
--skip-keys "ignition-transport5 ignition-msgs2 ignition-math6 ignition-common3 ignition-gui0 ignition-rendering2 libqt5multimedia5 pybind11" \
--from-paths src
- name: scan_build
shell: bash
working-directory: ${{ env.ROS_WS }}
run: |
. /opt/ros/${ROS_DISTRO}/setup.bash;
./src/${PACKAGE_NAME}/.github/run_scan_build \
--cmake-args -DCMAKE_LINKER=/usr/bin/llvm-ld \
--packages-up-to ${PACKAGE_NAME} ${EXTRA_PACKAGE_NAME} \
--event-handlers=console_direct+;

0 comments on commit 5c4bd25

Please sign in to comment.