def identify_license(self, content, license_part): for name, license in get_licenses().items(): if content is not None and getattr(license, license_part) == content: self.license_identifier = name break else: self.license_identifier = UNKNOWN_IDENTIFIER
def identify_license(self, content, license_part): if content is None: return for name, license_ in get_licenses().items(): template = getattr(license_, license_part).replace('\n', ' ').strip() last_index = -1 for license_section in template.split('{copyright_holder}'): # OK, now look for each section of the license in the incoming # content. index = content.replace('\n', ' ').strip().find(license_section.strip()) if index == -1 or index <= last_index: # Some part of the license is not in the content, or the license # is rearranged, this license doesn't match. break last_index = index else: # We found the license, so set it self.license_identifier = name break
def identify_license(self, content, license_part): if content is None: return for name, license_ in get_licenses().items(): template = remove_formatting(getattr(license_, license_part)) last_index = -1 for license_section in template.split('{copyright_holder}'): # OK, now look for each section of the license in the incoming # content. index = remove_formatting(content).find( license_section.strip()) if index == -1 or index <= last_index: # Some part of the license is not in the content, or the license # is rearranged, this license doesn't match. break last_index = index else: # We found the license, so set it self.license_identifier = name break
def main(argv=sys.argv[1:]): extensions = [ 'c', 'cc', 'cpp', 'cxx', 'h', 'hh', 'hpp', 'hxx', 'cmake', 'py', ] parser = argparse.ArgumentParser( description='Check code files for copyright and license information.', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument( 'paths', nargs='*', default=[os.curdir], help='The files or directories to check. For directories files ending ' "in %s will be considered (except directories starting with '.' " "or '_' and 'setup.py' files beside 'package.xml' files)." % ', '.join(["'.%s'" % e for e in extensions])) parser.add_argument('--exclude', metavar='filename', nargs='*', dest='excludes', help='The filenames to exclude.') group = parser.add_mutually_exclusive_group() group.add_argument( '--add-missing', nargs=2, metavar=('COPYRIGHT_NAME', 'LICENSE'), help=('Add missing copyright notice and license information using the ' 'passed copyright holder and license')) group.add_argument( '--add-copyright-year', nargs='*', type=int, help='Add the current year to existing copyright notices') group.add_argument('--list-copyright-names', action='store_true', help='List names of known copyright holders') group.add_argument('--list-licenses', action='store_true', help='List names of known licenses') parser.add_argument( '--verbose', action='store_true', help= 'Show all files instead of only the ones with errors / modifications') # not using a file handle directly # in order to prevent leaving an empty file when something fails early group.add_argument('--xunit-file', help='Generate a xunit compliant XML file') args = parser.parse_args(argv) names = get_copyright_names() if args.list_copyright_names: for key in sorted(names.keys()): print('%s: %s' % (key, names[key])) return 0 licenses = get_licenses() if args.list_licenses: for key in sorted(licenses.keys()): print('%s: %s' % (key, licenses[key].name)) return 0 if args.xunit_file: start_time = time.time() filenames = get_files(args.paths, extensions) if args.excludes: filenames = [ f for f in filenames if os.path.basename(f) not in args.excludes ] if not filenames: print('No repository roots and files found', file=sys.stderr) return 0 file_descriptors = {} for filename in sorted(filenames): file_descriptors[filename] = parse_file(filename) if args.add_missing: name = names.get(args.add_missing[0], args.add_missing[0]) if args.add_missing[1] not in licenses: parser.error( "'LICENSE' argument must be a known license name. " "Use the '--list-licenses' options to see alist of valid license names." ) license = licenses[args.add_missing[1]] add_missing_header(file_descriptors, name, license, args.verbose) return 0 if args.add_copyright_year is not None: if not args.add_copyright_year: args.add_copyright_year.append(time.strftime('%Y')) args.add_copyright_year = [ int(year) for year in args.add_copyright_year ] add_copyright_year(file_descriptors, args.add_copyright_year, args.verbose) return 0 report = [] # check each directory for CONTRIBUTING.md and LICENSE files for path in sorted(file_descriptors.keys()): file_descriptor = file_descriptors[path] message = None has_error = False if file_descriptor.filetype == SOURCE_FILETYPE: if not file_descriptor.exists: message = 'file not found' has_error = True elif not file_descriptor.content: message = 'file empty' elif not file_descriptor.copyright_identifiers: message = 'could not find copyright notice' has_error = True else: message = 'copyright=%s, license=%s' % \ (', '.join([str(c) for c in file_descriptor.copyrights]), file_descriptor.license_identifier) has_error = file_descriptor.license_identifier == UNKNOWN_IDENTIFIER elif file_descriptor.filetype in [ CONTRIBUTING_FILETYPE, LICENSE_FILETYPE ]: if not file_descriptor.exists: message = 'file not found' has_error = True elif not file_descriptor.content: message = 'file empty' has_error = True elif file_descriptor.license_identifier: message = file_descriptor.license_identifier has_error = file_descriptor.license_identifier == UNKNOWN_IDENTIFIER else: assert False, file_descriptor else: assert False, 'Unknown filetype: ' + file_descriptor.filetype if args.verbose or has_error: print('%s: %s' % (file_descriptor.path, message), file=sys.stderr if has_error else sys.stdout) report.append((file_descriptor.path, not has_error, message)) # output summary error_count = len([r for r in report if not r[1]]) if not error_count: print('No errors, checked %d files' % len(report)) rc = 0 else: print('%d errors, checked %d files' % (error_count, len(report)), file=sys.stderr) rc = 1 # generate xunit file if args.xunit_file: folder_name = os.path.basename(os.path.dirname(args.xunit_file)) file_name = os.path.basename(args.xunit_file) suffix = '.xml' if file_name.endswith(suffix): file_name = file_name[0:-len(suffix)] suffix = '.xunit' if file_name.endswith(suffix): file_name = file_name[0:-len(suffix)] testname = '%s.%s' % (folder_name, file_name) xml = get_xunit_content(report, testname, time.time() - start_time) path = os.path.dirname(os.path.abspath(args.xunit_file)) if not os.path.exists(path): os.makedirs(path) with open(args.xunit_file, 'w') as f: f.write(xml) return rc
def main(self, *, args): available_licenses = {} for shortname, entry in ament_copyright.get_licenses().items(): available_licenses[entry.spdx] = entry.license_files if args.license == '?': print('Supported licenses:\n%s' % ('\n'.join(available_licenses))) sys.exit(0) maintainer = Person(args.maintainer_name) if args.maintainer_email: maintainer.email = args.maintainer_email else: # try getting the email from the global git config git = shutil.which('git') if git is not None: p = subprocess.Popen([git, 'config', 'user.email'], stdout=subprocess.PIPE) resp = p.communicate() email = resp[0].decode().rstrip() if email: maintainer.email = email if not maintainer.email: maintainer.email = maintainer.name + '@todo.todo' node_name = None library_name = None if args.library_name: library_name = args.library_name if args.node_name: node_name = args.node_name if args.node_name == args.library_name: node_name = args.node_name + '_node' print( '[WARNING] node name can not be equal to the library name', file=sys.stderr) print('[WARNING] renaming node to %s' % node_name, file=sys.stderr) buildtool_depends = [] if args.build_type == 'ament_cmake': if args.library_name: buildtool_depends = ['ament_cmake_ros'] else: buildtool_depends = ['ament_cmake'] test_dependencies = [] if args.build_type == 'ament_cmake': test_dependencies = ['ament_lint_auto', 'ament_lint_common'] if args.build_type == 'ament_python': test_dependencies = [ 'ament_copyright', 'ament_flake8', 'ament_pep257', 'python3-pytest' ] if args.build_type == 'ament_python' and args.package_name == 'test': # If the package name is 'test', there will be a conflict between # the directory the source code for the package goes in and the # directory the tests for the package go in. return "Aborted since 'ament_python' packages can't be named 'test'. Please " + \ 'choose a different package name.' package = Package( package_format=args.package_format, name=args.package_name, version='0.0.0', description=args.description, maintainers=[maintainer], licenses=[args.license], buildtool_depends=[Dependency(dep) for dep in buildtool_depends], build_depends=[Dependency(dep) for dep in args.dependencies], test_depends=[Dependency(dep) for dep in test_dependencies], exports=[Export('build_type', content=args.build_type)]) package_path = os.path.join(args.destination_directory, package.name) if os.path.exists(package_path): return '\nAborted!\nThe directory already exists: ' + package_path + '\nEither ' + \ 'remove the directory or choose a different destination directory or package name' print('going to create a new package') print('package name:', package.name) print('destination directory:', os.path.abspath(args.destination_directory)) print('package format:', package.package_format) print('version:', package.version) print('description:', package.description) print('maintainer:', [str(maintainer) for maintainer in package.maintainers]) print('licenses:', package.licenses) print('build type:', package.get_build_type()) print('dependencies:', [str(dependency) for dependency in package.build_depends]) if node_name: print('node_name:', node_name) if library_name: print('library_name:', library_name) package_directory, source_directory, include_directory = \ create_package_environment(package, args.destination_directory) if not package_directory: return 'unable to create folder: ' + args.destination_directory if args.build_type == 'cmake': populate_cmake(package, package_directory, node_name, library_name) if args.build_type == 'ament_cmake': populate_ament_cmake(package, package_directory, node_name, library_name) if args.build_type == 'ament_python': if not source_directory: return 'unable to create source folder in ' + args.destination_directory populate_ament_python(package, package_directory, source_directory, node_name) if node_name: populate_python_node(package, source_directory, node_name) if library_name: populate_python_libary(package, source_directory, library_name) if args.build_type == 'ament_cmake' or args.build_type == 'cmake': if node_name: if not source_directory: return 'unable to create source folder in ' + args.destination_directory populate_cpp_node(package, source_directory, node_name) if library_name: if not source_directory or not include_directory: return 'unable to create source or include folder in ' + \ args.destination_directory populate_cpp_library(package, source_directory, include_directory, library_name) if args.license in available_licenses: with open(os.path.join(package_directory, 'LICENSE'), 'w') as outfp: for lic in available_licenses[args.license]: outfp.write(lic) else: print( "\n[WARNING]: Unknown license '%s'. This has been set in the package.xml, but " 'no LICENSE file has been created.\nIt is recommended to use one of the ament ' 'license identitifers:\n%s' % (args.license, '\n'.join(available_licenses)))
def main(argv=sys.argv[1:]): extensions = [ 'c', 'cc', 'cpp', 'cxx', 'h', 'hh', 'hpp', 'hxx', 'cmake', 'py', ] parser = argparse.ArgumentParser( description='Check code files for copyright and license information.', formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument( 'paths', nargs='*', default=[os.curdir], help='The files or directories to check. For directories files ending ' "in %s will be considered (except directories starting with '.' " "or '_' and 'setup.py' files beside 'package.xml' files)." % ', '.join(["'.%s'" % e for e in extensions])) parser.add_argument( '--exclude', metavar='filename', nargs='*', dest='excludes', help='The filenames to exclude.') group = parser.add_mutually_exclusive_group() group.add_argument( '--add-missing', nargs=2, metavar=('COPYRIGHT_NAME', 'LICENSE'), help=( 'Add missing copyright notice and license information using the ' 'passed copyright holder and license')) group.add_argument( '--add-copyright-year', nargs='*', type=int, help='Add the current year to existing copyright notices') group.add_argument( '--list-copyright-names', action='store_true', help='List names of known copyright holders') group.add_argument( '--list-licenses', action='store_true', help='List names of known licenses') parser.add_argument( '--verbose', action='store_true', help='Show all files instead of only the ones with errors / modifications') # not using a file handle directly # in order to prevent leaving an empty file when something fails early group.add_argument( '--xunit-file', help='Generate a xunit compliant XML file') args = parser.parse_args(argv) names = get_copyright_names() if args.list_copyright_names: for key in sorted(names.keys()): print('%s: %s' % (key, names[key])) return 0 licenses = get_licenses() if args.list_licenses: for key in sorted(licenses.keys()): print('%s: %s' % (key, licenses[key].name)) return 0 if args.xunit_file: start_time = time.time() filenames = get_files(args.paths, extensions) if args.excludes: filenames = [f for f in filenames if os.path.basename(f) not in args.excludes] if not filenames: print('No repository roots and files found', file=sys.stderr) return 0 file_descriptors = {} for filename in sorted(filenames): file_descriptors[filename] = parse_file(filename) if args.add_missing: name = names.get(args.add_missing[0], args.add_missing[0]) if args.add_missing[1] not in licenses: parser.error( "'LICENSE' argument must be a known license name. " "Use the '--list-licenses' options to see alist of valid license names.") license = licenses[args.add_missing[1]] add_missing_header(file_descriptors, name, license, args.verbose) return 0 if args.add_copyright_year is not None: if not args.add_copyright_year: args.add_copyright_year.append(time.strftime('%Y')) args.add_copyright_year = [int(year) for year in args.add_copyright_year] add_copyright_year(file_descriptors, args.add_copyright_year, args.verbose) return 0 report = [] # check each directory for CONTRIBUTING.md and LICENSE files for path in sorted(file_descriptors.keys()): file_descriptor = file_descriptors[path] message = None has_error = False if file_descriptor.filetype == SOURCE_FILETYPE: if not file_descriptor.exists: message = 'file not found' has_error = True elif not file_descriptor.content: message = 'file empty' elif not file_descriptor.copyright_identifiers: message = 'could not find copyright notice' has_error = True else: message = 'copyright=%s, license=%s' % \ (', '.join([str(c) for c in file_descriptor.copyrights]), file_descriptor.license_identifier) has_error = file_descriptor.license_identifier == UNKNOWN_IDENTIFIER elif file_descriptor.filetype in [CONTRIBUTING_FILETYPE, LICENSE_FILETYPE]: if not file_descriptor.exists: message = 'file not found' has_error = True elif not file_descriptor.content: message = 'file empty' has_error = True elif file_descriptor.license_identifier: message = file_descriptor.license_identifier has_error = file_descriptor.license_identifier == UNKNOWN_IDENTIFIER else: assert False, file_descriptor else: assert False, 'Unknown filetype: ' + file_descriptor.filetype if args.verbose or has_error: print('%s: %s' % (file_descriptor.path, message), file=sys.stderr if has_error else sys.stdout) report.append((file_descriptor.path, not has_error, message)) # output summary error_count = len([r for r in report if not r[1]]) if not error_count: print('No errors, checked %d files' % len(report)) rc = 0 else: print('%d errors, checked %d files' % (error_count, len(report)), file=sys.stderr) rc = 1 # generate xunit file if args.xunit_file: folder_name = os.path.basename(os.path.dirname(args.xunit_file)) file_name = os.path.basename(args.xunit_file) suffix = '.xml' if file_name.endswith(suffix): file_name = file_name[0:-len(suffix)] suffix = '.xunit' if file_name.endswith(suffix): file_name = file_name[0:-len(suffix)] testname = '%s.%s' % (folder_name, file_name) xml = get_xunit_content(report, testname, time.time() - start_time) path = os.path.dirname(os.path.abspath(args.xunit_file)) if not os.path.exists(path): os.makedirs(path) with open(args.xunit_file, 'w') as f: f.write(xml) return rc