create_rosjava_project.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 
00003 ##############################################################################
00004 # Imports
00005 ##############################################################################
00006 
00007 from __future__ import print_function
00008 
00009 import os
00010 import re
00011 import sys
00012 import argparse
00013 import xml.etree.ElementTree as ElementTree
00014 
00015 # local imports
00016 import utils
00017 import console
00018 
00019 ##############################################################################
00020 # Methods
00021 ##############################################################################
00022 
00023 
00024 def parse_arguments():
00025     argv = sys.argv[1:]
00026     parser = argparse.ArgumentParser(
00027         description='Creates a new rosjava package based on catkin and gradle. \n')
00028     parser.add_argument('name',
00029                         nargs=1,
00030                         help='The name for the package')
00031     parser.add_argument('-a', '--author',
00032                         action='store',
00033                         default=utils.author_name(),
00034                         help='A single author, may be used multiple times')
00035     args = parser.parse_args(argv)
00036     return args
00037 
00038 
00039 ##############################################################################
00040 # Methods acting on classes
00041 ##############################################################################
00042 
00043 
00044 # This inserts the labelled variables into the template wherever the corresponding
00045 # %package, %brief, %description and %depends is found.
00046 def instantiate_template(template, project_name, author):
00047     return template % locals()
00048 
00049 
00050 def instantiate_code_template(template, package_name, project_name, author):
00051     return template % locals()
00052 
00053 
00054 def create_gradle_package_files(args, template_directory):
00055     '''
00056       This is almost a direct copy from catkin_create_pkg.
00057     '''
00058     try:
00059         project_name = args.name[0].lower()
00060         package_path = os.path.abspath(os.path.join(os.getcwd(), project_name))
00061         for template_name in ['build.gradle']:  # 'CMakeLists.txt']:
00062             filename = os.path.join(package_path, template_name)
00063             template = utils.read_template_file(template_directory, template_name)
00064             contents = instantiate_template(template, project_name, args.author)
00065             try:
00066                 f = open(filename, 'w')
00067                 f.write(contents)
00068                 console.pretty_print('  File      : ', console.cyan)
00069                 console.pretty_println(template_name, console.yellow)
00070             finally:
00071                 f.close()
00072     except Exception:
00073         raise
00074 
00075 
00076 def create_talker_listener_classes(project_name, template_directory, author):
00077     path = os.path.join(os.getcwd(), project_name.lower())
00078     package_name = os.path.basename(os.getcwd())
00079     java_package_path = os.path.join(path, 'src', 'main', 'java', 'com', 'github', package_name, project_name)
00080     utils.mkdir_p(java_package_path)
00081     try:
00082         for template_name in ['Talker.java', 'Listener.java']:
00083             filename = os.path.join(java_package_path, template_name)
00084             template = utils.read_template_file(template_directory, template_name)
00085             contents = instantiate_code_template(template, package_name, project_name, author)
00086             try:
00087                 f = open(filename, 'w')
00088                 f.write(contents)
00089                 console.pretty_print('  File      : ', console.cyan)
00090                 console.pretty_println(template_name, console.yellow)
00091             finally:
00092                 f.close()
00093     except Exception:
00094         raise
00095 
00096 
00097 def add_to_root_gradle_settings(name):
00098     '''
00099       Adds project name to the root level settings.gradle file.
00100     '''
00101     for rel_path in ['.', '..']:
00102         settings_gradle_path = os.path.join(os.getcwd(), rel_path, 'settings.gradle')
00103         if os.path.isfile(settings_gradle_path):
00104             break
00105         else:
00106             settings_gradle_path = None
00107     if settings_gradle_path is None:
00108         console.pretty_println("\nCouldn't find the root level settings.gradle file - not adding to the superproject.")
00109         return
00110     with open(settings_gradle_path, 'a') as settings_gradle:
00111         console.pretty_print('  File      : ', console.cyan)
00112         console.pretty_println('settings.gradle', console.yellow)
00113         settings_gradle.write("include '%s'\n" % name)
00114 
00115 
00116 def add_catkin_generate_tree_command():
00117     for rel_path in ['.', '..']:
00118         build_gradle_path = os.path.join(os.getcwd(), rel_path, 'build.gradle')
00119         if os.path.isfile(build_gradle_path):
00120             break
00121         else:
00122             build_gradle_path = None
00123     if build_gradle_path is None:
00124         console.pretty_println("\nCouldn't find the root level build.gradle file - not adding to the superproject.")
00125         return
00126     with open(build_gradle_path, 'r') as build_gradle:
00127         console.pretty_print('  File      : ', console.cyan)
00128         console.pretty_println('build.gradle (catkin_generate_tree update)', console.yellow)
00129         new_contents = build_gradle.read().replace("apply plugin: 'catkin'", "apply plugin: 'catkin'\nproject.catkin.tree.generate()\n")
00130     with open(build_gradle_path, 'w') as build_gradle:
00131         build_gradle.write(new_contents)
00132 
00133 
00134 def add_to_package_xml(name):
00135     '''
00136       Adds project name to build_depends in package.xml (should be same name as the ros msg package name).
00137     '''
00138     for rel_path in ['.', '..']:
00139         package_xml_path = os.path.join(os.getcwd(), rel_path, 'package.xml')
00140         if os.path.isfile(package_xml_path):
00141             break
00142         else:
00143             package_xml_path = None
00144     if package_xml_path is None:
00145         console.pretty_println("\nCouldn't find the root level package.xml file - not adding to the superproject.")
00146         return
00147     with open(package_xml_path, 'r') as package_xml:
00148         console.pretty_print('  File      : ', console.cyan)
00149         console.pretty_println('package.xml (dependency update)', console.yellow)
00150         new_contents = package_xml.read().replace("</package>", "<build_depend>%s</build_depend>\n</package>" % name)
00151     with open(package_xml_path, 'w') as package_xml:
00152         package_xml.write(new_contents)
00153 
00154 
00155 def add_tasks_to_cmake_setup(tasks):
00156     '''
00157       Adds project name to build_depends in package.xml (should be same name as the ros msg package name).
00158     '''
00159     for rel_path in ['.', '..']:
00160         cmakelists_txt_path = os.path.join(os.getcwd(), rel_path, 'CMakeLists.txt')
00161         if os.path.isfile(cmakelists_txt_path):
00162             break
00163         else:
00164             cmakelists_txt_path = None
00165     if cmakelists_txt_path is None:
00166         console.pretty_println("\nCouldn't find the root level CMakeLists.txt - not adding to the superproject.")
00167         return
00168     with open(cmakelists_txt_path, 'r') as cmakelists_txt:
00169         old_contents = cmakelists_txt.read()
00170         result = re.search('^catkin_rosjava_setup\(.*\)', old_contents, re.MULTILINE)
00171         if result is None:
00172             console.pretty_println("\nCouldn't find a catkin_rosjava_setup entry in the CMakeLists.txt - not adding tasks.")
00173             return
00174         rosjava_setup_string = result.group(0)
00175         gradle_tasks = set([])
00176         if rosjava_setup_string.find("publishMavenJavaPublicationToMavenRepository") != -1:
00177             gradle_tasks.add("publishMavenJavaPublicationToMavenRepository")
00178         if rosjava_setup_string.find("installApp") != -1:
00179             gradle_tasks.add("installApp")
00180         gradle_tasks |= set(tasks)
00181         console.pretty_print('  File      : ', console.cyan)
00182         console.pretty_println('CMakeLists.txt (gradle task update)', console.yellow)
00183         old_text = rosjava_setup_string
00184         new_text = 'catkin_rosjava_setup(' + ' '.join(gradle_tasks) + ')'
00185         new_contents = old_contents.replace(old_text, new_text)
00186     with open(cmakelists_txt_path, 'w') as cmakelists_txt:
00187         cmakelists_txt.write(new_contents)
00188 
00189 
00190 def create_dummy_java_class(project_name):
00191     path = os.path.join(os.getcwd(), project_name.lower())
00192     package_name = os.path.basename(os.getcwd())
00193     java_package_path = os.path.join(path, 'src', 'main', 'java', 'com', 'github', package_name, project_name)
00194     utils.mkdir_p(java_package_path)
00195     filename = os.path.join(java_package_path, 'Dude.java')
00196     java_class = "package com.github.%s.%s;\n" % (package_name, project_name)
00197     java_class += "\n"
00198     java_class += "public class Dude {\n"
00199     java_class += "}\n"
00200     console.pretty_print('  File      : ', console.cyan)
00201     console.pretty_println('Dude.class', console.yellow)
00202     with open(filename, 'w') as dude_class:
00203         dude_class.write(java_class)
00204 
00205 
00206 def ros_package_name():
00207     for rel_path in ['.', '..']:
00208         package_xml_path = os.path.join(os.getcwd(), rel_path, 'package.xml')
00209         if os.path.isfile(package_xml_path):
00210             break
00211         else:
00212             package_xml_path = None
00213     if package_xml_path is None:
00214         console.pretty_println("\nCouldn't find the root level package.xml file - not adding to the superproject.")
00215         return
00216     tree = ElementTree.parse(package_xml_path)
00217     root = tree.getroot()
00218     name = root.find('name').text
00219     return name
00220 
00221 
00222 def create_rosjava_project_common(args, template_directory):
00223     project_name = args.name[0]
00224     console.pretty_println("\nCreating rosjava project ", console.bold)
00225     console.pretty_print("  Name      : ", console.cyan)
00226     console.pretty_println("%s" % project_name, console.yellow)
00227     utils.mkdir_p(os.path.join(os.getcwd(), project_name.lower()))
00228     # This is in the old form, let's shovel the shit around to the new form
00229     create_gradle_package_files(args, template_directory)
00230     add_to_root_gradle_settings(args.name[0])
00231 
00232 
00233 def create_rosjava_project():
00234     args = parse_arguments()
00235     project_name = args.name[0]
00236     author = args.author
00237     create_rosjava_project_common(args, 'rosjava_project')
00238     create_talker_listener_classes(project_name, 'rosjava_project', author)
00239     add_tasks_to_cmake_setup(['installApp', 'publishMavenJavaPublicationToMavenRepository'])
00240 
00241 
00242 def create_rosjava_library_project():
00243     args = parse_arguments()
00244     project_name = args.name[0]
00245     create_rosjava_project_common(args, 'rosjava_library_project')
00246     create_dummy_java_class(project_name)
00247     add_tasks_to_cmake_setup(['publishMavenJavaPublicationToMavenRepository'])
00248 
00249 
00250 def create_rosjava_msg_project():
00251     args = parse_arguments()
00252     project_name = args.name[0]
00253     create_rosjava_project_common(args, 'rosjava_msg_project')
00254     add_catkin_generate_tree_command()
00255     add_to_package_xml(project_name)
00256     add_tasks_to_cmake_setup(['publishMavenJavaPublicationToMavenRepository'])


rosjava_build_tools
Author(s): Daniel Stonier
autogenerated on Wed Sep 2 2015 11:34:26