def generate_setup_py(project_path): return '''## ! DO NOT MANUALLY INVOKE THIS setup.py, USE CATKIN INSTEAD from distutils.core import setup from catkin_pkg.python_setup import generate_distutils_setup # fetch values from package.xml setup_args = generate_distutils_setup( packages=%r, package_dir={'': 'src'}, requires=[], # TODO ) setup(**setup_args)''' % ( utils.get_python_packages(project_path), )
def catkinize_package(path, version, maintainer_emails): """ Calculates a list of changes for one package. Changes are 4-tupels of oldfile, backupfile, newfile, contents. This comes before execution so that the user may confirm or reject changes. """ if not os.path.isdir(path): raise ValueError('No directory found at %s' % path) manifest_path = os.path.join(path, 'manifest.xml') if not os.path.isfile(manifest_path): raise ValueError( "No rosbuild package at %s, missing manifest.xml" % manifest_path) # add PATH/src/NAME/__init__.py if *.py exists in PATH/src/NAME (because rosbuild did) package_name = os.path.basename(os.path.abspath(path)) print(package_name) if any(filename.endswith('.py') for dirpath, dirnames, filenames in os.walk(os.path.join(path, 'src', package_name)) for filename in filenames): if not os.path.exists(os.path.join(path, 'src', package_name, '__init__.py')): with open(os.path.join(path, 'src', package_name, '__init__.py'), 'wb') as f: pass # build the content of the potential new CMakeLists.txt and packaeg.xml new_manifest = convert_manifest(path, manifest_path, version, maintainer_emails=maintainer_emails) new_cmake = convert_cmake(path) filenames = ['CMakeLists.txt', 'manifest.xml', 'Makefile'] newfiles = ['CMakeLists.txt', 'package.xml', None] contents = [new_cmake, new_manifest, None] if utils.get_python_packages(path): filenames.append('setup.py') newfiles.append('setup.py') contents.append(generate_setup_py(path)) return _create_changesets(path, filenames, newfiles, contents)
def convert_cmake(project_path, cmakelists_path=None, manifest_xml_path=None): # handle default arguments if not cmakelists_path: cmakelists_path = os.path.join(project_path, 'CMakeLists.txt') if not manifest_xml_path: manifest_xml_path = os.path.join(project_path, 'manifest.xml') project_name = os.path.basename(os.path.abspath(project_path)) print('Converting %s' % cmakelists_path, file=sys.stderr) with open(cmakelists_path, 'r') as f_in: content = f_in.read() # get dependencies from manifest file catkin_depends, system_depends = get_dependencies(manifest_xml_path, project_path) catkin_depends.update(utils.get_message_dependencies(project_path)) catkin_depends.update(utils.get_service_dependencies(project_path)) catkin_depends.update(utils.get_action_dependencies(project_path)) catkin_depends.discard(project_name) if utils.get_message_files(project_path) or \ utils.get_service_files(project_path) or \ utils.get_action_files(project_path): catkin_depends.add('message_generation') catkin_depends.add('message_runtime') if utils.get_action_files(project_path): catkin_depends.add('actionlib_msgs') if 'eigen' in system_depends: system_depends.remove('eigen') system_depends.add('Eigen') # anything that looks like a macro or function call tokens = list(parse(content)) # storing the originals allows interactive mode where user confirms each # change result = tokens[:1] original = tokens[:1] boost_components = set() # find replacement for each snippet. Chunks are (funcall, argslist, # otherlines) first_boost = -1 for count, (name, fun_args, rest) in enumerate(chunks(tokens[1:], 3)): oldsnippet = '%s%s' % (name, fun_args) original.append(oldsnippet) newsnippet, components = convert_boost_snippet(name, fun_args) if newsnippet is None: newsnippet = convert_snippet(name, fun_args, project_path) if newsnippet != oldsnippet: result.append(newsnippet) else: result.append(None) else: if first_boost < 0: first_boost = count * 2 + 1 boost_components = boost_components.union(components) result.append(newsnippet) result.append(None) original.append(rest) if boost_components: # reverse order due to insert result.insert(first_boost, 'include_directories(${Boost_INCLUDE_DIRS})\n') result.insert( first_boost, 'find_package(Boost REQUIRED COMPONENTS %s)\n' % ' '.join(boost_components)) original.insert(first_boost, '') original.insert(first_boost, '') result_string = '' lines = content.splitlines() if not [l for l in lines if 'catkin_package' in l]: header = make_header_lines(project_name, ' '.join(catkin_depends)) result_string += ('\n'.join(header)) if utils.get_python_packages(project_path): result_string += '\ncatkin_python_setup()\n' added_package_lines = False def my_make_package_lines(): with_messages = ('add_message_files' in result_string or 'add_service_files' in result_string or 'add_action_files' in result_string) return make_package_lines(' '.join(catkin_depends), ' '.join(system_depends), with_messages, project_path) for (old_snippet, new_snippet) in zip(original, result): if old_snippet or new_snippet: this_snippet = new_snippet or old_snippet if not added_package_lines and ( 'add_library' in this_snippet or 'add_executable' in this_snippet or 'add_custom' in this_snippet): result_string += my_make_package_lines() added_package_lines = True result_string += this_snippet if not added_package_lines: result_string += my_make_package_lines() if utils.get_scripts(project_path): result_string += '\ninstall(PROGRAMS %s DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION})\n' % ( ' '.join(utils.get_scripts(project_path)), ) return result_string