Added logic so that prox removals will be sensitive to feature object data.  (eg, don't fire removal if never fired addition because didn't get feature data in time, etc.)

(function()
 {
     //map
     //keys: sporef of presence
     //values: map of actual visible objects
     var pResultSet = {};

     /**
      These get placed into the awaitingFeatureData and
      haveFeatureDataFor map
      @param {visible} vis - The visible that we request features for.
      @param {presence} featGrabber - The presence that we're using to
      request features and listen for feature updates.
      @param {presence} subscriber (optional) - A presence
      that wants to receive updates on vis.
      */
     function SubscriptionElement (vis,featGrabber,subscriber)
     {
         this.vis = vis;
         this.featGrabber =featGrabber;
         this.subscribers = {};
         if (typeof(subscriber) != 'undefined')
             this.subscribers[subscriber.toString()] = subscriber;
     }

     SubscriptionElement.prototype.addSubscriber =
         function(presToAdd)
     {
         this.subscribers[presToAdd.toString()] = presToAdd;
     };

     //returns true if there are no subscribers left.
     SubscriptionElement.prototype.noSubscribers =
         function()
     {
         for (var s in this.subscribers)
             return false;

         return true;
     };

     SubscriptionElement.prototype.removeSubscriber =
         function(presToRemove)
     {
         if (!(presToRemove.toString() in this.subscribers))
             delete this.subscribers[presToRemove.toString()];
     };

     //map
     //keys: sporef of visible awaiting data on
     //value: SubscriptionElement
     var awaitingFeatureData = {};

     //map
     //keys: sporef of visibles
     //keys: SubscriptionElement
     var haveFeatureDataFor  = {};

     //map
     //keys: sporef of presence
     //values: array of proximity added functions.  note, some
     //elements may be null if the proximity added function was
     //deregistered.
     var pAddCB = {};

     //map
     //keys: sporef of presence
     //values: array of proximity removed functions.  note, some
     //elements may be null if the proximity removed function was
     //deregistered.
     var pRemCB = {};

     //map
     //keys: sporef of presence
     //values: presences themselves.
     var sporefToPresences = {};

     system.onPresenceConnected(
         function(newPres)
         {
             sporefToPresences[newPres.toString()] = newPres;
             pResultSet[newPres.toString()]        = {};
             pAddCB[newPres.toString()]            = [];
             pRemCB[newPres.toString()]            = [];
         });

     //Does not hold internal data.  Instead, has private-like
     //variables defined above.
     function ProxManager()
     {
     }

     ProxManager.prototype.getProxResultSet = function(pres)
     {
         if (!(pres.toString() in pResultSet))
             throw new Error('Error getting prox result set.  ' +
                             'No record of presence.');

         return pResultSet[pres.toString()];
     };

     ProxManager.prototype.setProxAddCB = function(pres,proxAddCB)
     {
         if (!(pres.toString() in pAddCB))
         {
             throw new Error('Cannot add prox callback because do ' +
                             'Not have associated presence in ProxManager.');
         }

         var pArray = pAddCB[pres.toString()];

	 for (var i = 0; i <= pArray.length; i++)
	 {
	     if ((typeof(pArray[i]) == 'undefined') || (pArray[i] == null))
	     {
		 pArray[i] = proxAddCB;
		 return i;
	     }
	 }
         //shouldn't ever get here (notice the <= on exit condition of
         //for loop).  Just added so that syntax
         //highlighting of emacs doesn't keep bothering me.
         return null;
     };

     ProxManager.prototype.setProxRemCB = function (pres,proxRemCB)
     {
         if (!(pres.toString() in pRemCB))
         {
             throw new Error('Cannot add prox rem callback because do ' +
                             'not have associated presence in ProxManager.');
         }

         var pArray = pRemCB[pres.toString()];

	 for (var i = 0; i <= pArray.length; i++)
	 {
	     if ((typeof(pArray[i]) == 'undefined') || (pArray[i] == null))
	     {
		 pArray[i] = proxRemCB;
		 return i;
	     }
	 }
         //shouldn't ever get here (notice the <= on exit condition of
         //for loop).  Just added so that syntax
         //highlighting of emacs doesn't keep bothering me.
         return null;
     };

     ProxManager.prototype.delProxAddCB = function(pres,addID)
     {
         if (!(pres.toString() in pAddCB))
         {
             throw new Error('Cannot del prox add callback because do ' +
                             'not have associated presence in ProxManager.');
         }

         var pArray = pAddCB[pres.toString()];

         if (!(typeof(pArray[addID]) == 'undefined'))
             pArray[addID] = null;
     };

     ProxManager.prototype.delProxRemCB = function(pres,remID)
     {
         if (!(pres.toString() in pRemCB))
         {
             throw new Error('Cannot del prox rem callback because do ' +
                             'not have associated presence in ProxManager.');
         }

         var pArray = pRemCB[pres.toString()];

         if (!(typeof(pArray[addID]) == 'undefined'))
             pArray[addID] = null;
     };

     /**
      Gets called by system whenever visibleObj is within proximity
      range of pres.  Will trigger proxadded callbacks to be called
      if we already have the featureData for visibleObj.  Otherwise,
      queue visibleObj onto awaitingFeatureData.
      */
     ProxManager.prototype.proxAddedEvent = function (pres,visibleObj)
     {
         if (!(pres.toString() in pAddCB))
         {
             throw new Error('Cannot call add event callback because do ' +
                             'not have associated presence in ProxManager.');
         }

         if (visibleObj.toString() in haveFeatureDataFor)
         {
             //we already have feature data for this visible.  add pres
             //as subscriber to haveFeatureDataFor map and trigger callback.
             var subElement = haveFeatureDataFor[visibleObj.toString()];
             subElement.addSubscriber(pres);
             this.triggerAddCallback(pres,subElement.vis);
         }
         else
         {
             //we do not already have feature data for this visible.
             //Check if we're waiting on feature data for this object.
             //If we are, then, just add pres as a subscriber.  If we
             //are not, initiate feature object subscription using
             //pres as the requester.  If we are, waiting, then add
             //pres as a subscriber for this feature data.
             if (visibleObj.toString() in awaitingFeatureData)
             {
                 var subElement = awaitingFeatureData[visibleObj.toString()];
                 subElement.addSubscriber(pres);
             }
             else
             {
                 var subElement = new SubscriptionElement(visibleObj,pres,pres);
                 this.beginFeatureSubscribe(pres, visibleObj);
                 awaitingFeatureData[visibleObj.toString()] = subElement;
             }
         }
     };

     //tells pres to listen for feature vector from visibleObj
     ProxManager.prototype.beginFeatureSubscribe = function(pres,visibleObj)
     {
         system.__debugPrint('\nbeginFeatureSubscribe in proxManager ' +
                             'is just a dummy for now.  Fix soon.\n');
         //for now, simple sanity check.  After 1 second, release,
         //saying that featureData is 1.
         system.timeout(1,std.core.bind(this.subscribeComplete,this,pres,visibleObj,1));
     };

     ProxManager.prototype.killSubscription = function(pres,visibleObj)
     {
         system.__debugPrint('\nkillSubscription in proxManager ' +
                             'is just a dummy for now.  Fix soon.\n');
     };

     //should get called when a presence has received feature data
     //from visibleObj.
     ProxManager.prototype.subscribeComplete =
         function(pres,visibleObj,featureData)
     {
         visibleObj.featureData = featureData;
         if (!(visibleObj.toString() in awaitingFeatureData))
         {
             throw new Error('Error in subscribeComplete.  No longer '+
                             'have visibleObj in awaitingFeatureData.');
         }

         var subElement = awaitingFeatureData[visibleObj.toString()];
         delete awaitingFeatureData[visibleObj.toString()];

         if (subElement.noSubscribers())
         {
             //no one is waiting for/actually cares about the new
             //data.
             this.killSubscription(pres,visibleObj);
             return;
         }

         //know that we've received the data and that others want to
         //hear about it.  add subElement to haveFeatureDataFor map
         //and notify all subscribers that visibleObj (with
         //featureData) is in its prox result set and add visibleObj
         //to result set.
         haveFeatureDataFor[visibleObj.toString()] = subElement;
         for (var s in subElement.subscribers)
         {
             this.triggerAddCallback(subElement.subscribers[s],
                                     subElement.vis);
         }
     };

     //actually fire callback for pres's having seen visibleObj in-world
     //and add visibleObj to result set.
     ProxManager.prototype.triggerAddCallback = function(pres,visibleObj)
     {
         pResultSet[pres.toString()][visibleObj.toString()] = visibleObj;
         var pArray = pAddCB[pres.toString()];
         //trigger all non-null non-undefined callbacks
         system.changeSelf(pres);
	 for (var i in pArray)
         {
	     if ((typeof(pArray[i]) != 'undefined') && (pArray[i] != null))
		 pArray[i](visibleObj);
         }
     };

     //called by system when pinto actually states that visibleObj is
     //distant from pres.  If the visible exists in awaitingFeatureData
     //then we just remove a subscriber from it.  If the visible exists in
     //haveFeatureDataFor, then fire removed callback, decrement
     //subscribers.  If no subscribers left in haveFeatureDataFor, then
     //unsubscribe from feature data, and remove element from
     //haveFeatureDataFor.
     ProxManager.prototype.proxRemovedEvent = function (pres,visibleObj)
     {
         if (visibleObj.toString() in awaitingFeatureData)
             awaitingFeatureData[visibleObj.toString()].removeSubscriber(pres);
         else
         {
             //this line ensures that visibleObj will maintain
             //featureData associated with stored vis.
             visibleObj = haveFeatureDataFor[visibleObj.toString()].vis;
             var subElem = haveFeatureDataFor[visibleObj.toString()];
             subElem.removeSubscriber(pres);

             if (subElem.noSubscribers())
             {
                 this.killSubscription(pres,visibleObj);
                 delete haveFeatureDataFor[visibleObj.toString()];
             }

             //actually fire removed callback.
             this.triggerRemoveCallback(pres,visibleObj);
         }
     };

     ProxManager.prototype.triggerRemoveCallback = function(pres,visibleObj)
     {
         if (!(pres.toString() in pRemCB))
         {
             throw new Error('Cannot call rem event callback because do ' +
                             'not have associated presence in ProxManager.');
         }
         if (!(pres.toString() in pResultSet))
         {
             throw new Error('Cannot call rem event callback for presence ' +
                             'because no presence in pResultSet matches.');
         }

         //remove from to proxResultSet
         delete pResultSet[pres.toString()][visibleObj.toString()];

         //actually issue callbacks
         var pArray = pRemCB[pres.toString()];
         system.changeSelf(pres);
         //trigger all non-null non-undefined callbacks

	 for (var i in pArray)
         {
	     if ((typeof(pArray[i]) != 'undefined') && (pArray[i] != null))
		 pArray[i](visibleObj);
         }

     };

     //actually register an instance of proxmanager with system.
     system.__registerProxManager(new ProxManager());
 }
)();

////////////Now prox manager///////////

(function()
 {
     //map
     //keys: sporef of presence
     //values: map of actual visible objects
     var pResultSet = {};

     /**
      These get placed into the awaitingFeatureData and
      haveFeatureDataFor map
      @param {visible} vis - The visible that we request features for.
      @param {presence} featGrabber - The presence that we're using to
      request features and listen for feature updates.
      @param {presence} subscriber (optional) - A presence
      that wants to receive updates on vis.
      */
     function SubscriptionElement (vis,featGrabber,subscriber)
     {
         this.vis = vis;
         this.featGrabber =featGrabber;
         this.subscribers = {};
         if (typeof(subscriber) != 'undefined')
             this.subscribers[subscriber.toString()] = subscriber;
     }

     SubscriptionElement.prototype.addSubscriber =
         function(presToAdd)
     {
         this.subscribers[presToAdd.toString()] = presToAdd;
     };

     //returns true if there are no subscribers left.
     SubscriptionElement.prototype.noSubscribers =
         function()
     {
         for (var s in this.subscribers)
             return false;

         return true;
     };

     SubscriptionElement.prototype.removeSubscriber =
         function(presToRemove)
     {
         if (!(presToRemove.toString() in this.subscribers))
             delete this.subscribers[presToRemove.toString()];
     };

     //map
     //keys: sporef of visible awaiting data on
     //value: SubscriptionElement
     var awaitingFeatureData = {};

     //map
     //keys: sporef of visibles
     //keys: SubscriptionElement
     var haveFeatureDataFor  = {};

     //map
     //keys: sporef of presence
     //values: array of proximity added functions.  note, some
     //elements may be null if the proximity added function was
     //deregistered.
     var pAddCB = {};

     //map
     //keys: sporef of presence
     //values: array of proximity removed functions.  note, some
     //elements may be null if the proximity removed function was
     //deregistered.
     var pRemCB = {};

     //map
     //keys: sporef of presence
     //values: presences themselves.
     var sporefToPresences = {};

     system.onPresenceConnected(
         function(newPres)
         {
             sporefToPresences[newPres.toString()] = newPres;
             pResultSet[newPres.toString()]        = {};
             pAddCB[newPres.toString()]            = {};
             pRemCB[newPres.toString()]            = {};
         });

     //Does not hold internal data.  Instead, has private-like
     //variables defined above.
     function ProxManager()
     {
     }

     ProxManager.prototype.getProxResultSet = function(pres)
     {
         if (!(pres.toString() in pResultSet))
             throw new Error('Error getting prox result set.  ' +
                             'No record of presence.');

         return pResultSet[pres.toString()];
     };

     ProxManager.prototype.setProxAddCB = function(pres,proxAddCB)
     {
         if (!(pres.toString() in pAddCB))
         {
             throw new Error('Cannot add prox callback because do ' +
                             'Not have associated presence in ProxManager.');
         }

         var pArray = pAddCB[pres.toString()];

	 for (var i = 0; i <= pArray.length; i++)
	 {
	     if ((typeof(pArray[i]) == 'undefined') || (pArray[i] == null))
	     {
		 pArray[i] = proxAddCB;
		 return i;
	     }
	 }
         //shouldn't ever get here (notice the <= on exit condition of
         //for loop).  Just added so that syntax
         //highlighting of emacs doesn't keep bothering me.
         return null;
     };

     ProxManager.prototype.setProxRemCB = function (pres,proxRemCB)
     {
         if (!(pres.toString() in pRemCB))
         {
             throw new Error('Cannot add prox rem callback because do ' +
                             'not have associated presence in ProxManager.');
         }

         var pArray = pRemCB[pres.toString()];

	 for (var i = 0; i <= pArray.length; i++)
	 {
	     if ((typeof(pArray[i]) == 'undefined') || (pArray[i] == null))
	     {
		 pArray[i] = proxRemCB;
		 return i;
	     }
	 }
         //shouldn't ever get here (notice the <= on exit condition of
         //for loop).  Just added so that syntax
         //highlighting of emacs doesn't keep bothering me.
         return null;
     };

     ProxManager.prototype.delProxAddCB = function(pres,addID)
     {
         if (!(pres.toString() in pAddCB))
         {
             throw new Error('Cannot del prox add callback because do ' +
                             'not have associated presence in ProxManager.');
         }

         var pArray = pAddCB[pres.toString()];

         if (!(typeof(pArray[addID]) == 'undefined'))
             pArray[addID] = null;
     };

     ProxManager.prototype.delProxRemCB = function(pres,remID)
     {
         if (!(pres.toString() in pRemCB))
         {
             throw new Error('Cannot del prox rem callback because do ' +
                             'not have associated presence in ProxManager.');
         }

         var pArray = pRemCB[pres.toString()];

         if (!(typeof(pArray[addID]) == 'undefined'))
             pArray[addID] = null;
     };

     /**
      Gets called by system whenever visibleObj is within proximity
      range of pres.  Will trigger proxadded callbacks to be called
      if we already have the featureData for visibleObj.  Otherwise,
      queue visibleObj onto awaitingFeatureData.
      */
     ProxManager.prototype.proxAddedEvent = function (pres,visibleObj)
     {
         if (!(pres.toString() in pAddCB))
         {
             throw new Error('Cannot call add event callback because do ' +
                             'not have associated presence in ProxManager.');
         }

         if (visibleObj.toString() in haveFeatureDataFor)
         {
             //we already have feature data for this visible.  add pres
             //as subscriber to haveFeatureDataFor map and trigger callback.
             var subElement = haveFeatureDataFor[visibleObj.toString()];
             subElement.addSubscriber(pres);
             this.triggerAddCallback(pres,subElement.vis);
         }
         else
         {
             //we do not already have feature data for this visible.
             //Check if we're waiting on feature data for this object.
             //If we are, then, just add pres as a subscriber.  If we
             //are not, initiate feature object subscription using
             //pres as the requester.  If we are, waiting, then add
             //pres as a subscriber for this feature data.
             if (visibleObj.toString() in awaitingFeatureData)
             {
                 var subElement = awaitingFeatureData[visibleObj.toString()];
                 subElement.addSubscriber(pres);
             }
             else
             {
                 var subElement = new SubscriptionElement(visibleObj,pres,pres);
                 this.beginFeatureSubscribe(pres, visibleObj);
                 awaitingFeatureData[visibleObj.toString()] = subElement;
             }
         }
     };

     //tells pres to listen for feature vector from visibleObj
     ProxManager.prototype.beginFeatureSubscribe = function(pres,visibleObj)
     {
         //for now, simple sanity check.  After 1 second, release,
         //saying that featureData is 1.
         system.timeout(1,std.core.bind(this.subscribeComplete,this,pres,visibleObj,1));
     };

     //should get called when a presence has received feature data
     //from visibleObj.
     ProxManager.prototype.subscribeComplete =
         function(pres,visibleObj,featureData)
     {
         visibleObj.featureData = featureData;
         if (!(visibleObj.toString() in awaitingFeatureData))
         {
             throw new Error('Error in subscribeComplete.  No longer '+
                             'have visibleObj in awaitingFeatureData.');
         }

         var subElement = awaitingFeatureData[visibleObj.toString()];
         delete awaitingFeatureData[visibleObj.toString()];

         if (subElement.noSubscribers())
         {
             //no one is waiting for/actually cares about the new
             //data.
             this.killSubscription(pres,visibleObj);
             return;
         }

         //know that we've received the data and that others want to
         //hear about it.  add subElement to haveFeatureDataFor map
         //and notify all subscribers that visibleObj (with
         //featureData) is in its prox result set and add visibleObj
         //to result set.
         haveFeatureDataFor[visibleObj.toString()] = subElement;
         for (var s in subElement.subscribers)
         {
             this.triggerAddCallback(subElement.subscribers[s],
                                     subElement.vis);
         }
     };

     //actually fire callback for pres's having seen visibleObj in-world
     //and add visibleObj to result set.
     ProxManager.prototype.triggerAddCallback = function(pres,visibleObj)
     {
         pResultSet[pres.toString()][visibleObj.toString()] = visibleObj;
         var pArray = pAddCB[pres.toString()];
         //trigger all non-null non-undefined callbacks
         system.changeSelf(pres);
	 for (var i in pArray)
         {
	     if ((typeof(pArray[i]) != 'undefined') && (pArray[i] != null))
		 pArray[i](visibleObj);
         }
     };

     ProxManager.prototype.proxRemovedEvent = function (pres,visibleObj)
     {
         if (!(pres.toString() in pRemCB))
         {
             throw new Error('Cannot call rem event callback because do ' +
                             'not have associated presence in ProxManager.');
         }

         var pArray = pRemCB[pres.toString()];

         //remove from to proxResultSet
        delete pArray[visibleObj.toString()];
        system.changeSelf(pres);
        //trigger all non-null non-undefined callbacks
	for (var i in pArray)
	    if ((typeof(pArray[i]) != 'undefined') && (pArray[i] != null))
		pArray[i](visibleObj);
     };

     //actually register an instance of proxmanager with system.
     system.__registerProxManager(new ProxManager());
 }
)();


fix missing import (#437)

fix missing import (#437)

@{
# same logic as in from_base_image.Dockerfile.em
if arch in ['i386', 'armhf', 'arm64']:
    base_image = 'osrf/%s_%s:%s' % (os_name, arch, os_code_name)
else:
    base_image = '%s:%s' % (os_name, os_code_name)
}@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'echo "# BEGIN SECTION: Check docker status"',
        'echo "Testing trivial docker invocation..."',
        'docker run --rm %s true ; echo "\'docker run\' returned $?"' % base_image,
    ]),
))@
@(SNIPPET(
    'builder_system-groovy',
    command=
"""// DISABLE SLAVE IF OUTPUT INDICATES DOCKER RUN PROBLEMS
import hudson.model.Cause.UserIdCause
import hudson.model.ParametersAction
import hudson.slaves.OfflineCause.UserCause
import java.io.BufferedReader
import java.util.regex.Pattern
import org.jvnet.hudson.plugins.groovypostbuild.GroovyPostbuildAction

pattern = Pattern.compile("'docker run' returned [^0].*")

r = build.getLogReader()
br = new BufferedReader(r)
def line
while ((line = br.readLine()) != null) {
    matcher = pattern.matcher(line)
    if (matcher.matches()) {
        println "'docker run' failed"

        // mark slave as offline and log event
        def node = build.getBuiltOn()
        def computer = node.toComputer()
        computer.setTemporarilyOffline(true, new UserCause(null, "'docker run' failed"))

        // rescheduled a build with the same parameters
        // the requeue flag in the project configuration seems to not be sufficient anymore
        build.getProject().scheduleBuild(1, new UserIdCause(), *build.getActions(ParametersAction))

        // add badge to build
        build.getActions().add(GroovyPostbuildAction.createInfoBadge("'docker run' failed, disabled slave '" + computer.name + "', rescheduled job"))

        // abort this build
        throw new InterruptedException()
    }
}
println "docker seems operational, continuing"
""",
    script_file=None,
))@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'echo "# END SECTION"',
    ]),
))@

@{
# same logic as in from_base_image.Dockerfile.em
if arch in ['i386', 'armhf', 'arm64']:
    base_image = 'osrf/%s_%s:%s' % (os_name, arch, os_code_name)
else:
    base_image = '%s:%s' % (os_name, os_code_name)
}@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'echo "# BEGIN SECTION: Check docker status"',
        'echo "Testing trivial docker invocation..."',
        'docker run --rm %s true ; echo "\'docker run\' returned $?"' % base_image,
    ]),
))@
@(SNIPPET(
    'builder_system-groovy',
    command=
"""// DISABLE SLAVE IF OUTPUT INDICATES DOCKER RUN PROBLEMS
import hudson.model.ParametersAction
import hudson.slaves.OfflineCause.UserCause
import java.io.BufferedReader
import java.util.regex.Pattern
import org.jvnet.hudson.plugins.groovypostbuild.GroovyPostbuildAction

pattern = Pattern.compile("'docker run' returned [^0].*")

r = build.getLogReader()
br = new BufferedReader(r)
def line
while ((line = br.readLine()) != null) {
    matcher = pattern.matcher(line)
    if (matcher.matches()) {
        println "'docker run' failed"

        // mark slave as offline and log event
        def node = build.getBuiltOn()
        def computer = node.toComputer()
        computer.setTemporarilyOffline(true, new UserCause(null, "'docker run' failed"))

        // rescheduled a build with the same parameters
        // the requeue flag in the project configuration seems to not be sufficient anymore
        build.getProject().scheduleBuild(1, new UserIdCause(), *build.getActions(ParametersAction))

        // add badge to build
        build.getActions().add(GroovyPostbuildAction.createInfoBadge("'docker run' failed, disabled slave '" + computer.name + "', rescheduled job"))

        // abort this build
        throw new InterruptedException()
    }
}
println "docker seems operational, continuing"
""",
    script_file=None,
))@
@(SNIPPET(
    'builder_shell',
    script='\n'.join([
        'echo "# END SECTION"',
    ]),
))@


first herd commit fixing child asset inverse whoo

class Herd.Asset extends DS.Model
  createdAt: DS.attr 'date'
  fileName: DS.attr 'string'
  fileSize: DS.attr 'number'
  contentType: DS.attr 'string'
  type: DS.attr 'string'
  url: DS.attr 'string'
  position: DS.attr 'number'
  metadata: DS.attr 'raw'

  width: DS.attr 'number'
  height: DS.attr 'number'

  parentAsset: DS.belongsTo 'asset', { inverse: 'childAssets' }
  childAssets: DS.hasMany 'asset', { inverse: null }

  transform: DS.belongsTo 'transform'

  +computed metadata
  permalink: (key, permalinkString)->
    if arguments.length == 1
      @metadata.permalink
    else
      @metadata.permalink = permalinkString

  t: (trans) ->
    @childAssets.find (item, ix) ->
      item.transform == trans || item.transform?.options == trans

class Herd.AssetSerializer extends DS.ActiveModelSerializer with DS.EmbeddedRecordsMixin
  attrs:
    transform: {serialize: 'records'}

class Herd.Asset extends DS.Model
  createdAt: DS.attr 'date'
  fileName: DS.attr 'string'
  fileSize: DS.attr 'number'
  contentType: DS.attr 'string'
  type: DS.attr 'string'
  url: DS.attr 'string'
  position: DS.attr 'number'
  metadata: DS.attr 'raw'

  width: DS.attr 'number'
  height: DS.attr 'number'

  parentAsset: DS.belongsTo 'asset', { inverse: 'childAssets' }
  childAssets: DS.hasMany 'asset'

  transform: DS.belongsTo 'transform'

  +computed metadata
  permalink: (key, permalinkString)->
    if arguments.length == 1
      @metadata.permalink
    else
      @metadata.permalink = permalinkString

  t: (trans) ->
    @childAssets.find (item, ix) ->
      item.transform == trans || item.transform?.options == trans

class Herd.AssetSerializer extends DS.ActiveModelSerializer with DS.EmbeddedRecordsMixin
  attrs:
    transform: {serialize: 'records'}


Change build directory from package direcotry to devel go directory.

# vim: ft=cmake :
@[if DEVELSPACE]@
set(ROSGO_ROOT "${CATKIN_DEVEL_PREFIX}/go")
@[else]@
set(ROSGO_ROOT "${CMAKE_INSTALL_PREFIX}/go")
@[end if]@

file(MAKE_DIRECTORY ${ROSGO_ROOT})

if($ENV{GOPATH})
    set(ENV{GOPATH} ${ROSGO_ROOT}:$ENV{GOPATH})
else()
    set(ENV{GOPATH} ${ROSGO_ROOT})
endif()

set(ROSGO_SRC ${ROSGO_ROOT}/src)
set(ROSGO_BIN ${ROSGO_ROOT}/bin)
execute_process(COMMAND go env GOARCH OUTPUT_VARIABLE ROSGO_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND go env GOOS OUTPUT_VARIABLE ROSGO_OS OUTPUT_STRIP_TRAILING_WHITESPACE)
set(ROSGO_PKG ${ROSGO_ROOT}/pkg/${ROSGO_OS}_${ROSGO_ARCH})

file(MAKE_DIRECTORY ${ROSGO_SRC})
file(MAKE_DIRECTORY ${ROSGO_BIN})
file(MAKE_DIRECTORY ${ROSGO_PKG})

macro(rosgo_add_executable _package)
    #set(output ${ROSGO_BIN}/${_package})
    set(src_link ${CATKIN_DEVEL_PREFIX}/go/src/${_package})
    add_custom_target(
        ${_package} ALL
        COMMAND ${CMAKE_COMMAND} -E create_symlink ${PROJECT_SOURCE_DIR}/src/${_package} ${src_link}
        COMMAND env GOPATH=$ENV{GOPATH} go install ${_package}
    )
endmacro()

macro(rosgo_add_library _package)
    #set(output ${ROSGO_PKG}/${_package}.a)
    set(src_link ${CATKIN_DEVEL_PREFIX}/go/src/${_package})
    add_custom_target(
        ${_package} ALL
        COMMAND ${CMAKE_COMMAND} -E create_symlink ${PROJECT_SOURCE_DIR}/src/${_package} ${src_link}
        COMMAND env GOPATH=$ENV{GOPATH} go install ${_package}
    )
endmacro()

# At DEVELSPACE, this macro export PROJECT_SOURCE_DIR to GOPATH
macro(catkin_rosgo_setup)
    #    set(ENV{GOPATH} "${PROJECT_SOURCE_DIR}:$ENV{GOPATH}")
endmacro()

# vim: ft=cmake :
@[if DEVELSPACE]@
set(ROSGO_ROOT "${CATKIN_DEVEL_PREFIX}/go")
@[else]@
set(ROSGO_ROOT "${CMAKE_INSTALL_PREFIX}/go")
@[end if]@

file(MAKE_DIRECTORY ${ROSGO_ROOT})

if($ENV{GOPATH})
    set(ENV{GOPATH} ${ROSGO_ROOT}:$ENV{GOPATH})
else()
    set(ENV{GOPATH} ${ROSGO_ROOT})
endif()

set(ROSGO_SRC ${ROSGO_ROOT}/src)
set(ROSGO_BIN ${ROSGO_ROOT}/bin)
execute_process(COMMAND go env GOARCH OUTPUT_VARIABLE ROSGO_ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND go env GOOS OUTPUT_VARIABLE ROSGO_OS OUTPUT_STRIP_TRAILING_WHITESPACE)
set(ROSGO_PKG ${ROSGO_ROOT}/pkg/${ROSGO_OS}_${ROSGO_ARCH})

file(MAKE_DIRECTORY ${ROSGO_SRC})
file(MAKE_DIRECTORY ${ROSGO_BIN})
file(MAKE_DIRECTORY ${ROSGO_PKG})

macro(rosgo_add_executable _package)
    set(_output ${PROJECT_SOURCE_DIR}/bin/${_package})
    message(STATUS GOPATH=$ENV{GOPATH})
    add_custom_command(
        OUTPUT ${_output}
        COMMAND env GOPATH=$ENV{GOPATH} go install ${_package}
    )
    add_custom_target(${_package} ALL DEPENDS ${_output})
endmacro()

macro(rosgo_add_library _package)
    set(_output ${PROJECT_SOURCE_DIR}/pkg/${ROSGO_OS}_${ROSGO_ARCH}/${_package}.a)
    message(STATUS GOPATH=$ENV{GOPATH})
    add_custom_command(
        OUTPUT ${_output}
        COMMAND env GOPATH=$ENV{GOPATH} go install ${_package}
    )
    add_custom_target(${_package} ALL DEPENDS ${_output})
endmacro()

# At DEVELSPACE, this macro export PROJECT_SOURCE_DIR to GOPATH
macro(catkin_rosgo_setup)
    set(ENV{GOPATH} "${PROJECT_SOURCE_DIR}:$ENV{GOPATH}")
endmacro()


update list of EOL ubuntu distributions (#503)

@[if os_name == 'ubuntu' and os_code_name in ['saucy', 'utopic', 'vivid', 'wily', 'yakkety', 'zesty']]@
RUN find /etc/apt/ -name *.list -exec sed -i -e 's/archive.ubuntu.com\|security.ubuntu.com/old-releases.ubuntu.com/g' {} \;
@[end if]@

@[if os_name == 'ubuntu' and os_code_name in ['saucy', 'utopic']]@
RUN find /etc/apt/ -name *.list -exec sed -i -e 's/archive.ubuntu.com\|security.ubuntu.com/old-releases.ubuntu.com/g' {} \;
@[end if]@


fix escaping (#72)

fix escaping (#72)

<?xml version='1.0' encoding='UTF-8'?>
<project>
  <actions/>
  <description></description>
  <keepDependencies>false</keepDependencies>
  <properties>
    <com.coravy.hudson.plugins.github.GithubProjectProperty plugin="github@@1.25.1">
      <projectUrl>@(ci_scripts_repository)/</projectUrl>
      <displayName />
    </com.coravy.hudson.plugins.github.GithubProjectProperty>
    <com.sonyericsson.rebuild.RebuildSettings plugin="rebuild@@1.25">
      <autoRebuild>false</autoRebuild>
      <rebuildDisabled>false</rebuildDisabled>
    </com.sonyericsson.rebuild.RebuildSettings>
    <org.jenkinsci.plugins.requeuejob.RequeueJobProperty plugin="jobrequeue@@1.1">
      <requeueJob>true</requeueJob>
    </org.jenkinsci.plugins.requeuejob.RequeueJobProperty>
@(SNIPPET(
    'property_parameter-definition',
    ci_scripts_default_branch=ci_scripts_default_branch,
    default_repos_url=default_repos_url,
    supplemental_repos_url=supplemental_repos_url,
    use_connext_default=use_connext_default,
    disable_connext_static_default=disable_connext_static_default,
    disable_connext_dynamic_default=disable_connext_dynamic_default,
    use_osrf_connext_debs_default=use_osrf_connext_debs_default,
    use_fastrtps_default=use_fastrtps_default,
    use_opensplice_default=use_opensplice_default,
    cmake_build_type=cmake_build_type,
    ament_build_args_default=ament_build_args_default,
    ament_test_args_default=ament_test_args_default,
    enable_c_coverage_default=enable_c_coverage_default,
))@
  </properties>
  <scm class="hudson.plugins.git.GitSCM" plugin="git@@3.0.1">
    <configVersion>2</configVersion>
    <userRemoteConfigs>
      <hudson.plugins.git.UserRemoteConfig>
        <url>@(ci_scripts_repository)</url>
        <credentialsId>1c2004f6-2e00-425d-a421-2e1ba62ca7a7</credentialsId>
      </hudson.plugins.git.UserRemoteConfig>
    </userRemoteConfigs>
    <branches>
      <hudson.plugins.git.BranchSpec>
        <name>refs/heads/${CI_SCRIPTS_BRANCH}</name>
      </hudson.plugins.git.BranchSpec>
    </branches>
    <doGenerateSubmoduleConfigurations>false</doGenerateSubmoduleConfigurations>
    <browser class="hudson.plugins.git.browser.GithubWeb">
      <url></url>
    </browser>
    <submoduleCfg class="list"/>
    <extensions>@
@[if os_name != 'windows']
      <hudson.plugins.git.extensions.impl.SubmoduleOption>
        <disableSubmodules>false</disableSubmodules>
        <recursiveSubmodules>true</recursiveSubmodules>
        <trackingSubmodules>false</trackingSubmodules>
        <reference/>
        <parentCredentials>false</parentCredentials>
      </hudson.plugins.git.extensions.impl.SubmoduleOption>
    @
@[end if]</extensions>
  </scm>
  <assignedNode>@(label_expression)</assignedNode>
  <canRoam>false</canRoam>
  <disabled>false</disabled>
  <blockBuildWhenDownstreamBuilding>false</blockBuildWhenDownstreamBuilding>
  <blockBuildWhenUpstreamBuilding>false</blockBuildWhenUpstreamBuilding>
  <triggers>@
@[if time_trigger_spec]
    <hudson.triggers.TimerTrigger>
      <spec>@(time_trigger_spec)</spec>
    </hudson.triggers.TimerTrigger>
  @
@[end if]</triggers>
  <concurrentBuild>true</concurrentBuild>
  <builders>
    <hudson.plugins.groovy.SystemGroovy plugin="groovy@@2.0">
      <source class="hudson.plugins.groovy.StringSystemScriptSource">

          <sandbox>false</sandbox>
        </script>
      </source>
    </hudson.plugins.groovy.SystemGroovy>
    <hudson.tasks.@(shell_type)>
      <command>@
@[if os_name in ['linux', 'osx', 'linux-aarch64']]@
rm -rf ws workspace "work space"

echo "# BEGIN SECTION: Determine arguments"
export CI_ARGS="--do-venv --force-ansi-color --workspace-path $WORKSPACE"
if [ -n "${CI_BRANCH_TO_TEST+x}" ]; then
  export CI_ARGS="$CI_ARGS --test-branch $CI_BRANCH_TO_TEST"
fi
if [ "$CI_USE_WHITESPACE_IN_PATHS" = "true" ]; then
  export CI_ARGS="$CI_ARGS --white-space-in sourcespace buildspace installspace workspace"
fi
if [ "$CI_USE_CONNEXT" = "true" ]; then
  export CI_ARGS="$CI_ARGS --connext"
fi
if [ "$CI_DISABLE_CONNEXT_STATIC" = "true" ]; then
  export CI_ARGS="$CI_ARGS --disable-connext-static"
fi
if [ "$CI_DISABLE_CONNEXT_DYNAMIC" = "true" ]; then
  export CI_ARGS="$CI_ARGS --disable-connext-dynamic"
fi
if [ "$CI_USE_OSRF_CONNEXT_DEBS" = "true" ]; then
  export CI_ARGS="$CI_ARGS --osrf-connext-debs"
fi
if [ "$CI_USE_FASTRTPS" = "true" ]; then
  export CI_ARGS="$CI_ARGS --fastrtps"
fi
if [ "$CI_USE_OPENSPLICE" = "true" ]; then
  export CI_ARGS="$CI_ARGS --opensplice"
fi
if [ -z "${CI_ROS2_REPOS_URL+x}" ]; then
  CI_ROS2_REPOS_URL="@default_repos_url"
fi
export CI_ARGS="$CI_ARGS --repo-file-url $CI_ROS2_REPOS_URL"
if [ -n "${CI_ROS2_SUPPLEMENTAL_REPOS_URL+x}" ]; then
  export CI_ARGS="$CI_ARGS --supplemental-repo-file-url $CI_ROS2_SUPPLEMENTAL_REPOS_URL"
fi
if [ "$CI_ISOLATED" = "true" ]; then
  export CI_ARGS="$CI_ARGS --isolated"
fi
if [ "${CI_CMAKE_BUILD_TYPE}" != "None" ]; then
  export CI_ARGS="$CI_ARGS --cmake-build-type $CI_CMAKE_BUILD_TYPE"
fi
if [ "$CI_ENABLE_C_COVERAGE" = "true" ]; then
  export CI_ARGS="$CI_ARGS --coverage"
fi
if [ -n "${CI_AMENT_BUILD_ARGS+x}" ]; then
  case $CI_AMENT_BUILD_ARGS in
    *-- )
      # delimiter is already appended
      ;;
    * )
      CI_AMENT_BUILD_ARGS="$CI_AMENT_BUILD_ARGS --"
      ;;
  esac
  export CI_ARGS="$CI_ARGS --ament-build-args $CI_AMENT_BUILD_ARGS"
fi
if [ -n "${CI_AMENT_TEST_ARGS+x}" ]; then
  case $CI_AMENT_TEST_ARGS in
    *-- )
      # delimiter is already appended
      ;;
    * )
      CI_AMENT_TEST_ARGS="$CI_AMENT_TEST_ARGS --"
      ;;
  esac
  export CI_ARGS="$CI_ARGS --ament-test-args $CI_AMENT_TEST_ARGS"
fi
@[if os_name in ['linux', 'linux-aarch64'] and turtlebot_demo]@
export CI_ARGS="$CI_ARGS --ros1-path /opt/ros/kinetic"
@[end if]@
echo "Using args: $CI_ARGS"
echo "# END SECTION"

@[if os_name in ['linux', 'linux-aarch64']]@
mkdir -p $HOME/.ccache
echo "# BEGIN SECTION: docker version"
docker version
echo "# END SECTION"
echo "# BEGIN SECTION: docker info"
docker info
echo "# END SECTION"
echo "# BEGIN SECTION: Inject date into Dockerfile"
sed -i "s/@@today_str/`date +%Y-%m-%d`/" linux_docker_resources/Dockerfile
echo "# END SECTION"
echo "# BEGIN SECTION: Build Dockerfile"
@[if os_name == 'linux-aarch64']@
sed -i 's+^FROM.*$+FROM aarch64/ubuntu:xenial+' linux_docker_resources/Dockerfile
sed -i 's+apt-get update+(apt-get update || true)+' linux_docker_resources/Dockerfile
@[  if turtlebot_demo]@
docker build --build-arg PLATFORM=arm --build-arg INSTALL_TURTLEBOT2_DEMO_DEPS=true -t ros2_batch_ci_turtlebot_demo linux_docker_resources
@[  else]@
docker build --build-arg PLATFORM=arm -t ros2_batch_ci_aarch64 linux_docker_resources
@[  end if]@
@[elif os_name == 'linux']@
@[  if turtlebot_demo]@
docker build --build-arg INSTALL_TURTLEBOT2_DEMO_DEPS=true -t ros2_batch_ci_turtlebot_demo linux_docker_resources
@[  else]@
docker build -t ros2_batch_ci linux_docker_resources
@[  end if]@
@[else]@
@{ assert 'Unknown os_name: ' + os_name }@
@[end if]@
echo "# END SECTION"
echo "# BEGIN SECTION: Run Dockerfile"
@[if turtlebot_demo]@
export CONTAINER_NAME=ros2_batch_ci_turtlebot_demo
@[elif os_name == 'linux']@
export CONTAINER_NAME=ros2_batch_ci
@[elif os_name == 'linux-aarch64']@
export CONTAINER_NAME=ros2_batch_ci_aarch64
@[else]@
@{ assert 'Unknown os_name: ' + os_name }@
@[end if]@
docker run --privileged -e UID=`id -u` -e GID=`id -g` -e CI_ARGS="$CI_ARGS" -e CCACHE_DIR=/home/rosbuild/.ccache -i -v `pwd`:/home/rosbuild/ci_scripts -v $HOME/.ccache:/home/rosbuild/.ccache $CONTAINER_NAME
echo "# END SECTION"
@[else]@
echo "# BEGIN SECTION: Run script"
/usr/local/bin/python3 -u run_ros2_batch.py $CI_ARGS
echo "# END SECTION"
@[end if]@
@[elif os_name == 'windows']@
setlocal enableDelayedExpansion
rmdir /S /Q ws workspace "work space"

echo "# BEGIN SECTION: Determine arguments"
set "PATH=%PATH:"=%"
set "CI_ARGS=--force-ansi-color --workspace-path %WORKSPACE%"
if "%CI_BRANCH_TO_TEST%" NEQ "" (
  set "CI_ARGS=%CI_ARGS% --test-branch %CI_BRANCH_TO_TEST%"
)
if "%CI_USE_WHITESPACE_IN_PATHS%" == "true" (
  set "CI_ARGS=%CI_ARGS% --white-space-in sourcespace buildspace installspace workspace"
)
if "%CI_USE_CONNEXT%" == "true" (
  set "CI_ARGS=%CI_ARGS% --connext"
)
if "%CI_DISABLE_CONNEXT_STATIC%" == "true" (
  set "CI_ARGS=%CI_ARGS% --disable-connext-static"
)
if "%CI_DISABLE_CONNEXT_DYNAMIC%" == "true" (
  set "CI_ARGS=%CI_ARGS% --disable-connext-dynamic"
)
if "%CI_USE_OSRF_CONNEXT_DEBS%" == "true" (
  set "CI_ARGS=%CI_ARGS% --osrf-connext-debs"
)
if "%CI_USE_FASTRTPS%" == "true" (
  set "CI_ARGS=%CI_ARGS% --fastrtps"
)
if "%CI_USE_OPENSPLICE%" == "true" (
  set "CI_ARGS=%CI_ARGS% --opensplice"
)
if "%CI_ROS2_REPOS_URL%" EQU "" (
  set "CI_ROS2_REPOS_URL=@default_repos_url"
)
set "CI_ARGS=%CI_ARGS% --repo-file-url %CI_ROS2_REPOS_URL%"
if "%CI_ROS2_SUPPLEMENTAL_REPOS_URL%" NEQ "" (
  set "CI_ARGS=%CI_ARGS% --supplemental-repo-file-url %CI_ROS2_SUPPLEMENTAL_REPOS_URL%"
)
if "%CI_ISOLATED%" == "true" (
  set "CI_ARGS=%CI_ARGS% --isolated"
)
if "%CI_CMAKE_BUILD_TYPE%" NEQ "None" (
  set "CI_ARGS=%CI_ARGS% --cmake-build-type %CI_CMAKE_BUILD_TYPE%"
)
if "%CI_CMAKE_BUILD_TYPE%" == "Debug" (
  where python_d > python_debug_interpreter.txt
  set /p PYTHON_DEBUG_INTERPRETER=<python_debug_interpreter.txt
  set "CI_ARGS=%CI_ARGS% --python-interpreter !PYTHON_DEBUG_INTERPRETER!"
)
if "%CI_ENABLE_C_COVERAGE%" == "true" (
  set "CI_ARGS=%CI_ARGS% --coverage"
)
if "%CI_AMENT_BUILD_ARGS%" NEQ "" (
  if "%CI_AMENT_BUILD_ARGS:~-2%" NEQ "--" (
    set "CI_AMENT_BUILD_ARGS=%CI_AMENT_BUILD_ARGS% --"
  )
  set "CI_ARGS=%CI_ARGS% --ament-build-args %CI_AMENT_BUILD_ARGS%"
)
if "%CI_AMENT_TEST_ARGS%" NEQ "" (
  if "%CI_AMENT_TEST_ARGS:~-2%" NEQ "--" (
    set "CI_AMENT_TEST_ARGS=%CI_AMENT_TEST_ARGS% --"
  )
  set "CI_ARGS=%CI_ARGS% --ament-test-args %CI_AMENT_TEST_ARGS%"
)
echo Using args: %CI_ARGS%
echo "# END SECTION"

echo "# BEGIN SECTION: Run script"
python -u run_ros2_batch.py %CI_ARGS%
echo "# END SECTION"
@[else]@
@{ assert 'Unknown os_name: ' + os_name }@
@[end if]</command>
    </hudson.tasks.@(shell_type)>
  </builders>
  <publishers>
@(SNIPPET(
    'publisher_warnings',
    os_name=os_name,
))@
@(SNIPPET(
    'publisher_cobertura',
))@
@(SNIPPET(
    'publisher_xunit',
))@
@[if mailer_recipients]@
    <hudson.tasks.Mailer plugin="mailer@@1.20">
      <recipients>@(mailer_recipients)</recipients>
      <dontNotifyEveryUnstableBuild>@(dont_notify_every_unstable_build)</dontNotifyEveryUnstableBuild>
      <sendToIndividuals>false</sendToIndividuals>
    </hudson.tasks.Mailer>
@[end if]@
  </publishers>
  <buildWrappers>
@[if build_timeout_mins]@
    <hudson.plugins.build__timeout.BuildTimeoutWrapper plugin="build-timeout@@1.18">
      <strategy class="hudson.plugins.build_timeout.impl.AbsoluteTimeOutStrategy">
        <timeoutMinutes>@(build_timeout_mins)</timeoutMinutes>
      </strategy>
      <operationList>
        <hudson.plugins.build__timeout.operations.AbortOperation />
      </operationList>
    </hudson.plugins.build__timeout.BuildTimeoutWrapper>
@[end if]@
    <hudson.plugins.timestamper.TimestamperBuildWrapper plugin="timestamper@@1.8.8" />
    <hudson.plugins.ansicolor.AnsiColorBuildWrapper plugin="ansicolor@@0.5.0">
      <colorMapName>xterm</colorMapName>
    </hudson.plugins.ansicolor.AnsiColorBuildWrapper>
@[if os_name != 'windows']@
    <com.cloudbees.jenkins.plugins.sshagent.SSHAgentBuildWrapper plugin="ssh-agent@@1.15">
      <credentialIds>
        <string>1c2004f6-2e00-425d-a421-2e1ba62ca7a7</string>
      </credentialIds>
      <ignoreMissing>false</ignoreMissing>
    </com.cloudbees.jenkins.plugins.sshagent.SSHAgentBuildWrapper>
@[end if]@
  </buildWrappers>
</project>


Fix exception printing in the scripter so exceptions are also received and reported to the commanding object.

/*  Sirikata
 *  scripter.em
 *
 *  Copyright (c) 2011, Ewen Cheslack-Postava
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of Sirikata nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

system.require('std/core/bind.js');
system.require('std/escape.em');
system.require('std/core/pretty.em');

if (typeof(std) === "undefined") std = {};
if (typeof(std.script) === "undefined") std.script = {};

(
function() {

    var ns = std.script;

    /** A Scripter is an object which will display a scripting window
     *  for operating on other objects.
     */
    ns.Scripter = function(parent) {
        this._parent = parent;
        this._scriptedObjects = {};

        var scripting_gui = this._parent._simulator.createGUI("scripting", "scripting/prompt.html", 400, 600);
        scripting_gui.bind("event", std.core.bind(this._handleScriptEvent, this));
        this._scriptingWindow = scripting_gui;
        this._scriptingWindow.hide();

        // Listen for replies
        var scriptReplyPattern = new util.Pattern("reply", "script");
        var scriptReplyHandler = std.core.bind(this._handleScriptReply, this);
        scriptReplyHandler <- scriptReplyPattern;

        // Listen for print events
        var printPattern = new util.Pattern("request", "print");
        var printHandler = std.core.bind(this._handlePrint, this);
        printHandler <- printPattern;
    };

    ns.Scripter.prototype.script = function(target) {
        if (!target) return;

        this._parent.invoke("initScript", target);
        this._scriptingWindow.eval('addObject(' + Escape.escapeString(target.toString(), '"') + ');');
        this._scriptingWindow.show();
        this._scriptedObjects[target.toString()] = target;
    };

    ns.Scripter.prototype._handleScriptEvent = function(evt, objid, val) {
        if (evt == 'Close') {
            system.print('Close\n'); // FIXME
        }
        else if (evt == 'ExecScript') {
            // ExecScript Command Value
            var target = this._scriptedObjects[objid];
            if (!target) {
                system.prettyprint('Received ExecScript UI event for unknown object:' + objid);
                return;
            }
            var request = {
                request : 'script',
                script : val
            };
            request -> target;
        }
    };

    ns.Scripter.prototype._handleScriptReply = function(msg, sender) {
        var win = this._scriptingWindow;

        if (msg.value !== undefined)
            win.eval('addMessage(' + Escape.escapeString(sender.toString(), '\"') + ', ' + Escape.escapeString(std.core.pretty(msg.value), '"') + ')');
        if (msg.exception !== undefined)
            win.eval('addMessage(' + Escape.escapeString(sender.toString(), '\"') + ', ' + Escape.escapeString('Exception: ' + std.core.pretty(msg.exception), '"') + ')');
    };

    ns.Scripter.prototype._handlePrint = function(msg, sender) {
        var win = this._scriptingWindow;

        if (msg.print) {
            var to_print = msg.print;
            win.eval('addMessage(' + Escape.escapeString(sender.toString(), '\"') + ', ' + Escape.escapeString(std.core.pretty(to_print), '"') + ')');
        }
    };

})();

/*  Sirikata
 *  scripter.em
 *
 *  Copyright (c) 2011, Ewen Cheslack-Postava
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without
 *  modification, are permitted provided that the following conditions are
 *  met:
 *  * Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 *  * Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in
 *    the documentation and/or other materials provided with the
 *    distribution.
 *  * Neither the name of Sirikata nor the names of its contributors may
 *    be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
 * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

system.require('std/core/bind.js');
system.require('std/escape.em');
system.require('std/core/pretty.em');

if (typeof(std) === "undefined") std = {};
if (typeof(std.script) === "undefined") std.script = {};

(
function() {

    var ns = std.script;

    /** A Scripter is an object which will display a scripting window
     *  for operating on other objects.
     */
    ns.Scripter = function(parent) {
        this._parent = parent;
        this._scriptedObjects = {};

        var scripting_gui = this._parent._simulator.createGUI("scripting", "scripting/prompt.html", 400, 600);
        scripting_gui.bind("event", std.core.bind(this._handleScriptEvent, this));
        this._scriptingWindow = scripting_gui;
        this._scriptingWindow.hide();

        // Listen for replies
        var scriptReplyPattern = new util.Pattern("reply", "script");
        var scriptReplyHandler = std.core.bind(this._handleScriptReply, this);
        scriptReplyHandler <- scriptReplyPattern;

        // Listen for print events
        var printPattern = new util.Pattern("request", "print");
        var printHandler = std.core.bind(this._handlePrint, this);
        printHandler <- printPattern;
    };

    ns.Scripter.prototype.script = function(target) {
        if (!target) return;

        this._parent.invoke("initScript", target);
        this._scriptingWindow.eval('addObject(' + Escape.escapeString(target.toString(), '"') + ');');
        this._scriptingWindow.show();
        this._scriptedObjects[target.toString()] = target;
    };

    ns.Scripter.prototype._handleScriptEvent = function(evt, objid, val) {
        if (evt == 'Close') {
            system.print('Close\n'); // FIXME
        }
        else if (evt == 'ExecScript') {
            // ExecScript Command Value
            var target = this._scriptedObjects[objid];
            if (!target) {
                system.prettyprint('Received ExecScript UI event for unknown object:' + objid);
                return;
            }
            var request = {
                request : 'script',
                script : val
            };
            request -> target;
        }
    };

    ns.Scripter.prototype._handleScriptReply = function(msg, sender) {
        var win = this._scriptingWindow;

        if (msg.value)
            win.eval('addMessage(' + Escape.escapeString(sender.toString(), '\"') + ', ' + Escape.escapeString(msg.value.toString(), '"') + ')');
        else if (msg.exception)
            win.eval('addMessage(' + Escape.escapeString(sender.toString(), '\"') + Escape.escapeString('Exception: ' + msg.exception.toString(), '"') + ')');
    };

    ns.Scripter.prototype._handlePrint = function(msg, sender) {
        var win = this._scriptingWindow;

        if (msg.print) {
            var to_print = msg.print;
            win.eval('addMessage(' + Escape.escapeString(sender.toString(), '\"') + ', ' + Escape.escapeString(std.core.pretty(to_print), '"') + ')');
        }
    };

})();


Remove another hardcoded srv

Remove another hardcoded srv

// generated from rosidl_generator_cpp/resource/srv__traits.hpp.em
// generated code does not contain a copyright notice

@#######################################################################
@# EmPy template for generating <srv>__traits.hpp files
@#
@# Context:
@#  - spec (rosidl_parser.ServiceSpecification)
@#    Parsed specification of the .srv file
@#  - subfolder (string)
@#    The subfolder / subnamespace of the message
@#    Either 'srv' or 'action'
@#  - get_header_filename_from_msg_name (function)
@#######################################################################
@
@{
header_guard_parts = [
    spec.pkg_name, subfolder,
    get_header_filename_from_msg_name(spec.srv_name) + '__traits_hpp']
header_guard_variable = '__'.join([x.upper() for x in header_guard_parts]) + '_'
cpp_namespace = '%s::%s::' % (spec.pkg_name, subfolder)
}@

#include "@(spec.pkg_name)/@(subfolder)/@(get_header_filename_from_msg_name(spec.srv_name))__struct.hpp"

#ifndef @(header_guard_variable)
#define @(header_guard_variable)

namespace rosidl_generator_traits
{

#ifndef __ROSIDL_GENERATOR_CPP_TRAITS
#define __ROSIDL_GENERATOR_CPP_TRAITS

template<typename T>
struct has_fixed_size : std::false_type {};

template<typename T>
struct has_bounded_size : std::false_type {};

#endif  // __ROSIDL_GENERATOR_CPP_TRAITS

template<>
struct has_fixed_size<@(cpp_namespace)@(spec.srv_name)>
  : std::integral_constant<
    bool,
    has_fixed_size<@(cpp_namespace)@(spec.srv_name)_Request>::value &&
    has_fixed_size<@(cpp_namespace)@(spec.srv_name)_Response>::value
  >
{
};

template<>
struct has_bounded_size<@(cpp_namespace)@(spec.srv_name)>
  : std::integral_constant<
    bool,
    has_bounded_size<@(cpp_namespace)@(spec.srv_name)_Request>::value &&
    has_bounded_size<@(cpp_namespace)@(spec.srv_name)_Response>::value
  >
{
};

}  // namespace rosidl_generator_traits

#endif  // @(header_guard_variable)

// generated from rosidl_generator_cpp/resource/srv__traits.hpp.em
// generated code does not contain a copyright notice

@#######################################################################
@# EmPy template for generating <srv>__traits.hpp files
@#
@# Context:
@#  - spec (rosidl_parser.ServiceSpecification)
@#    Parsed specification of the .srv file
@#  - subfolder (string)
@#    The subfolder / subnamespace of the message
@#    Either 'srv' or 'action'
@#  - get_header_filename_from_msg_name (function)
@#######################################################################
@
@{
header_guard_parts = [
    spec.pkg_name, subfolder,
    get_header_filename_from_msg_name(spec.srv_name) + '__traits_hpp']
header_guard_variable = '__'.join([x.upper() for x in header_guard_parts]) + '_'
cpp_namespace = '%s::srv::' % (spec.pkg_name)
}@

#include "@(spec.pkg_name)/@(subfolder)/@(get_header_filename_from_msg_name(spec.srv_name))__struct.hpp"

#ifndef @(header_guard_variable)
#define @(header_guard_variable)

namespace rosidl_generator_traits
{

#ifndef __ROSIDL_GENERATOR_CPP_TRAITS
#define __ROSIDL_GENERATOR_CPP_TRAITS

template<typename T>
struct has_fixed_size : std::false_type {};

template<typename T>
struct has_bounded_size : std::false_type {};

#endif  // __ROSIDL_GENERATOR_CPP_TRAITS

template<>
struct has_fixed_size<@(cpp_namespace)@(spec.srv_name)>
  : std::integral_constant<
    bool,
    has_fixed_size<@(cpp_namespace)@(spec.srv_name)_Request>::value &&
    has_fixed_size<@(cpp_namespace)@(spec.srv_name)_Response>::value
  >
{
};

template<>
struct has_bounded_size<@(cpp_namespace)@(spec.srv_name)>
  : std::integral_constant<
    bool,
    has_bounded_size<@(cpp_namespace)@(spec.srv_name)_Request>::value &&
    has_bounded_size<@(cpp_namespace)@(spec.srv_name)_Response>::value
  >
{
};

}  // namespace rosidl_generator_traits

#endif  // @(header_guard_variable)


Fixing nvidia snippet for gazebo

Fixing nvidia snippet for gazebo

@(TEMPLATE(
    'snippet/add_generated_comment.Dockerfile.em',
    user_name=user_name,
    tag_name=tag_name,
    source_template_name=template_name,
    now_str=now_str,
))@
@(TEMPLATE(
    'snippet/from_base_image.Dockerfile.em',
    template_packages=template_packages,
    os_name=os_name,
    os_code_name=os_code_name,
    arch=arch,
    base_image=base_image,
))@
MAINTAINER Nate Koenig nkoenig@@osrfoundation.org
@[if 'packages' in locals()]@
@[if packages]@

# install packages
RUN apt-get update && apt-get install -q -y \
    @(' \\\n    '.join(packages))@

@[end if]@
@[end if]@

# install gazebo packages
RUN apt-get update && apt-get install -q -y \
    @(' \\\n    '.join(gazebo_packages))@

# setup environment
RUN echo "export QT_X11_NO_MITSHM=1" >> ~/.bashrc \
    && update-locale LANG=C.UTF-8 LC_MESSAGES=POSIX

# install nvidia drivers
ADD nvidia-driver.run /tmp/nvidia-driver.run
RUN sh /tmp/nvidia-driver.run -a -N --ui=none --no-kernel-module \
	&& rm /tmp/nvidia-driver.run

ENTRYPOINT ["bash", "-c"]
@{
cmds = [
'bash',
]
}@
CMD ["@(' && '.join(cmds))"]

@(TEMPLATE(
    'snippet/add_generated_comment.Dockerfile.em',
    user_name=user_name,
    tag_name=tag_name,
    source_template_name=template_name,
    now_str=now_str,
))@
@(TEMPLATE(
    'snippet/from_base_image.Dockerfile.em',
    template_packages=template_packages,
    os_name=os_name,
    os_code_name=os_code_name,
    arch=arch,
    base_image=base_image,
))@
MAINTAINER Nate Koenig nkoenig@@osrfoundation.org
@[if 'packages' in locals()]@
@[if packages]@

# install packages
RUN apt-get update && apt-get install -q -y \
    @(' \\\n    '.join(packages))@

@[end if]@
@[end if]@

# install gazebo packages
RUN apt-get update && apt-get install -q -y \
    @(' \\\n    '.join(gazebo_packages))@

# setup environment
RUN echo "export QT_X11_NO_MITSHM=1" >> ~/.bashrc \
    && update-locale LANG=C.UTF-8 LC_MESSAGES=POSIX

ADD nvidia-driver.run /tmp/nvidia-driver.run
RUN sudo sh /tmp/nvidia-driver.run -a -N --ui=none --no-kernel-module \
	&& sudo rm /tmp/nvidia-driver.run

ENTRYPOINT ["bash", "-c"]
@{
cmds = [
'bash',
]
}@
CMD ["@(' && '.join(cmds))"]


Always init rosdep if it is installed

Always init rosdep if it is installed

If rosdep is to be installed but `rosdistro_index_url` is unset, then avoid setting the environment variable but still initialize rosdep

@(TEMPLATE(
    'snippet/add_generated_comment.Dockerfile.em',
    user_name=user_name,
    tag_name=tag_name,
    source_template_name=template_name,
))@
@(TEMPLATE(
    'snippet/from_base_image.Dockerfile.em',
    template_packages=template_packages,
    os_name=os_name,
    os_code_name=os_code_name,
    arch=arch,
    base_image=base_image,
    maintainer_name=maintainer_name,
))@
@(TEMPLATE(
    'snippet/setup_tzdata.Dockerfile.em',
    os_name=os_name,
    os_code_name=os_code_name,
))@
@{
template_dependencies = [
    'dirmngr',
    'gnupg2',
    'lsb-release',
]
# add 'python3-pip' to 'template_dependencies' if pip dependencies are declared
if 'pip3_install' in locals():
    if isinstance(pip3_install, list) and pip3_install != []:
        template_dependencies.append('python3-pip')
}@
@(TEMPLATE(
    'snippet/install_upstream_package_list.Dockerfile.em',
    packages=template_dependencies,
    upstream_packages=upstream_packages if 'upstream_packages' in locals() else [],
))@
@
# setup keys
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 421C365BD9FF1F717815A3895523BAEEB01FA116

# setup sources.list
RUN echo "deb http://packages.ros.org/ros2/ubuntu `lsb_release -sc` main" > /etc/apt/sources.list.d/ros2-latest.list

# setup environment
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8

@{
# add colcon packages to 'ros2_repo_packages' if colcon is used
if 'colcon_args' in locals():
    colcon_packages = [
        'python3-colcon-common-extensions',
    ]
    ros2_repo_packages.extend(colcon_packages)
}@
@[if 'ros2_repo_packages' in locals()]@
@[  if ros2_repo_packages]@
# install packages from the ROS repositories
RUN apt-get update && apt-get install -y --no-install-recommends \
    @(' \\\n    '.join(sorted(ros2_repo_packages)))@  \
    && rm -rf /var/lib/apt/lists/*

@[  end if]@
@[end if]@
@
@[if 'pip3_install' in locals()]@
@[  if pip3_install]@
# install python packages
RUN pip3 install -U \
    @(' \\\n    '.join(pip3_install))@

@[  end if]@
@[end if]@
@
@[if 'vcs' in locals()]@
@[  if vcs]@

@[if 'rosdep' in locals()]@
@[  if 'rosdistro_index_url' in rosdep]@
# bootstrap rosdep
ENV ROSDISTRO_INDEX_URL @(rosdep['rosdistro_index_url'])
@[  end if]@
RUN rosdep init \
    && rosdep update
@[end if]@

# clone source
ENV ROS2_WS @(ws)
RUN mkdir -p $ROS2_WS/src
WORKDIR $ROS2_WS
@(TEMPLATE(
    'snippet/vcs_import.Dockerfile.em',
    vcs=vcs,
    ws='src',
))@

@[  end if]@
@[end if]@
@
@[if 'rosdep' in locals()]@
@[  if 'install' in rosdep]@
@(TEMPLATE(
    'snippet/install_rosdep_dependencies.Dockerfile.em',
    install_args=rosdep['install'],
))@
@[  end if]@
@[end if]@

@[if 'colcon_args' in locals()]@
@[  if colcon_args]@
# build source
WORKDIR $ROS2_WS
RUN colcon \
    @(' \\\n    '.join(colcon_args))@

@[  end if]@
@[end if]@
# setup bashrc
RUN cp /etc/skel/.bashrc ~/

@[if 'entrypoint_name' in locals()]@
@[  if entrypoint_name]@
@{
entrypoint_file = entrypoint_name.split('/')[-1]
}@
# setup entrypoint
COPY ./@entrypoint_file /

ENTRYPOINT ["/@entrypoint_file"]
@[  end if]@
@[end if]@
@{
cmds = [
'bash',
]
}@
CMD ["@(' && '.join(cmds))"]

@(TEMPLATE(
    'snippet/add_generated_comment.Dockerfile.em',
    user_name=user_name,
    tag_name=tag_name,
    source_template_name=template_name,
))@
@(TEMPLATE(
    'snippet/from_base_image.Dockerfile.em',
    template_packages=template_packages,
    os_name=os_name,
    os_code_name=os_code_name,
    arch=arch,
    base_image=base_image,
    maintainer_name=maintainer_name,
))@
@(TEMPLATE(
    'snippet/setup_tzdata.Dockerfile.em',
    os_name=os_name,
    os_code_name=os_code_name,
))@
@{
template_dependencies = [
    'dirmngr',
    'gnupg2',
    'lsb-release',
]
# add 'python3-pip' to 'template_dependencies' if pip dependencies are declared
if 'pip3_install' in locals():
    if isinstance(pip3_install, list) and pip3_install != []:
        template_dependencies.append('python3-pip')
}@
@(TEMPLATE(
    'snippet/install_upstream_package_list.Dockerfile.em',
    packages=template_dependencies,
    upstream_packages=upstream_packages if 'upstream_packages' in locals() else [],
))@
@
# setup keys
RUN apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys 421C365BD9FF1F717815A3895523BAEEB01FA116

# setup sources.list
RUN echo "deb http://packages.ros.org/ros2/ubuntu `lsb_release -sc` main" > /etc/apt/sources.list.d/ros2-latest.list

# setup environment
ENV LANG C.UTF-8
ENV LC_ALL C.UTF-8

@{
# add colcon packages to 'ros2_repo_packages' if colcon is used
if 'colcon_args' in locals():
    colcon_packages = [
        'python3-colcon-common-extensions',
    ]
    ros2_repo_packages.extend(colcon_packages)
}@
@[if 'ros2_repo_packages' in locals()]@
@[  if ros2_repo_packages]@
# install packages from the ROS repositories
RUN apt-get update && apt-get install -y --no-install-recommends \
    @(' \\\n    '.join(sorted(ros2_repo_packages)))@  \
    && rm -rf /var/lib/apt/lists/*

@[  end if]@
@[end if]@
@
@[if 'pip3_install' in locals()]@
@[  if pip3_install]@
# install python packages
RUN pip3 install -U \
    @(' \\\n    '.join(pip3_install))@

@[  end if]@
@[end if]@
@
@[if 'vcs' in locals()]@
@[  if vcs]@

@[if 'rosdep' in locals()]@
@[  if 'rosdistro_index_url' in rosdep]@
# bootstrap rosdep
ENV ROSDISTRO_INDEX_URL @(rosdep['rosdistro_index_url'])
RUN rosdep init \
    && rosdep update
@[  end if]@
@[end if]@

# clone source
ENV ROS2_WS @(ws)
RUN mkdir -p $ROS2_WS/src
WORKDIR $ROS2_WS
@(TEMPLATE(
    'snippet/vcs_import.Dockerfile.em',
    vcs=vcs,
    ws='src',
))@

@[  end if]@
@[end if]@
@
@[if 'rosdep' in locals()]@
@[  if 'install' in rosdep]@
@(TEMPLATE(
    'snippet/install_rosdep_dependencies.Dockerfile.em',
    install_args=rosdep['install'],
))@
@[  end if]@
@[end if]@

@[if 'colcon_args' in locals()]@
@[  if colcon_args]@
# build source
WORKDIR $ROS2_WS
RUN colcon \
    @(' \\\n    '.join(colcon_args))@

@[  end if]@
@[end if]@
# setup bashrc
RUN cp /etc/skel/.bashrc ~/

@[if 'entrypoint_name' in locals()]@
@[  if entrypoint_name]@
@{
entrypoint_file = entrypoint_name.split('/')[-1]
}@
# setup entrypoint
COPY ./@entrypoint_file /

ENTRYPOINT ["/@entrypoint_file"]
@[  end if]@
@[end if]@
@{
cmds = [
'bash',
]
}@
CMD ["@(' && '.join(cmds))"]


fix regression from #29

fix regression from #29

# generated from ros/core/roslib/cmake/roslib-extras.cmake.em

@[if DEVELSPACE]@
# set path to gendeps executable in develspace
set(gendeps_exe @(CMAKE_CURRENT_SOURCE_DIR)/scripts/gendeps)
@[else]@
# set path to gendeps executable in installspace
set(gendeps_exe ${roslib_DIR}/../../../@(CATKIN_PACKAGE_BIN_DESTINATION)/gendeps)
@[end if]@

# generated from ros/core/roslib/cmake/roslib-extras.cmake.em

@[if DEVELSPACE]@
# set path to gendeps executable in develspace
set(gendeps_exe @(CMAKE_CURRENT_SOURCE_DIR)/scripts/gendeps)
@[else]@
# set path to gendeps executable in installspace
set(gendeps_exe ${genlib_DIR}/../../../@(CATKIN_PACKAGE_BIN_DESTINATION)/gendeps)
@[end if]@