makerule.py
Go to the documentation of this file.
00001 #!/usr/bin/env python
00002 # Software License Agreement (BSD License)
00003 #
00004 # Copyright (c) 2009, Willow Garage, Inc.
00005 # All rights reserved.
00006 #
00007 # Redistribution and use in source and binary forms, with or without
00008 # modification, are permitted provided that the following conditions
00009 # are met:
00010 #
00011 #  * Redistributions of source code must retain the above copyright
00012 #    notice, this list of conditions and the following disclaimer.
00013 #  * Redistributions in binary form must reproduce the above
00014 #    copyright notice, this list of conditions and the following
00015 #    disclaimer in the documentation and/or other materials provided
00016 #    with the distribution.
00017 #  * Neither the name of Willow Garage, Inc. nor the names of its
00018 #    contributors may be used to endorse or promote products derived
00019 #    from this software without specific prior written permission.
00020 #
00021 # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 # FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 # BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 # CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 # ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 # POSSIBILITY OF SUCH DAMAGE.
00033 
00034 from __future__ import print_function
00035 
00036 import optparse
00037 import os
00038 import re
00039 import sys
00040 import rosbag.migration
00041 
00042 import genpy.message
00043 import genpy.dynamic
00044 
00045 def print_trans(old, new, indent):
00046     from_txt = '%s [%s]' % (old._type, old._md5sum)
00047     if new is not None:
00048         to_txt= '%s [%s]' % (new._type, new._md5sum)
00049     else:
00050         to_txt = 'Unknown'
00051     print('    ' * indent + ' * From: %s' % from_txt)
00052     print('    ' * indent + '   To:   %s' % to_txt)
00053 
00054 if __name__ == '__main__':
00055     parser = optparse.OptionParser(usage='usage: makerule.py msg.saved [-a] output_rulefile [rulefile1, rulefile2, ...] [-n]')
00056     parser.add_option('-a', '--append',    action='store_true', dest='append',    default=False)
00057     parser.add_option('-n', '--noplugins', action='store_true', dest='noplugins', default=False)
00058     (options, args) = parser.parse_args()
00059 
00060     if len(args) < 2:
00061         parser.error("Incorrect number of arguments")
00062 
00063     rulefile = args[1]
00064 
00065     if os.path.isfile(rulefile) and not options.append:
00066         print("The file %s already exists.  Include -a if you intend to append." % rulefile, file=sys.stderr)
00067         exit(1)
00068 
00069     if not os.path.isfile(rulefile) and options.append:
00070         print("The file %s does not exist, and so -a is invalid." % rulefile, file=sys.stderr)
00071         exit(1)
00072 
00073     if options.append:
00074         append_rule = [rulefile]
00075     else:
00076         append_rule = []
00077 
00078     f = open(args[0])
00079     if f is None:
00080         print('Could not open message full definition: %s', file=sys.stderr)
00081         sys.exit()
00082 
00083     type_line = f.readline()
00084     pat = re.compile(r"\[(.*)]:")
00085     type_match = pat.match(type_line)
00086     if type_match is None:
00087         print("Full definition file malformed.  First line should be: '[my_package/my_msg]:'", file=sys.stderr)
00088         sys.exit()
00089 
00090     old_type = type_match.groups()[0]
00091     old_full_text = f.read()
00092     f.close()
00093 
00094     old_class = genpy.dynamic.generate_dynamic(old_type,old_full_text)[old_type]
00095 
00096     if old_class is None:
00097         print('Could not generate class from full definition file.', file=sys.stderr)
00098         sys.exit()
00099 
00100     mm = rosbag.migration.MessageMigrator(args[2:]+append_rule,not options.noplugins)
00101 
00102     migrations = rosbag.migration.checkmessages(mm, [old_class])
00103 
00104     if migrations == []:
00105         print('Saved definition is up to date.')
00106         exit(0)
00107 
00108     print('The following migrations need to occur:')
00109 
00110     all_rules = []
00111     for m in migrations:
00112         all_rules.extend(m[1])
00113 
00114         print_trans(m[0][0].old_class, m[0][-1].new_class, 0)
00115         if len(m[1]) > 0:
00116             print("    %d rules missing:" % len(m[1]))
00117             for r in m[1]:
00118                 print_trans(r.old_class, r.new_class, 1)
00119 
00120     if rulefile is None:
00121         print("rulefile not specified")
00122     else:
00123         output = ''
00124         rules_left = mm.filter_rules_unique(all_rules)
00125 
00126         if rules_left == []:
00127             print("\nNo additional rule files needed to be generated.  %s not created." % rulefile)
00128             exit(0)
00129 
00130         while rules_left != []:
00131             extra_rules = []
00132 
00133             for r in rules_left:
00134                 if r.new_class is None:
00135                     print("The message type %s appears to have moved.  Please enter the type to migrate it to." % r.old_class._type)
00136                     new_type = raw_input('>')
00137                     new_class = genpy.message.get_message_class(new_type)
00138                     while new_class is None:
00139                         print("\'%s\' could not be found in your system.  Please make sure it is built." % new_type)
00140                         new_type = raw_input('>')
00141                         new_class = genpy.message.get_message_class(new_type)
00142                     new_rule = mm.make_update_rule(r.old_class, new_class)
00143                     R = new_rule(mm, 'GENERATED.' + new_rule.__name__)
00144                     R.find_sub_paths()
00145                     new_rules = [r for r in mm.expand_rules(R.sub_rules) if r.valid == False]
00146                     extra_rules.extend(new_rules)
00147                     print('Creating the migration rule for %s requires additional missing rules:' % new_type)
00148                     for nr in new_rules:
00149                         print_trans(nr.old_class, nr.new_class,1)
00150                     output += R.get_class_def()
00151                 else:
00152                     output += r.get_class_def()
00153             rules_left = mm.filter_rules_unique(extra_rules)
00154         f = open(rulefile, 'a')
00155         f.write(output)
00156         f.close()
00157         print("\nThe necessary rule files have been written to: %s" % rulefile)


rosbag
Author(s): Tim Field, Jeremy Leibs, James Bowman
autogenerated on Fri Aug 28 2015 12:33:52