Seeking suggestions - how to have versions of an Automator service workflow

I have a workflow which is installed as a Service. It is used to call code in my AppleScript applet. The Service has one action: a "Run AppleScript" action. I update the Service quite often with improvements.

I need a way to know whether my users' copy of the Service is out-of-date. I have developed some ideas:

  • First is to compare file size of user's copy against the copy being distributed. If they are different, then, the user's copy is out-of-date and needs to be updated. That works except that users need to be able to retain changes to their copy of the Service which should not be over-written my by applet.
  • Second is to make a custom property in the workflow's info.plist file. That, however, is over-written by Automator when it saves the workflow.
  • Third is to add a comment to the AppleScript code inside the workflow which can be interrogated by my applet. That does work but, opening and reading the workflow file seems like over-kill and runs the risk of that file being over-written or the XML code being corrupted.
  • Fourth is to add a plain text file to the contents of the workflow which would contain the version detail. My applet could then interrogate that file to get the version and this know whether the user's copy is out-of-date.

I'm inclined to using the 4th idea. However, all of those ideas are kludges.

Is there an Apple sanctioned method of versioning an Automator service workflow ?

Thanks.

  • Idea three (or reading a workflow variable) isn't all that different from four - what are you doing that risks corrupting the workflow declaration file?

Add a Comment

Replies

what are you doing that risks corrupting the workflow declaration file?

I'm not sure what might happen but, I am wary of "3" because the raw workflow file contains a lot of XML code I don't understand. Option "4" seems less risky as long as Automator doesn't delete the file. Also, in AppleScript, it's a bit quicker to get the entire contents of the file rather in "3" which would require code which parses the content looking for the version number. I've done test code for both and found "4" a little bit easier.

If all you are doing is reading the XML file, I'm not sure what would corrupt it, but an idea similar to the AppleScript comment would be to add a variable to the workflow (both would be in the file).

In a workflow's bundle, the /Contents/document.wflow file is a property list that declares the various actions with their settings (such as the script for the Run AppleScript action), action connections, workflow metadata, and any variables. By adding a variable for a version number to the workflow, your script can just look for the variable name and get its value instead of adding a file to the bundle - System Events includes a Property List Suite, so you can do something like:

on run -- example
   set plistFile to (choose file with showing package contents) -- get the document.wflow file
   set variables to getPlistElement from {plistFile, "variables"}
   if variables is not missing value then repeat with anItem in variables -- multiple variables
      if |name| of anItem is "Version" then -- or whatever
         return first item of value of anItem -- the value is a list
      end if
   end repeat
   return missing value -- not found
end run

to getPlistElement from plistItems -- get specified element from plist structure by name or index
   try
      if (count plistItems) < 2 then error "item list contains too few items"
      tell application "System Events"
         set element to property list file ((first item of plistItems) as text) -- root element
         repeat with anItem in rest of plistItems -- add on the sub items
            set anItem to contents of anItem
            try -- handle an index number
               set anItem to anItem as integer
            end try
            set element to (get property list item anItem of element)
         end repeat
         return value of element
      end tell
   on error errmess number errnum -- not found, etc
      log "getPlistElement error:  " & errmess & " (" & errnum & ")" -- or pass it on
      return missing value
   end try
end getPlistElement
  • Many thanks for all that. It is a much more elegant solution.

    As mentioned, I don't understand XML files. So, I don't know where or how to add "variables" to the wflow file. I could use System Events to add a new plist item to the file but, I don't know where in the structure to put it so that it is not overwritten by Automator when I edit and save the AppleScript.

    Anyway, I tried to just shove in a new key called "variables" using a text editor. Now Automator can't open the Service at all or it just hangs and I have to force quit it. So, I clearly have no idea of what I'm doing.

    As an aside, the wflow file has this section:

    on run {input, parameters}

    (* Your script goes here *) return input

    end run

    But my AS code isn't there. It's located under "ActionParameters", "source". My AS code is in a logical place as it is run by the "Run AppleScript" action. But, what is expected to go in the "on run" section ?

    Cheers.

Add a Comment

OK, I tried using automator actions to add the variable to the wflow file. I tried with "Get Specified Text" which I had hoped would pass the value to "Set Value of Variable". Automator said the value of the variable versions was "1.21" which was good. But, in fact the value was not stored anywhere near the variable in the xml file. Instead there is a mass of UUID and RTF data sprinkled in many places.

Anyway, I tried your code but, it produced an error: Can't get value of {identifier:"com.apple.Automator.Variable.Storage", |name|:"Version", UUID:"844A34DE-EEA4-48B1-B56C-4941A4510522"}.)

So, I'll try another day.

Thanks.

p.s., I've just found the "variables" pane in Automator Library. Maybe I'll try that.

cheers.

  • If the variable is created by the workflow, it won’t have a value in the document settings, since it is set by the workflow at run time. A variable manually created by right-clicking the variable pane (at the bottom of the workflow document) will persist between runs.

Add a Comment

It's working. Many thanks.