def update_manifest(self): build_depends = self.get_build_dependencies() run_depends = self.get_run_dependencies() test_depends = self.get_test_dependencies() self.manifest.add_packages(build_depends, run_depends, test_depends) if len(self.files['msg']) + len(self.files['srv']) + len( self.files['action']) > 0: md = self.get_dependencies_from_msgs() self.manifest.add_packages(md, md) self.manifest.add_message_dependencies() if CFG.should('remove_empty_export_tag'): self.manifest.remove_empty_export() if self.manifest.is_metapackage() and CFG.should( 'update_metapackage_deps'): parent_path = os.path.abspath(os.path.join(self.root, '..')) parent_folder = os.path.split(parent_path)[1] if self.name == parent_folder: for package in get_packages(parent_path, create_objects=False): pkg_name = os.path.split(package)[1] if pkg_name != self.name: self.manifest.add_packages([], [pkg_name], allow_depend_tag=False) self.manifest.output()
def output(self, new_fn=None): if CFG.should('enforce_manifest_ordering'): self.enforce_ordering() if CFG.should('enforce_package_tabbing'): self.enforce_tabbing(self.root) if self.format == 2 and CFG.should( 'consolidate_depend_in_package_xml'): self.replace_package_set( ['build_depend', 'build_export_depend', 'exec_depend'], 'depend') if new_fn is None: new_fn = self.fn s = self.tree.toxml(self.tree.encoding) if not self.header: s = s.replace('<?xml version="1.0" ?>', '').strip() else: s = s.replace('?><package', '?>\n<package') s = s.replace(' ?>', '?>') if CFG.should('remove_dumb_package_comments'): s = clean_contents(s, 'package', {'package': self.name}) if CFG.should('remove_empty_package_lines'): s = remove_blank_lines(s) old_s = open(new_fn, 'r').read().decode('UTF-8') if old_s.strip() == s: return f = open(new_fn, 'w') f.write(s.encode('UTF-8')) f.write('\n') f.close()
def output(self, new_fn=None): if CFG.should('enforce_manifest_ordering'): self.enforce_ordering() if new_fn is None: new_fn = self.fn s = self.tree.toxml() if not self.header: s = s.replace('<?xml version="1.0" ?>', '').strip() else: s = s.replace(' ?><package>', '?>\n<package>') if CFG.should('remove_dumb_package_comments'): for line in IGNORE_LINES: s = s.replace(line, '') if CFG.should('remove_empty_package_lines'): while '\n\n\n' in s: s = s.replace('\n\n\n', '\n\n') old_s = open(new_fn, 'r').read() if old_s.strip() == s: return f = open(new_fn, 'w') f.write(s) f.write('\n') f.close()
def __init__(self, fn): self.tree = parse(fn) self.root = self.tree.childNodes[0] self.header = '<?xml' in open(fn).read() self.fn = fn self._format = None if self.format > 1: raise Exception('Only catkin format 1 is supported') tab_ct = collections.defaultdict(int) for c in self.root.childNodes: if c.nodeType == c.TEXT_NODE: spaces = count_trailing_spaces(c.data) tab_ct[spaces] += 1 self.std_tab = max(tab_ct.iteritems(), key=operator.itemgetter(1))[0] if CFG.should('enforce_package_tabbing'): for c in self.root.childNodes: if c.nodeType == c.TEXT_NODE and c!=self.root.childNodes[-1]: spaces = count_trailing_spaces(c.data) if spaces > self.std_tab: c.data = c.data[: self.std_tab-spaces] elif spaces < self.std_tab: c.data = c.data + ' '*(self.std_tab-spaces)
def add_packages(self, build_depends, run_depends, test_depends=None, allow_depend_tag=True): if self.format == 1: run_depends += build_depends existing_build = self.get_packages('build') existing_run = self.get_packages('run') build_depends = set(build_depends) - existing_build run_depends = set(run_depends) - existing_run if self.format == 1: self.insert_new_elements('build_depend', build_depends) self.insert_new_elements('run_depend', run_depends) elif CFG.should('always_add_depend_in_format_2') and allow_depend_tag: self.insert_new_elements('depend', build_depends.union(run_depends)) else: both = build_depends.intersection(run_depends) self.insert_new_elements('depend', both) self.insert_new_elements('build_depend', build_depends - both) self.insert_new_elements('exec_depend', build_depends - both - existing_run) self.insert_new_elements('exec_depend', run_depends - both) if test_depends is not None and len(test_depends) > 0: existing_test = self.get_packages('test') test_depends = set( test_depends) - existing_build - build_depends - existing_test self.insert_new_elements('test_depend', test_depends)
def get_build_dependencies(self): packages = set() if CFG.should('read_source'): for source in self.sources: packages.update(source.get_dependencies()) if self.name in packages: packages.remove(self.name) return sorted(list(packages))
def output(self, fn=None): if CFG.should('enforce_cmake_ordering'): self.enforce_ordering() s = str(self) if CFG.should('remove_dumb_cmake_comments'): s = remove_all_hashes(s) s = clean_contents(s, 'cmake', {'package': self.name}) if CFG.should('remove_empty_cmake_lines'): s = remove_blank_lines(s) if '(\n)' in s: s = s.replace('(\n)', '()') if fn is None: fn = self.fn with open(fn, 'w') as cmake: cmake.write(s)
def update_cmake(self): deps = self.get_dependencies_from_msgs() self.cmake.check_dependencies(self.get_build_dependencies() + deps) if CFG.should('check_exported_dependencies'): self.cmake.check_exported_dependencies( self.name, self.get_message_dependencies()) if CFG.should('target_catkin_libraries'): self.cmake.check_libraries() self.cmake.check_generators(self.files['msg'], self.files['srv'], self.files['action'], self.files['cfg'], deps) if self.has_header_files(): self.cmake.check_include_path() if len(self.get_cpp_source()) > 0: self.cmake.add_catkin_include_path() self.cmake.check_library_setup() setup = self.get_setup_py() if setup and setup.valid and 'catkin_python_setup' not in self.cmake.content_map: self.cmake.add_command_string('catkin_python_setup()') if CFG.should('prettify_catkin_package_cmd'): self.cmake.catkin_package_cleanup() if CFG.should('prettify_package_lists'): self.cmake.package_lists_cleanup() if CFG.should('prettify_msgs_srvs'): self.cmake.msg_srv_cleanup() if CFG.should('prettify_installs'): self.cmake.install_cleanup() if CFG.should('check_installs'): self.cmake.update_cplusplus_installs() if setup: self.cmake.update_python_installs(setup.execs) if CFG.should('check_misc_installs'): extra_files_by_folder = collections.defaultdict(list) the_root = os.path.join(self.root, '') for category, files in self.files.iteritems(): if category in [ 'source', 'msg', 'srv', 'action', 'cfg', None ]: continue for fn in files: path, base = os.path.split(fn.replace(the_root, '', 1)) if base in FILES_TO_NOT_INSTALL: continue extra_files_by_folder[path].append(base) for folder, files in extra_files_by_folder.iteritems(): self.cmake.update_misc_installs(files, folder) self.cmake.output()
def get_run_dependencies(self): packages = set() if CFG.should('read_launches'): for launch in self.files['launch']: x = Launch(launch) packages.update(x.get_dependencies()) if self.name in packages: packages.remove(self.name) return sorted(list(packages))
def __repr__(self): if CFG.should('alphabetize') and self.name in SHOULD_ALPHABETIZE: self.values = sorted(self.values) s = self.style.prename if len(self.name) > 0: s += self.name s += self.style.name_val_sep s += self.style.val_sep.join(self.values) return s
def update_cmake(self): deps = self.get_dependencies_from_msgs() self.cmake.check_dependencies( self.get_dependencies() + deps) if CFG.should('check_exported_dependencies'): self.cmake.check_exported_dependencies(self.name, self.get_message_dependencies()) self.cmake.check_generators( self.files['msg'], self.files['srv'], self.files['action'], self.files['cfg'], deps) setup = self.get_setup_py() if setup and setup.valid and \ 'catkin_python_setup' not in self.cmake.content_map: self.cmake.add_command('catkin_python_setup()') if CFG.should('check_installs'): self.cmake.update_cplusplus_installs() if setup: self.cmake.update_python_installs(setup.execs) self.cmake.output()
def output(self, fn=None): if CFG.should('enforce_cmake_ordering'): self.enforce_ordering() s = str(self) if CFG.should('remove_dumb_cmake_comments'): D = {'package': self.name} for line in IGNORE_LINES: s = s.replace(line, '') for pattern in IGNORE_PATTERNS: s = s.replace(pattern % D, '') if CFG.should('remove_empty_cmake_lines'): while '\n\n\n' in s: s = s.replace('\n\n\n', '\n\n') if fn is None: fn = self.fn with open(fn, 'w') as cmake: cmake.write(s)
def update_manifest(self): for build in [True, False]: dependencies = self.get_dependencies(build) if build: self.manifest.add_packages(dependencies, build) self.manifest.add_packages(dependencies, False) if len(self.files['msg']) + len(self.files['srv']) + len(self.files['action']) > 0: self.manifest.add_packages(['message_runtime'], True) if CFG.should('remove_empty_export_tag'): self.manifest.remove_empty_export() self.manifest.output()
def __repr__(self): if CFG.should('alphabetize_cmake_options') and self.name in SHOULD_ALPHABETIZE: self.values = sorted(self.values) s = self.pre if len(self.name)>0: s += self.name if self.tab is None and len(self.values)>0: s += ' ' elif len(self.values)>0: s += '\n' + ' ' *self.tab if self.tab is None: s += ' '.join(self.values) else: s += ('\n' + ' '*self.tab).join(self.values) return s
def enforce_ordering(self): chunks = [] current = [] for x in self.root.childNodes: current.append(x) if x.nodeType == x.ELEMENT_NODE: chunks.append((x, current)) current = [] if len(current) > 0: chunks.append((None, current)) self.root.childNodes = [] alpha = CFG.should('alphabetize') key = lambda d: get_sort_key(d[0], alpha) for a, b in sorted(chunks, key=key): self.root.childNodes += b
def enforce_ordering(self): chunks = [] current = [] group = None for x in self.root.childNodes: current.append(x) if x.nodeType==x.ELEMENT_NODE: chunks.append( (x, current) ) current = [] if len(current)>0: chunks.append( (None, current) ) self.root.childNodes = [] alpha = CFG.should('alphabetize_depends') key = lambda d: get_sort_key(d[0], alpha) for a,b in sorted(chunks, key=key): self.root.childNodes += b
def fix_people(pkgs, interactive=True): people = collections.defaultdict(set) for package in pkgs: for tag, the_list in package.get_people().iteritems(): for name, email in the_list: people[email].add(name) if 'canonical_names' not in CFG and interactive: name = query( 'What is your name (exactly as you\'d like to see it in the documentation)? ' ) email = query('What is your email (for documentation purposes)? ') CFG['canonical_names'] = [{'name': name, 'email': email}] canonical = [] canonical_names = {} canonical_emails = {} for d in CFG['canonical_names']: name = d['name'] email = d['email'] canonical_names[name] = email canonical_emails[email] = name canonical.append((name, email)) replace_rules = {} for d in CFG.get('replace_rules', []): from_key = d['from']['name'], d['from']['email'] to_key = d['to']['name'], d['to']['email'] replace_rules[from_key] = to_key for email, names in people.iteritems(): if len(names) == 1: one_name = list(names)[0] matching_rule = get_rule_match(replace_rules, one_name, email) if matching_rule is not None: continue elif email in canonical_emails: if canonical_emails[email] == one_name: continue else: print 'The name "%s" found in the packages for %s does not match saved name "%s"' % \ (one_name, email, canonical_emails[email]) continue elif one_name in canonical_names: print 'The email "%s" found in the packages for %s does not match saved email "%s"' % \ (email, one_name, canonical_names[one_name]) continue elif interactive: response = 'x' while response not in 'abcq': print 'New person %s/%s found! What would you like to do? ' % ( one_name, email) print ' a) Leave it be.' print ' b) Replace with another.' print ' c) Mark as canonical name.' print ' q) Quit.' response = raw_input('? ').lower() if response == 'q': exit(0) elif response == 'a': continue elif response == 'b': response = '' new_name = None new_email = None options = canonical[:] for email0, names0 in people.iteritems(): if email == email0: continue for name in names0: key = (name, email0) if key not in options: options.append((name, email0)) while True: print "== Options ==" for i, (name, email0) in enumerate(options): print '%d) %s/%s' % (i, name, email0) print 'n) None of the above' print 'i) Nevermind.' print 'q) Quit.' response = raw_input('? ') if response == 'q': exit(0) elif response == 'i': continue elif response == 'n': new_name = query('New name? ') new_email = query('New email? ') break try: choice = int(response) if choice >= 0 and choice < len(options): new_name, new_email = options[choice] break except: None if new_name and new_email: new_key = '%s/%s' % (new_name, new_email) response = 'x' while response not in 'abcdq': print "== Should we always do this? ==" print ' a) Always replace exact match %s/%s with %s' % ( one_name, email, new_key) print ' b) Replace anyone with the name %s with %s' % ( one_name, new_key) print ' c) Replace anyone with the email %s with %s' % ( email, new_key) print ' d) Just do it for now.' print ' q) Quit.' response = raw_input('? ').lower() if response == 'q': exit(0) if response == 'b': email = '*' elif response == 'c': one_name = '*' replace_rules[(one_name, email)] = (new_name, new_email) if response in 'abc': new_value = {} new_value['from'] = { 'email': simplify(email), 'name': simplify(one_name) } new_value['to'] = { 'email': simplify(new_email), 'name': simplify(new_name) } if 'replace_rules' not in CFG: CFG['replace_rules'] = [] CFG['replace_rules'].append(new_value) else: canonical_names[one_name] = email canonical_emails[email] = one_name canonical.append((one_name, email)) if 'canonical_names' not in CFG: CFG['canonical_names'] = [] CFG['canonical_names'].append({ 'name': simplify(one_name), 'email': simplify(email) }) continue elif len(email) > 0: print 'Found %s with multiple names: %s' % (email, ', '.join(names)) for package in pkgs: package.update_people(replace_rules)