SCM Adapter Scripts
From ChangesWiki
Contents |
[edit] Writing an SCM Adapter Script for Fun and Profit
SCM adapter scripts facilitate the interaction between the Changes SCM HUD window (activated by AppleScript or via the chdiff utility) and a "flavor" of SCM. SCM adapter scripts can be written in any language which is executable (such as shell script, python, or ruby).
[edit] Examples
- git_adapter.py - http://changesrelease.s3.amazonaws.com/git_adapter.py
- svn_adapter.py - http://changesrelease.s3.amazonaws.com/svn_adapter.py
- hg_adapter.py - http://changesrelease.s3.amazonaws.com/hg_adapter.py
[edit] Commands
Your script will need to support the following commands:
--command=test_managed <file path>
This command tests the file at <file path> to see if it is "managed" by this flavor of SCM. A plist in XML format is written to stdout containing a dictionary with the following entries:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>isManaged</key> <true/> <key>returnCode</key> <integer>0</integer> <key>stdErr</key> <string></string> </dict> </plist>
In the plist, notice that there is an "isManaged" key, denoting the managed (by this SCM system) status of the file. There is also a return code (should be zero for no error) and the standard error component of the underlying SCM utility's output. In this mode, Changes only looks at the isManaged key, while ignoring any error status, as it's expected here.
--command=list_revs <file path>
This will export a list of revisions for the file at <file path>. A plist in XML format is written to stdout containing a dictionary with the following entries:
?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>returnCode</key> <integer>0</integer> <key>revList</key> <array> <dict> <key>author</key> <string>dynaflash</string> <key>date</key> <date>2008-04-15T17:08:31Z</date> <key>msg</key> <string>MacGui: replace handbrake.m0k.org references with handbrake.fr in the entire macosx/ directory</string> <key>rev</key> <integer>1419</integer> </dict> . . . <key>stdErr</key> <string></string> </dict> </plist>
In the plist, notice there is a "returnCode" (0 for no error), an array called "revList", which contains a list of revision dictionaries, and finally a string with the key "stdErr", encapsulating the standard error output of the underlying scm utility. Changes will parse this plist, and if the "returnCode" is 0 and the "revList" is populated, display the SCM HUD with the list of revisions in "revList".
Each revList dictionary contains the following key/value pairs:
- author - who committed the change
- date - when was the change committed?
- msg - any message associated with the commit
- rev - a durable revision id, which will be used to identify an revision to the script when we're exporting files later
--command=url_for_export <file path>
This command returns the "export url", which is actually just an export id which is passed as the "exporturl" to the "export_rev" command. In subversion, this really is and URL, but in git for example, it's a <revision>:relative/path/to/file identifier. This wart will be fixed in a future version of Changes. A plist in XML format is written to stdout containing a dictionary with the following entries:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>exportURL</key> <string>svn://svn.handbrake.fr/HandBrake/trunk/macosx/main.mm</string> <key>returnCode</key> <integer>0</integer> <key>stdErr</key> <string></string> </dict> </plist>
In this plist, there is a "returnCode" (0 for no error), a string called "exportURL" containing the export "URL" (could really be any id, for git it's a revision:path string) which will be passed to the following command. As usual, the "stdErr" key contains a value which encapsuates the stderr output from the underlying SCM utility.
--command=export_rev --rev=<revision> --exporturl=<exporturl> <file path>
This will export the revision at <revision> of the file at <export url> and <file path> (file path is optional for some SCMs, but needed for git - see the example git_adapter.py module). A plist in XML format is written to stdout containing a dictionary with the following entries:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <plist version="1.0"> <dict> <key>returnCode</key> <integer>0</integer> <key>stdErr</key> <string></string> <key>tmpPath</key> <string>/var/tmp/tmp.0.0x0fzP</string> </dict> </plist>
In this plist, the is a "returnCode" (0 for no error), a string called "tmpPath" which contains a path to the exported file in /var/tmp. Any stderr output from the underlying SCM utility is encapsulated in the string which the "stdErr" key contains.
[edit] SCM Adapter Locations
Changes looks for SCM Adapters in the following locations:
- ~/Library/Application Support/Changes/SCM Adapters
- Changes.app/Contents/Resources/SCM Adapters
Changes will test using your scripts first and fall back to the ones contained in the app bundle if a match is not found. Your script must have the executable bit set!