Source code for rosdistro.verify

# Software License Agreement (BSD License)
#
# Copyright (c) 2013, Open Source Robotics Foundation, Inc.
# 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 Open Source Robotics Foundation, 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 difflib
import sys

import yaml

from . import get_distribution_file, get_distribution_files, get_doc_build_files, get_doc_file, get_index, get_release_build_files, get_release_file, get_source_build_files, get_source_file
from .loader import load_url


[docs]def verify_files_parsable(index_url): return verify_files(index_url, _check_files_parsable, include_deprecated=False)
def _check_files_parsable(index, dist_name, loader_function, _yaml_url, _file_type): try: loader_function(index, dist_name) except Exception as e: print(str(e), file=sys.stderr) return False return True
[docs]def reformat_files(index_url): return verify_files(index_url, _reformat_files)
[docs]def verify_files_identical(index_url): return verify_files(index_url, _check_files_identical)
[docs]def verify_files(index_url, callback, include_deprecated=False): identical = True index = get_index(index_url) for dist_name in sorted(index.distributions.keys()): dist = index.distributions[dist_name] if index.version < 3: providers = [get_distribution_file] else: providers = [get_distribution_files] if include_deprecated: providers.extend([get_release_file, get_source_file, get_doc_file]) file_providers = { 'distribution': (providers, 'distribution'), } if index.version < 3: file_providers.update({ 'release_builds': (get_release_build_files, 'release-build'), 'source_builds': (get_source_build_files, 'source-build'), 'doc_builds': (get_doc_build_files, 'doc-build') }) for key in sorted(file_providers.keys()): provider, file_type = file_providers[key] yaml_url = dist[key] if isinstance(provider, list): for p in provider: identical &= callback(index, dist_name, p, yaml_url, file_type) else: identical &= callback(index, dist_name, provider, yaml_url, file_type) return identical
def _reformat_files(index, dist_name, loader_function, yaml_url, file_type): all_identical = True files = loader_function(index, dist_name) if not isinstance(files, list): files = [files] yaml_url = [yaml_url] for i, f in enumerate(files): url = yaml_url[i] if not url.startswith('file://'): print('Skipping non-file url: %s' % url) continue identical = _check_file_identical(f, yaml_url[i], file_type) all_identical &= identical path = url[7:] if identical: print('Skipping identical file: %s' % path) continue print('Updating file: %s' % path) data = f.get_data() dist_file_data = _to_yaml(data) dist_file_data = '\n'.join(_yaml_header_lines(file_type, data['version'])) + '\n' + dist_file_data with open(path, 'w') as f: f.write(dist_file_data) return all_identical def _check_files_identical(index, dist_name, loader_function, yaml_url, file_type): identical = True files = loader_function(index, dist_name) if not isinstance(files, list): files = [files] yaml_url = [yaml_url] for i, f in enumerate(files): identical &= _check_file_identical(f, yaml_url[i], file_type) return identical def _check_file_identical(dist_file, yaml_url, file_type): yaml_str = load_url(yaml_url) yaml_lines = yaml_str.splitlines() dist_file_data = dist_file.get_data() dist_file_lines = _to_yaml(dist_file_data).splitlines() dist_file_lines[0:0] = _yaml_header_lines(file_type, dist_file_data['version']) if yaml_lines != dist_file_lines: diff = difflib.unified_diff( yaml_lines, dist_file_lines, yaml_url, 'loaded-and-saved', n=1, lineterm='') for line in diff: print(line, file=sys.stderr) return False return True def _to_yaml(data): yaml_str = yaml.dump(data, default_flow_style=False) yaml_str = yaml_str.replace(': null', ':') yaml_str = yaml_str.replace(': {}', ':') return yaml_str def _yaml_header_lines(file_type, version): rep = '141' if file_type == 'index': if version == 3: rep = '143' elif version == 4: rep = '153' if file_type == 'distribution' and version == 2: rep = '143' return [ '%YAML 1.1', '# ROS %s file' % file_type, '# see REP %s: http://ros.org/reps/rep-0%s.html' % (rep, rep), '---' ]