text: #!/bin/bash
  
  # Function that builds a message generation:
  # Note that we need to clean before in order to remove renamed messages.
  build_generation()
  {
      # This hack is needed because `catkin_make_isolated` does NOT provide any option to clean the package;
      # either way, even with `catkin_make clean`, it does NOT remove the package directory if .pyc files are inside it:
      for dir in $(tr ':' '\n' <<< "$PYTHONPATH")
      do
          cd "$dir"
          rm -rf test_rosbag
          cd "$OLDPWD"
      done
  
      catkin_make_isolated -q --pkg test_rosbag --cmake-args -DMSG_DIRECTORY="msg_$1" >/dev/null
  }
  
  # Function that saves the full text definition of a message:
  save_msg()
  {
      msg_type=${1/msg_*\//}
      msg_type=test_rosbag/${msg_type/.msg}
  
      saved_msg=${1/.msg/.saved}
  
      if [ ! -f "$saved_msg" ]
      then
          rosrun rosbag savemsg.py "$msg_type" > "$saved_msg"
  
          if [ $? -eq 0 ]
          then
              echo "Saved message $msg_type: $saved_msg"
          else
              echo "Failed to save message $msg_type!"
          fi
      else
          echo "Message $msg_type already saved in $saved_msg"
      fi
  }
  
  # Function that saves a message generation full definition (needed to create migration rules):
  save_generation()
  {
      msgs=$(find "msg_$1" -name "*.msg")
  
      for msg in $msgs
      do
          save_msg "$msg"
      done
  }
  
  # Function that creates migration rules from a previous message generation to the current one:
  make_rules()
  {
      saved_msgs=$(find "msg_$1" -name "*.saved")
  
      for saved_msg in $saved_msgs
      do
          rules=$(find msg_* test -name "*.bmr" -print0 | xargs -0)
          rule_file=${saved_msg/.saved/.bmr}
  
          if [ ! -f "$rule_file" ]
          then
              # Note that we can't redirect the output to >/dev/null because for renamed/moved messages we need to
              # provide the new message name.
              rosrun rosbag makerule.py "$saved_msg" "$rule_file" $rules
  
              if [ -f "$rule_file" ]
              then
                  echo "Created rule for $saved_msg: $rule_file"
                  echo "Set valid = True, the order and implement the update method, or remove it if you don't want it."
                  echo "Then press ENTER."
                  read
              else
                  echo "No rule needed for $saved_msg!"
              fi
          else
              echo "Rule for $saved_msg already exists: $rule_file"
          fi
      done
  }
  
  # Take positional arguments that specifies the source and target message generations to create migration rules for:
  if [ $# -eq 2 ]
  then
      GENERATION_SOURCE=$1
      GENERATION_TARGET=$2
  else
      echo "Usage  : $0 <source generation> <target generation>"
      echo "Example: $0 gen4 current"
      exit 1
  fi
  
  # Find the bag_migration_tests folder inside the test_rosbag package, since the .msg files are in the sub-folders
  # there:
  DESTINATION=$(rospack find test_rosbag)/bag_migration_tests
  
  # Build messages for the source generation:
  echo "Building generation: ${GENERATION_SOURCE}"
  build_generation "${GENERATION_SOURCE}"
  
  if [ $? -ne 0 ]
  then
      >&2 echo "Failed to build messages for the source generation ${GENERATION_SOURCE}!"
      exit 1
  fi
  
  echo
  
  # Save generation messages full text (needed to create migration rules):
  echo "Saving messages full text for generation: ${GENERATION_SOURCE}"
  cd "$DESTINATION"
  save_generation "${GENERATION_SOURCE}"
  cd "$OLDPWD"
  
  if [ $? -ne 0 ]
  then
      >&2 echo "Failed to save messages full text for the source generation ${GENERATION_SOURCE}!"
      exit 1
  fi
  
  echo
  
  # Build messages for the target generation:
  echo "Building generation: ${GENERATION_TARGET}"
  build_generation "${GENERATION_TARGET}"
  
  if [ $? -ne 0 ]
  then
      >&2 echo "Failed to build messages for the target generation ${GENERATION_TARGET}!"
      exit 1
  fi
  
  echo
  
  # Generate rules wrt to the source generation:
  echo "Making rules from source generation '${GENERATION_SOURCE}' to target generation '${GENERATION_TARGET}'"
  cd "$DESTINATION"
  make_rules "${GENERATION_SOURCE}"
  cd "$OLDPWD"
  
  if [ $? -ne 0 ]
  then
      >&2 echo "Failed to generate rules!"
      exit 1
  fi
  
  echo "* Remember that migration rules for renamed messages needs to be created manually!"
  echo "* Also remember that the migration rules in the files generated by this script might belong to other messages,"
  echo "  other than the one on the file name, so you should organize them properly!"
  
  # We don't really need to change the directory back to the old one, it's done automatically on exit:
  # cd $OLDPWD
  