Making makerule.py mirror user interaction of checkbag.py
This commit is contained in:
parent
6b406d5f47
commit
f710e17df5
|
@ -38,12 +38,49 @@ import roslib; roslib.load_manifest(PKG)
|
|||
|
||||
import sys
|
||||
import rosbagmigration
|
||||
|
||||
from optparse import OptionParser
|
||||
|
||||
import os
|
||||
|
||||
import re
|
||||
|
||||
import roslib.message
|
||||
def print_trans(old,new,indent):
|
||||
from_txt = "%s [%s]"%(old._type, old._md5sum)
|
||||
if new is not None:
|
||||
to_txt= "%s [%s]"%(new._type, new._md5sum)
|
||||
else:
|
||||
to_txt = "Unknown"
|
||||
print " "*indent + " * From: %s"%(from_txt,)
|
||||
print " "*indent + " To: %s"%(to_txt,)
|
||||
|
||||
if __name__ == '__main__':
|
||||
if len(sys.argv) >= 3:
|
||||
|
||||
parser = OptionParser(usage="usage: makerule.py msg.saved [-a] output_rulefile [rulefile1, rulefile2, ...] [-n]")
|
||||
parser.add_option("-a","--append",action="store_true",dest="append",default=False)
|
||||
parser.add_option("-n","--noplugins",action="store_true",dest="noplugins",default=False)
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
all_rules = []
|
||||
|
||||
if len(args) >= 2:
|
||||
|
||||
rulefile = args[1]
|
||||
|
||||
if os.path.isfile(rulefile) and not options.append:
|
||||
print >> sys.stderr, "The file %s already exists. Include -a if you intend to append."%rulefile
|
||||
exit(1)
|
||||
|
||||
if not os.path.isfile(rulefile) and options.append:
|
||||
print >> sys.stderr, "The file %s does not exist, and so -a is invalid."%rulefile
|
||||
exit(1)
|
||||
|
||||
if options.append:
|
||||
append_rule = [rulefile]
|
||||
else:
|
||||
append_rule = []
|
||||
|
||||
|
||||
f = open(sys.argv[1])
|
||||
|
||||
if f is None:
|
||||
|
@ -59,6 +96,7 @@ if __name__ == '__main__':
|
|||
|
||||
old_type = type_match.groups()[0]
|
||||
old_full_text = f.read()
|
||||
f.close()
|
||||
|
||||
old_class = roslib.genpy.generate_dynamic(old_type,old_full_text)[old_type]
|
||||
|
||||
|
@ -66,28 +104,63 @@ if __name__ == '__main__':
|
|||
print >> sys.stderr, "Could not generate class from full definition file."
|
||||
sys.exit()
|
||||
|
||||
new_class = roslib.message.get_message_class(sys.argv[2])
|
||||
mm = rosbagmigration.MessageMigrator(args[2:]+append_rule,not options.noplugins)
|
||||
|
||||
if new_class is None:
|
||||
print >> sys.stderr, "Could not find class corresponding to %s"%sys.argv[2]
|
||||
sys.exit()
|
||||
migrations = rosbagmigration.checkmessages(mm, [old_class])
|
||||
|
||||
# If the type and md5sum match, there is nothing necessary to do
|
||||
if ((old_class._type, old_class._md5sum) == (new_class._type, new_class._md5sum)):
|
||||
print >> sys.stderr, "Types already match, nothing to do."
|
||||
sys.exit()
|
||||
|
||||
mm = rosbagmigration.MessageMigrator(sys.argv[3:])
|
||||
if migrations == []:
|
||||
print "Saved definition is up to date"
|
||||
exit(0)
|
||||
else:
|
||||
print "The following migrations need to occur:"
|
||||
for m in migrations:
|
||||
all_rules.extend(m[1])
|
||||
|
||||
new_rule = mm.make_update_rule(old_class, new_class)
|
||||
R = new_rule(mm, "GENERATED")
|
||||
R.find_sub_paths()
|
||||
print_trans(m[0][0].old_class, m[0][-1].new_class, 0)
|
||||
if len(m[1]) > 0:
|
||||
print " %d rules missing:"%(len(m[1]))
|
||||
for r in m[1]:
|
||||
print_trans(r.old_class, r.new_class,1)
|
||||
|
||||
# Print rule definition and all additionally necessery definitions
|
||||
R.print_def()
|
||||
[r.print_def() for r in mm.get_invalid_rules()]
|
||||
if rulefile is not None:
|
||||
|
||||
|
||||
output = ""
|
||||
rules_left = mm.filter_rules_unique(all_rules)
|
||||
|
||||
if rules_left == []:
|
||||
print "\nNo additional rule files needed to be generated. %s not created."%(rulefile)
|
||||
exit(0)
|
||||
|
||||
while rules_left != []:
|
||||
extra_rules = []
|
||||
|
||||
for r in rules_left:
|
||||
if r.new_class is None:
|
||||
print "The message type %s appears to have moved. Please enter the type to migrate it to."%(r.old_class._type,)
|
||||
new_type = raw_input('>')
|
||||
new_class = roslib.scriptutil.get_message_class(new_type)
|
||||
while new_class is None:
|
||||
print "\'%s\' could not be found in your system. Please make sure it is built."%new_type
|
||||
new_type = raw_input('>')
|
||||
new_class = roslib.scriptutil.get_message_class(new_type)
|
||||
new_rule = mm.make_update_rule(r.old_class, new_class)
|
||||
R = new_rule(mm, 'GENERATED.' + new_rule.__name__)
|
||||
R.find_sub_paths()
|
||||
new_rules = [r for r in mm.expand_rules(R.sub_rules) if r.valid == False]
|
||||
extra_rules.extend(new_rules)
|
||||
print 'Creating the migration rule for %s requires additional missing rules:'%new_type
|
||||
for nr in new_rules:
|
||||
print_trans(nr.old_class, nr.new_class,1)
|
||||
output += R.get_class_def()
|
||||
else:
|
||||
output += r.get_class_def()
|
||||
rules_left = mm.filter_rules_unique(extra_rules)
|
||||
f = open(rulefile, 'a')
|
||||
f.write(output)
|
||||
f.close()
|
||||
print "\nThe necessary rule files have been written to: %s"%(rulefile,)
|
||||
else:
|
||||
print "rulefile not specified"
|
||||
else:
|
||||
print "usage: makerule.py <msg_full_text> <new_msg_name> [rulefile1, rulefile2, ...]"
|
||||
parser.error("Incorrect number of arguments")
|
||||
|
||||
|
|
|
@ -84,6 +84,33 @@ def checkbag(migrator, inbag):
|
|||
|
||||
return migrations
|
||||
|
||||
## Check whether a bag file can be played in the current system
|
||||
#
|
||||
# @param migrator The message migrator to use
|
||||
# @param message_list A list of message classes.
|
||||
# @returns A list of tuples for each type in the bag file. The first
|
||||
# element of each tuple is the full migration path for the type. The
|
||||
# second element of the tuple is the expanded list of invalid rules
|
||||
# for that particular path.
|
||||
def checkmessages(migrator, messages):
|
||||
checked = Set()
|
||||
migrations = []
|
||||
|
||||
for msg in messages:
|
||||
key = get_message_key(msg)
|
||||
if key not in checked:
|
||||
target = migrator.find_target(msg)
|
||||
# Even in the case of a zero-length path (matching md5sums), we still want
|
||||
# to migrate in the event of a type change (message move).
|
||||
path = migrator.find_path(msg, target)
|
||||
|
||||
if (path != []):
|
||||
migrations.append((path, [r for r in migrator.expand_rules([sn.rule for sn in path]) if r.valid == False]))
|
||||
|
||||
checked.add(key)
|
||||
|
||||
return migrations
|
||||
|
||||
## Fix a bag so that it can be played in the current system
|
||||
#
|
||||
# @param migrator The message migrator to use
|
||||
|
|
Loading…
Reference in New Issue