TweetFollow Us on Twitter

September 95 - MPW Tips and Tricks: Customizing Source Control With SourceServer

MPW Tips and Tricks: Customizing Source Control With SourceServer

Tim Maroney

When two engineers on a team edit the same source file at the same time, the resulting chaos can be terrible to behold. Source control was invented to mitigate the problem. Most Macintosh programmers are familiar with the MPW Shell's Check In and Check Out dialogs, and with its Projector commands. The next frontier of custom source control involves SourceServer, a nearly faceless application that implements most of the Projector commands. MPW scripts are easy to write, but they're no match for the power, speed, and friendliness of compiled software. SourceServer exports Projector commands as Apple events, allowing source control from compiled software without launching the MPW Shell in all its pomp and splendor.

Popular third-party development environments often send Apple events to SourceServer for integrated source control. You can also use SourceServer to customize Projector beyond what you might have thought possible. For instance, you can drag source control, kicking and screaming, into the modern world of user experience with drop-on applications. In this column, I'll show you how to check a file in or out with a simple drag and drop, and how to use SourceServer for other things as well. The sample code is provided on this issue's CD; SourceServer is distributed, with documentation, on the MPW Pro and E.T.O. CDs (available from Apple Developer Catalog) and with third-party development systems.

APPLE EVENTS FOR SOURCESERVER

Apple events have many faces, but they're primarily a way of communicating between different applications.

Each Apple event encapsulates a message as a command with any number of input parameters; the receiver of the message may return any number of result parameters to the sender. The most basic unit of data is the Apple event descriptor, which consists of a type code and a data handle. Apple events are built out of descriptors and are themselves special kinds of complex descriptors.

    For an excellent introduction to Apple events, see "Scripting the Finder From Your Application" by Greg Anderson in develop Issue 20.*

SourceServer's commands are represented as descriptor lists. Its Apple events are exact duplicates of the MPW Shell's Projector commands, but to avoid the overhead of a full command parser, both the command name and each argument are descriptors in the descriptor list. This saves you the trouble of putting quotes and escapes into arguments that might contain spaces or other special characters. The downside is that you have to expand arguments yourself: you can't pass in MPW wildcard characters, backquoted commands for expansion, or other special constructs.

Creating descriptor lists may sound harder than writing MPW scripts, but that's only because it is. I've provided some utility routines to ease the way, though. Listing 1 shows the utilities and illustrates how to make a command to check out a file for modification. As illustrated in the CheckOut routine in this listing, you call the CreateCommand routine first and then use the AddXArg routines to add arguments.

Listing 1. Creating SourceServer commands

OSErr CreateCommand(AEDesc *command, CString commandText)
// Begin a new SourceServer command; name of command is in
// commandText.
{
   OSErr err = AECreateList(NULL, 0, false, command);
   if (err != noErr) return err;
   err = AddCStringArg(command, commandText);
   if (err != noErr) (void) AEDisposeDesc(command);
   return err;
}

OSErr AddCommentArg(AEDesc *command, StringPtr comment)
/* Add a "-cs comment" argument to a SourceServer command. */
{
   OSErr err;
   if (comment[0] == 0) return noErr;
   err = AddCStringArg(command, "-cs");
   if (err != noErr) return err;
   err = AddPStringArg(command, comment);
   return err;
}

/* Other SourceServer argument utilities */
OSErr AddDirArg(AEDesc *command, short vRefNum, long folderID);
OSErr AddProjectArg(AEDesc *command, StringPtr projectName);
OSErr AddUserArg(AEDesc *command, StringPtr userName);
OSErr AddFullNameArg(AEDesc *command, FSSpec *file);
OSErr AddPStringArg(AEDesc *command, StringPtr string);
OSErr AddCStringArg(AEDesc *command, CString string);

OSErr CheckOut(FSSpec *file, StringPtr userName,
               StringPtr projectName, StringPtr comment)
/* Create a "Check Out Modifiable" command for SourceServer: */
/* CheckOut -m -cs <comment> -d <dir> -project < */
/*           project> -u <user> <file> */
{
   OSErr             err;
   AEDesc          command;
   CStringHandle    output = NULL, diagnostic = NULL;

   err = CreateCommand(&command, "CheckOut");
   if (err != noErr) return err;
   err = AddCStringArg(&command, "-m");
   if (err == noErr) err = AddCommentArg(&command, comment);
   if (err == noErr)
     err = AddDirArg(&command, file->vRefNum, file->parID);
   if (err == noErr) err = AddProjectArg(&command, projectName);
   if (err == noErr) err = AddUserArg(&command, userName);
   if (err == noErr) err = AddPStringArg(&command, file->name);
   if (err == noErr)
     err = SourceServerCommand(&command, &output, &diagnostic);
   (void) AEDisposeDesc(&command);
   /* Display output or diagnostic text as desired. */
   if (output != NULL) DisposeHandle((Handle) output);
   if (diagnostic != NULL) DisposeHandle((Handle) diagnostic);
   return err;
}

Some of the utilities take Pascal strings, while others take C strings, which could well be considered bad programming practice. I chose this dubious method not because I'm on drugs, but because Pascal strings and C strings are used in different ways. SourceServer's text descriptors are C strings; when passed to these utilities as string constants, they shouldn't be converted from Pascal format in place, since some compilers put constants in read-only areas. If you're internationally savvy, you may have another objection: string constants themselves are bad practice. However, for better or worse, MPW scripts and tools are not internationalized. Just like aliens in Star Trek, all MPW programmers are assumed to speak English.

While on the subject of programming practice, I must gently reprimand SourceServer for its approach to Apple events, in which script commands are simulated through a single 'cmnd' event. SourceServer's idiosyncratic convention dates from the earliest days of Apple events, and modern guidelines discourage this type of design. An application implementing its own Apple events should designate a different command code for each operation, treating arguments as keyword parameters.

Listing 2 shows how to send an Apple event to SourceServer. It's first necessary to find and perhaps launch the SourceServer application. The snippet called SignatureToApp (by Jens Alfke) on this issue's CD accomplishes this with a single function call. Simply pass in the creator code of SourceServer, which is 'MPSP'.

Listing 2. Sending commands to SourceServer

OSErr SourceServerCommand(AEDesc *command, CStringHandle *output,
                          CStringHandle *diagnostic)
{
   AppleEvent            aeEvent;
   AERecord              aeReply;
   AEDesc                sourceServerAddress, paramDesc;
   ProcessSerialNumber   sourceServerProcess;
   /* SignatureToApp requires this due to a minor bug */
   FSSpec                appSpec;
   long                  theLong, theSize;
   DescType              theType;
   OSErr                 err;

   *output = *diagnostic = NULL;   /* default replies */
   
   /* Find the SourceServer process and make a descriptor for its */
   /* process ID. */
   err = SignatureToApp('MPSP', NULL, &sourceServerProcess,
                         &appSpec, NULL, Sig2App_LaunchApplication,
                         launchContinue + launchDontSwitch);
   if (err != noErr) return err;
   err = AECreateDesc(typeProcessSerialNumber,
                      (Ptr) &sourceServerProcess,
                     sizeof(ProcessSerialNumber),
                     &sourceServerAddress);
   if (err != noErr) return err;

   /* Create and send the SourceServer Apple event. */
   err = AECreateAppleEvent('MPSP', 'cmnd', &sourceServerAddress,
                           kAutoGenerateReturnID, kAnyTransactionID,
                           &aeEvent);
   /* done with the address descriptor */
   (void) AEDisposeDesc(&sourceServerAddress);
   if (err != noErr) return err;
   /* add the command */
   err = AEPutParamDesc(&aeEvent, keyDirectObject, command);
   if (err != noErr) { (void) AEDisposeDesc(&aeEvent); return err; }
   err = AESend(&aeEvent, &aeReply,
                kAEWaitReply + kAENeverInteract, kAENormalPriority,
                kNoTimeOut, NULL, NULL);
   (void) AEDisposeDesc(&aeEvent);   /* done with the Apple event */
   if (err != noErr) return err;

   /* Check for an error return in the keyErrorNumber parameter. */
   err = AEGetParamPtr(&aeReply, keyErrorNumber, typeInteger,
                      &theType, &theLong, sizeof(long),
                      &theSize);
   if (err == noErr && (err = theLong) == noErr) {
      /* Get the standard output from the keyDirectObject parameter. */
      err = AEGetParamDesc(&aeReply, keyDirectObject, typeChar,
                           &paramDesc);
      if (err == noErr)
          *output = (CStringHandle) paramDesc.dataHandle;
      /* Get the diagnostic output from the 'diag' parameter. */
      err = AEGetParamDesc (&aeReply, 'diag', typeChar,
          &paramDesc);
      if (err == noErr)
          *diagnostic = (CStringHandle) paramDesc.dataHandle;
      /* Get the MPW status from the 'stat' parameter -- it */
      /* becomes our error return. */
      err = AEGetParamPtr(&aeReply, 'stat', typeInteger,
                         &theType, &theLong,
                         sizeof(long), &theSize);
      if (err == noErr) err = theLong;
   }

   /* done with the reply descriptor */
   (void) AEDisposeDesc(&aeReply);
   return err;
}

The event must be created before it can be sent. For SourceServer, there's a single parameter, named keyDirectObject, which is the descriptor list containing the command. After sending the event, you must extract the results. The results of an Apple event are returned as keyword parameters in a reply descriptor. First there's the standard keyErrorNumber parameter, which returns an error code if delivery failed. SourceServer returns three other parameters: The 'stat' parameter contains a second error code; if it's nonzero, SourceServer tried to execute the command and failed. When there's an error, there will be diagnostic output in the 'diag' parameter, a handle containing text from the MPW diagnostic (error) channel. Finally, there's standard output -- a handle specified by keyDirectObject -- which contains explanatory text.

PROJECTDRAG -- DRAG AND DROP SOURCE CONTROL

The Macintosh has always had a drag and drop user experience, but the true power and generality of dragging has been widely recognized only recently. The drag paradigm can even be used for source control. To turn Projector into a drag-savvy system, I've written a set of utilities called ProjectDrag (source code and documentation are provided on this issue's CD). You simply drag and drop icons onto the following miniapplications that make up ProjectDrag, and the corresponding function is performed:
  • Check In and Check Out, for checking files in and out

  • ModifyReadOnly, for editing a file without checking it out

  • Update, for bringing a file or folder up to date, as well as canceling checkouts and modify-read-only changes

  • ProjectDrag Setup, for configuring the system
These utilities are based on a drop-on application framework called DropShell (written by Leonard Rosenthol and Stephan Somogyi), also on the CD. When a file is dropped onto an application, the application receives an Open Documents ('odoc') event. DropShell takes care of the rigmarole of receiving this and other required Apple events. The ProjectDrag miniapplications pull the file specifications out of 'odoc' events and create SourceServer commands that operate on the files and folders that were dropped on their icons.
    DropShell is also available on the Internet at ftp://ftp.hawaii.edu/pub/mac/info-mac/Development/src/ and at other Info-Mac mirror sites.*
Some setup is required. ProjectDrag needs to know the locations of Projector databases. It maps between project names and Projector database files by keeping aliases to database folders in its Preferences folder. To start using a project, simply drag its ProjectorDB file or the enclosing folder onto ProjectDrag Setup. Projector also needs to know your user name, and your initials or a nickname are used in change comments at the start of files. These are stored in a text file in the Preferences folder. ProjectDrag asks you for this information if it can't find it, or you can launch ProjectDrag Setup and give the Set User Name command.

ProjectDrag is scriptable, unlike SourceServer and the MPW Shell. The miniapplications have an Apple event terminology resource ('aete') to advertise their events to scripting systems. This allows you to add source control commands to any application that lets you add AppleScript scripts to its menus.

ProjectDrag is able to run remotely over a network. This circumvents a limitation of SourceServer, which can only be driven locally. ProjectDrag can receive remote Apple events and then drive a copy of SourceServer that's local to it. Among other uses, this could support an accelerator for Apple Remote Access. Checking a file in or out over ARA takes a few minutes, which is fine, especially for those who find tedium particularly enjoyable. Copying files is faster. With local AppleScript front ends for remote ProjectDrag miniapplications, you could copy files to and from a remote "shadow folder" and initiate SourceServer commands at the remote location, where they would execute over a fast network such as Ethernet.

I like to think that I can solve user interface problems in my sleep. When I was writing ProjectDrag, I had a dream of a better user experience. Instead of miniapplications, ProjectDrag would be a magical system extension that would put a single small icon at some convenient place on the screen. When you dragged a file onto this icon, it would pop open into a temporary window and show you icons for the various options. Dreams are great for creativity, but it's easier to weigh alternatives when you're awake. After I woke up, I realized that miniapplications will be able to do the same thing.

Here's how: In Copland, the next generation of the Mac OS, the Finder will spring-load folders so that they open automatically when you drag onto them. It will also let you stash commonly used folders at the bottom of the screen, where they appear as short title bars. Drag the ProjectDrag folder to the bottom of the screen and you're set! Since the Finder will be providing my dream interface, there's no point in a lot of trap patching and extensibility infrastructure to accomplish the same thing.

Copland will bring another user experience benefit to ProjectDrag: it's planned that document windows will have a draggable file icon in their title bar, so you'll be able to use ProjectDrag on an open document by dragging the icon from its window.

YOU TAKE IT FROM HERE

You can create programs that use SourceServer for many other tasks. On cross-platform projects, Projector is sometimes used to control both platforms' source folders. This can lead to baroque and error-prone processes. With SourceServer, you can create front ends that do the right thing. They could copy to remote folders over a network, or lock read-only files since the other platform doesn't see Projector's 'ckid' resources.

Quality is an interesting area for source control applications. A quality tool could query Projector databases for the frequency and scope of changes at various stages of the project, correlating them with bug tracking to develop project metrics. Along similar lines, a tool could measure the change rate of various files to assist in what the quality gods refer to as root-cause analysis.

SourceServer is much more than a way for development systems to provide integrated source control. It's great for structuring your internal development process as well!

TIM MARONEY wrote TOPS Terminal and BackDrop, and has been a major contributor to TOPS for Macintosh, FaxPro, and Cachet. He has also contributed to Fiery, the Disney Screen Saver, Ofoto, Colortron, and the Usenet Mac Programmer's Guide. Tim learned computer networking while working on the Andrew and MacIP projects at Carnegie Mellon and studied compiler design in graduate school at Chapel Hill. He has written for all three major operating systems and a few minor ones. On the Macintosh, Tim's code has included applications, INITs, control panels, HyperCard stacks, XCMDs, shared libraries, trap patches, plug-ins, scripts, and things more difficult to characterize. Tim is currently doing contract work at Apple, and is available for parties and special events at a nominal cost.*

Thanks to Greg Anderson, Arno Gourdol, and B. Winston Hendrickson for reviewing this column.*

Special thanks to Jens Alfke, Jon Pugh, Leonard Rosenthol, and Stephan Somogyi.*

 

Community Search:
MacTech Search:

Software Updates via MacUpdate

Parallels Desktop 10.2.0 - Run Windows a...
Parallels Desktop is simply the world's bestselling, top-rated, and most trusted solution for running Windows applications on your Mac. With Parallels Desktop for Mac, you can seamlessly run both... Read more
LaunchBar 6.2 - Powerful file/URL/email...
LaunchBar is an award-winning productivity utility that offers an amazingly intuitive and efficient way to search and access any kind of information stored on your computer or on the Web. It provides... Read more
Firefox 37.0 - Fast, safe Web browser. (...
Firefox offers a fast, safe Web browsing experience. Browse quickly, securely, and effortlessly. With its industry-leading features, Firefox is the choice of Web development professionals and casual... Read more
Arq 4.11 - Online backup to Google Drive...
Arq is super-easy online backup for the Mac. Back up to your own Google Drive storage (15GB free storage), your own Amazon Glacier ($.01/GB per month storage) or S3, or any SFTP server. Arq backs up... Read more
MacFamilyTree 7.3.4 - Create and explore...
MacFamilyTree gives genealogy a facelift: it's modern, interactive, incredibly fast, and easy to use. We're convinced that generations of chroniclers would have loved to trade in their genealogy... Read more
Yummy FTP 1.10.2 - FTP/SFTP/FTPS client...
Yummy FTP is an FTP + SFTP + FTPS file transfer client which focuses on speed, reliability and productivity. Whether you need to transfer a few files or a few thousand, schedule automatic backups, or... Read more
VueScan 9.5.08 - Scanner software with a...
VueScan is a scanning program that works with most high-quality flatbed and film scanners to produce scans that have excellent color fidelity and color balance. VueScan is easy to use, and has... Read more
Iridient Developer 3.0.1 - Powerful imag...
Iridient Developer (was RAW Developer) is a powerful image conversion application designed specifically for OS X. Iridient Developer gives advanced photographers total control over every aspect of... Read more
Monodraw 0.8.4.1 - Powerful ASCII art ed...
Monodraw allows you to easily create text-based art (like diagrams, layouts, flow charts) and visually represent algorithms, data structures, binary formats and more. Because it's all just text, it... Read more
Air Video Server HD 2.1.0 - Stream video...
Air Video Server HD streams videos instantly from your computer on your iPhone, iPad, iPod touch or Apple TV. No need to worry about converting or transferring files. We took everything that was... Read more

Marvel Mighty Heroes, the Ultimate Marve...
DeNA and Marvel Entertainment have brought us a new action-packed brawler: Marvel Mighty Heroes. You can play with up to four of your friends as you favorite marvel heroes like Iron Man, Thor, Spider-Man, Captain America, Star-Lord, Hulk, and... | Read more »
Take Note - The Jot Script 2 Evernote Ed...
Adonit's Jot Script 2 sylus has an all-new edition that's meant to be Evernote's BFF. The sylus has been redesigned to work better with iPads and give you faster stroke tracking, smoother line rendering, and better tip-to-line accuracy. | Read more »
INFINIT Lets Mobile Users Send Files of...
Infinit  is a file sharing app that ignores file size limits. It maintains the original quality of your photos and videos so you can be sure they look awesome after sending. You can move entire albums of photos or full HD films from your iPhone to... | Read more »
Serious Sam Double D Developer is Making...
There's nothing like the thrill of watching a horse race, especially when the horses are drunk.  | Read more »
2K Announces WWE 2K, Mobile's First...
It seems like this month has been pretty big for wrestling. First Wrestlemania, then 2K has announces that they're releasing  WWE 2K for iOS. It's a simulation-based WWE game where you'll get to play with several WWE superstars such as John Cena, ... | Read more »
How the Apple Watch Could Change the Fac...
The Apple Watch is still a ways out, but my previous musings on the wearable’s various features got me thinking: what might it be like a year after launch? Two years? Five years? What if it becomes a symbiotic part of the iOS framework to the point... | Read more »
You Can Start Challenging Your Friends t...
Last year we reported that Sebastian Gosztyla's new game, Dual, was theorized to be released sometime during the summer of 2014. Sadly that did not become a reality, but the good news it there is now an official release date. | Read more »
Forgotten Memories : Alternate Realities...
Forgotten Memories : Alternate Realities, from Psychoz Interactive, is planned for release on April 23. The Resident Evil, Silent Hill, and Alone in the Dark inspired horror game puts you in the shoes of Rose Hawkins as she searches for a missing... | Read more »
Pie In The Sky: A Pizza Odyssey (Games)
Pie In The Sky: A Pizza Odyssey 1.0 Device: iOS Universal Category: Games Price: $2.99, Version: 1.0 (iTunes) Description: A game about delivering pizza. In space. | Read more »
Chosen Gives Hopeful Singers, Songwriter...
If YouTube videos and reality TV shows like The Voice have taught us one thing, it’s that there are a lot of people out there who are anxious to show the world their talents. And if they’ve taught us a second thing, it’s that there’s an almost... | Read more »

Price Scanner via MacPrices.net

Will Microsoft’s Surface 3 Give The 12-inch M...
The more I ruminate over the new 12-inch MacBook, the more it occurs that it’s probably going to be more of a cannibalization threat to high-end iPads (including a new 12-inch ‘Pad when/if that... Read more
13-inch 2.4GHz Retina MacBook Pro available f...
MacMall has the 2013 13″ 2.4GHz/128GB Retina MacBook Pro available for $949.99 for a limited time. Shipping is free. Their price is $350 off original MSRP, and it’s the only sub-$1000 new Retina... Read more
Adobe Brings Powerful Layout-Design Capabilit...
Adobe today announced the availability of Adobe Comp CC, a free iPad app that enables rapid creation of layout concepts for mobile, Web and print projects. With Comp CC, designers can rough out and... Read more
13-inch 2.6GHz/256GB Retina MacBook Pro avail...
Best Buy has clearance 2014 13″ 2.6GHz/256GB Retina MacBook Pros available for $1199.99 including free shipping. Their price is $300 off original MSRP, and it’s the lowest price for this model.... Read more
Updated Mac Price Trackers
We’ve updated our Mac Price Trackers with the latest information on prices, bundles, and availability on systems from Apple’s authorized internet/catalog resellers: - 15″ MacBook Pros - 13″ MacBook... Read more
21-inch 1.4GHz iMac on sale for $999, save $1...
Best Buy has the 21″ 1.4GHz iMac on sale for $999.99 on their online store. Choose free shipping or free local store pick up. Price is for online orders only, in-store prices may vary. Their price is... Read more
2.6GHz Mac mini on sale for $649, save $50
Amazon has the 2.6GHz Mac mini on sale for $649.99 including free shipping. Their price is $50 off MSRP, and it’s the lowest price available for this model. Read more
Textkraft Professional 3.2 Powerful iPad Text...
Finally it’s springtime, at least theoretically in my neck of the woods, where we’re still navigating canyons between towering snowbanks with temperatures well below freezing in winter weather that... Read more
Apple offering refurbished 27-inch 5K iMacs f...
The Apple Store is offering Apple Certified Refurbished 27″ 3.5GHz 5K iMacs for $2119 including free shipping. Their price is $380 off the price of new models, and it’s the lowest price available for... Read more
16GB iPad mini on sale for $199, save $50
Walmart has 16GB iPad minis (1st generation) available for $199.99 on their online store, including free shipping. Their price is $50 off MSRP. Online orders only. Read more

Jobs Board

DevOps Software Engineer - *Apple* Pay, iOS...
**Job Summary** Imagine what you could do here. At Apple , great ideas have a way of becoming great products, services, and customer experiences very quickly. Bring Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
Sr. Technical Services Consultant, *Apple*...
**Job Summary** Apple Professional Services (APS) has an opening for a senior technical position that contributes to Apple 's efforts for strategic and transactional Read more
Lead *Apple* Solutions Consultant - Retail...
**Job Summary** Job Summary The Lead ASC is an Apple employee who serves as the Apple business manager and influencer in a hyper-business critical Reseller's store Read more
*Apple* Pay - Site Reliability Engineer - Ap...
**Job Summary** Imagine what you could do here. At Apple , great ideas have a way of becoming great products, services, and customer experiences very quickly. Bring Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.