123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- #!/usr/bin/env python
- # Copyright (c) 2017, Open Source Robotics Foundation
- # All rights reserved.
- #
- # Redistribution and use in source and binary forms, with or without
- # modification, are permitted provided that the following conditions are met:
- #
- # * Redistributions of source code must retain the above copyright
- # notice, this list of conditions and the following disclaimer.
- # * Redistributions in binary form must reproduce the above copyright
- # notice, this list of conditions and the following disclaimer in the
- # documentation and/or other materials provided with the distribution.
- # * Neither the name of the Willow Garage, Inc. nor the names of its
- # contributors may be used to endorse or promote products derived from
- # this software without specific prior written permission.
- #
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
- # LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
- # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
- # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
- # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- # POSSIBILITY OF SUCH DAMAGE.
- import argparse
- import os
- import sys
- import yaml
- from rosdep2.sources_list import load_cached_sources_list, DataSourceMatcher, SourcesListLoader, CachedDataSource
- from rosdep2.lookup import RosdepLookup
- from rosdep2.rospkg_loader import DEFAULT_VIEW_KEY
- from rosdep2.sources_list import *
- def create_default_sources():
- sources = []
- # get all rosdistro files
- basedir = os.path.realpath(os.path.join(os.path.dirname(os.path.realpath(__file__)), '..'))
- filepath = os.path.join(basedir, 'index.yaml')
- with open(filepath) as f:
- content = f.read()
- index = yaml.safe_load(content)
- for distro in index['distributions']:
- distfile = 'file://' + basedir + '/' + distro + '/distribution.yaml'
- print('loading %s' % distfile)
- try:
- rds = RosDistroSource(distro)
- except KeyError:
- # When first adding a ROS distro to the repository, it won't yet
- # exist at the URL that RosDistroSource fetches from github. When
- # trying to index it, RosDistroSource will throw a KeyError. If we
- # see that KeyError, just ignore it and don't add the distro to the
- # list of sources.
- continue
- rosdep_data = get_gbprepo_as_rosdep_data(distro)
- sources.append(CachedDataSource('yaml', distfile, [distro], rosdep_data))
- for filename in os.listdir(os.path.join(basedir, 'rosdep')):
- if not filename.endswith('yaml'):
- continue
- filepath = os.path.join(basedir, 'rosdep', filename)
- with open(filepath) as f:
- content = f.read()
- rosdep_data = yaml.safe_load(content)
- tag = 'osx' if 'osx-' in filepath else ''
- sources.append(CachedDataSource('yaml', 'file://' + filepath, [tag], rosdep_data))
- return sources
- def check_duplicates(sources, os_name, os_codename):
- # output debug info
- print('checking sources')
- for source in sources:
- print('- %s' % source.url)
- # create lookup
- sources_loader = SourcesListLoader(sources)
- lookup = RosdepLookup.create_from_rospkg(sources_loader=sources_loader)
- # check if duplicates
- print("checking duplicates")
- db_name_view = {}
- has_duplicates = False
- # to avoid merge views
- view = lookup._load_view_dependencies(DEFAULT_VIEW_KEY, lookup.loader)
- for view_key in lookup.rosdep_db.get_view_dependencies(DEFAULT_VIEW_KEY):
- db_entry = lookup.rosdep_db.get_view_data(view_key)
- print('* %s' % view_key)
- for dep_name, dep_data in db_entry.rosdep_data.items():
- # skip unknown os names
- if os_name not in dep_data.keys():
- continue
- # skip unknown os codenames
- if (
- isinstance(dep_data[os_name], dict) and
- 'pip' not in dep_data[os_name].keys() and
- os_codename not in dep_data[os_name].keys()
- ):
- continue
- if dep_name in db_name_view:
- print('%s (%s, %s) is multiply defined in\n\t%s and \n\t%s\n' %
- (dep_name, os_name, os_codename, db_name_view[dep_name], view_key))
- has_duplicates = True
- db_name_view[dep_name] = view_key
- return not has_duplicates
- def main(infile):
- sources = create_default_sources()
- matcher = DataSourceMatcher.create_default()
- print('default sources')
- for source in sources:
- print('- %s' % source.url)
- # replace with infile
- for filename in infile:
- filepath = os.path.join(os.getcwd(), filename)
- with open(filepath) as f:
- content = f.read()
- rosdep_data = yaml.safe_load(content)
- # osx-homebrew uses osx tag
- tag = 'osx' if 'osx-' in filepath else ''
- model = CachedDataSource('yaml', 'file://' + filepath, [tag], rosdep_data)
- # add sources if not exists
- if not [x for x in sources if os.path.basename(filename) == os.path.basename(x.url)]:
- sources.append(model)
- else:
- # remove files with same filename
- sources = [model if os.path.basename(filename) == os.path.basename(x.url) else x for x in sources]
- ret = True
- for tag in [['indigo', 'ubuntu', 'trusty'],
- ['jade', 'ubuntu', 'trusty'],
- ['kinetic', 'ubuntu', 'xenial'],
- ['lunar', 'ubuntu', 'xenial'],
- ['', 'osx', 'homebrew']]:
- matcher.tags = tag
- print('checking with %s' % matcher.tags)
- os_name = tag[1]
- os_codename = tag[2]
- ret &= check_duplicates([x for x in sources if matcher.matches(x)],
- os_name, os_codename)
- return ret
- if __name__ == '__main__':
- parser = argparse.ArgumentParser(description='Checks whether rosdep files contain duplicate ROS rules')
- parser.add_argument('infiles', nargs='*', help='input rosdep YAML file')
- args = parser.parse_args()
- if not main(args.infiles):
- sys.exit(1)
|