How to Automagically Sync Directories Across Multiple Macs with Git & Launchd

In an effort to minimize my downtime when the funny noises this MacBook Pro is making finally amount to something – I’ve wired up a git repository to OS X’s native launchd service. The git repository hold all of my active projects – whether development projects with their own repos, research projects, consulting project. Everything.

Right now, there’s a Mac mini holding the shared repo with a MacBook Pro and a MacBook Air pushing and pulling to it.

  1. Set up SSH keys the laptops and server (I like GitHub’s instructions)
  2. Set up the repo on the server
    mkdir active-projects.git
    cd active-projects.git
    git --bare init
  3. set up a repo on both client macs
    cd ~/Documents/Projects
    git init
    git add .
    git commit -a -m "initial commit"
  4. create the active-projects.sh backup script in your ~/Documents directory #!/bin/sh
    DATE=`date -u`
    cd /Users/YOUR-USER-NAME/Documents/Projects
    git pull origin master
    git add .
    git commit -a -m "Active Project Sync - $DATE"
    git push origin master
  5. make active-projects.sh executable chmod +x project-backup.sh
  6. Make the active-projects-backup.plist file for launchd

    < ?xml version="1.0" encoding="UTF-8"?>
    < !DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN"
    "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <dict>
    <key>Label</key>
    <string>YOURNAME.rsync.backup</string>
    <key>LowPriorityIO</key>
    <true />
    <key>Program</key>
    <string>/Users/YOUR-USER-NAME/Documents/active-projects.sh</string>
    <key>ProgramArguments</key>
    <array>
    <string>active-projects.sh</string>
    </array>
    <key>RunAtLoad</key>
    <true />
    <key>QueueDirectories</key>
    <array>
    <string>/Users/YOUR-USER-NAME/Documents/Projects</string>
    </array>
    <key>WorkingDirectory</key>
    <array>
    <string>/Users/YOUR-USER-NAME/Documents/Projects</string>
    </array>
    </dict>
  7. save the active-projects-backup.plist file to ~/Library/LaunchAgents and load it up launchctl load ~/Library/LaunchAgents/active-projects-backup.plist
  8. Now, whenever a change is made in your ~/Documents/Projects – it will be automatically committed to the git repo and propagated to all computers connected to that repo. Like magic.

Thanks to culturedcode’s instructions for syncing Things with git & Launchd.

How to Kill a Frozen Parallels Virtual Machine

Multiple projects have me using Windows more than I’m accustomed to, so I picked up a copy of Parallels and Windows Vista and loaded them up on the MacBook Pro.

My relationship with the MacBook Pro has been trying these past few weeks. Like an aged sitcom introducing a new character – this recent addition isn’t helping.

I found myself with a frozen Vista shutdown this afternoon, and for my own future reference here’s how to terminate a frozen Parallels Virtual Machine (from Parallels knowledgebase)


ps auxwww | grep prl

And grab the processes UUID of the process containing prl_vm_app and curly brackets (it’ll be obvious – especially if you’re only running one virtual machine)

Then

sudo kill [The VM's UUID]

Easy.

Asks: Should We Buy a HD TiVo?

Our Series2 TiVo is on its last legs. With each passing day, its over-the-air recordings (we’re a no cable household) are more and more unwatchable, while digital over-the-air recordings are getting more stable. But seriously, TV without TiVo is like email without a spam filter.

Back in January, I replaced our DVD player w/ a Mac Mini. Since then, none of TiVo’s non-TV features have been used (music, podcast, etc) – simply because TiVo’s UI was too much of a PITA compared to Front Row & OS X.

The Mini’s secondary job is to play Netflix disks and does so with far fewer curse words1 than the dedicated DVD player it replaced.

In a world where; there’s a computer already plugged into our TV, NBC is back on iTunes, Hulu.com gaining traction, and the Roku box, dropping $200+ on a HD TiVo for over-the-air programming seems questionable.

What would you do?

UPDATE 12 JUNE 2009
The Tivo HD is now on order. Lifetime service.

1. I won’t get into my complaints about iTunes and Front Row here – they deserve their own post. 😉

Planting Flying Meat Acorn Near Photoshop Elements Grave

Like most professional graphic designers, my career was measured in versions of Adobe Photoshop.

v2.5: I decided I wanted to be a graphic designer. The dad of a high school classmate was one. I went to talk with him about it. He worked out of his basement home office with a view of the lake, a room full of Apple gear, and telecommuted to Minneapolis. He launched Photoshop and showed me some of the crazy stuff he was doing with it. I left stunned.

v3: Spent far too long on the Photoshop Classroom-in-a-book tutorial as part of my least favorite college course – something about printing methods and preparing images for press.

v4: The first version I used in a professional environment auch auf Deutsche.

v5: Editable type, Multiple Undo. Those two features are reason enough to fall in love with it.

v6: Like Word 6, and Star Wars 2 – all the hope, promise, performance, and love of the previous version was an unsaved memory. This is the last full version I used and the beginning of my strained relationship with Adobe.

In 2002, my new digital camera shipped with Photoshop Elements v2 and then a couple years later, my scanner shipped with Elements v3. Aside from a few small omissions (inverse selection, select color range, etc), Elements was all the image editing horsepower I needed. It was my go to app, until I switched to the MacBook.

Elements never launched on the MacBook. It’d just bounce and bounce and bounce and bounce until I forgot why I opened it and Force Quit (a pretty good indicator of my image editing workload over the past 2 years).

After 15 years, my relationship with Photoshop officially ended today.

A while back, I downloaded Flying Meat’s Acorn and hadn’t opened it until this afternoon. While Elements was bouncing, I opened Acorn to take a closer look at a client website mockup. Instinct kicked in and I was pushing pixels, using the same key commands I remembered from Photoshop.

Before I hit Save the first time, I bought a license.

In addition to costing less than 1/10th the price of Photoshop, it was the most integrated web/desktop licensing experience I’ve seen. After completing the purchase online, a single click in the browser applied the license to the still running desktop app. Seamless. Fast. Amazing.

I’m one step closer to being Adobe-free and happier than ever.

Leopard Installs Not Always Problem Free

After the customary until-you-cant-take-it-anymore 30-minute waiting period, I installed 10.5 Leopard on the Mac mini that serves my local network.

The mini isn’t my primary work machine, and it’s regular duties are fairly straight forward: transport backups, be invisible.

As such, the upgrade was quick and straight-forward (but I wasn’t really paying attention, I was working while all this was going on). After restarting the it was back. I poked around a little, started investigating CalendarServer and decided that the spit-and-polish on the UI would in fact make me more productive1 so I started the upgrade on my primary workstation.

This was a bad idea.

After the intial upgrade, one of the handful of third-party PreferencePanes or Startup Items sent the Finder into an infinite loop of crash and relaunch and crash and relaunch repeat until hard restart.

Two re-upgrades later, I determined it wasn’t bad installs, and firewire-moded into trash anything that may be interfering with the Startup process2.

While this process gave me Leopard, I’m still recovering days later. Not yet back to where I was in Tiger.

The archive+install ate my /local directory, so I needed to re-install svn and mysql (thankfully I left myself a reminder). The ruby mysql gem needed to be recompiled and I’v lost my VPN configuration. All of which were running just fine previously.

There are 3 more Macs in the house scheduled for upgrades. None of which I’m prepared to dedicate the same amount of time on as my primary machine. Yes, I’m gun shy.

1. There’s a Jobs’ Reality Distortion Field for you.
2. M-Audio, Wacom, and Tivo are all suspects.

MySQL on OS X Reinstall Reminders

First off, if you can avoid reinstalling MySQL on OS X – by all means do. Whatever the reason is that you want to do a reinstall, it’s not a good one1. Just buck up and work around whatever issue you have. It’s not as bad as what follows.

Let’s say you decide to reinstall anyway.

Since there’s no easy way to uninstall, you go on a crazy rabbit hunt – including showing all the hidden files2 – through your system to eradicate all instances of MySQL and any dbs (bu-bye data). Then, you downloaded and installed a fresh binary from dev.mysql.com. Now, there’s no reason to do 3 or 4 system restarts, but you haven’t listened to me this far.

Weeee.

Now, I’m pretty sure that if you go back into your Rails app and run rake db:migrate you’ll get the following:
dyld: Library not loaded: /usr/local/mysql/lib/mysql/libmysqlclient.15.dylib

Thank Peter Morris for reminding you to run:
sudo install_name_tool -change /usr/local/mysql/lib/mysql/libmysqlclient.15.dylib /usr/local/mysql/lib/libmysqlclient.15.dylib /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7/lib/mysql.bundle

Hey, not so fast, make sure you set up the same root pass you had before:
/usr/local/mysql/bin/mysqladmin -u root password new_password_here

1. My reason – I was intermittently getting "Lost connection to MySQL server during query" when running rake test. It seems better now. There had to be
2. defaults write com.apple.finder AppleShowAllFiles ON

How To Install MacPorts, Apache2, Rails, MySql, Mongrel, and Subversion on an Intel Mac

Now that I’m just about ready to deploy my first rails app, I thought I’d get the deployment environment set up rock solid on both the production and the development machines (one Mac Mini and one MacBookPro).

Like many other tutorials on this same subject, your mileage may vary. In fact I’m writing this now, because mine did. After stalling out in many of the tutorials all different places, this is what worked for me.

  1. Download and install MacPorts (used to be DarwinPorts)
  2. Open up a terminal and type:
    sudo port selfupdate
    making sure everything is the way it should be.
    If you’re like me, you get port: command not found in return.
  3. I fixed this by opening up .bash_profile in a text editor (Textmate: mate ~/.bash_profile) and adding the line
    export PATH=/opt/local/bin:$PATH
  4. Next download and install MySQL5
    I grabbed the binary from the bottom of the MySQL 5 download page. It comes with a System Preference Pane and checkbox for auto-startup. I’m using CocoaSQL for admin.
  5. Change the MySQL5 root password

    /opt/local/lib/mysql5/bin/mysqladmin -u root password 'new-password'
    /opt/local/lib/mysql5/bin/mysqladmin -u root -h [HOSTNAME] password 'new-password'
  6. Next load up the Apache2 package
    sudo port install apache2
    (this takes a while)
  7. sudo launchctl load -w /Library/LaunchDaemons/org.macports.apache2.plist to launch Apache2 on startup. I’ve disabled Apple’s default Web Sharing in the System Preferences.
  8. Create an initial http.conf file
    cd /opt/local/apache2/conf
    sudo cp httpd.conf.sample httpd.conf
  9. Start up Apache2
    sudo /opt/local/apache2/bin/apachectl -k start
  10. Load up http://localhost. It should say “It works!”

  11. sudo port install fcgi
    sudo port install lighttpd +ssl
    sudo port install mod_fastcgi
  12. Next load up Subversion package with the mod_dav_svn for Apache2
    sudo port install subversion +mod_dav_svn +tools
  13. Next load up Ruby, RubyGems, Termios, RB-MySQL5 Bridge, and ImageMagick Packages
    sudo port install ruby
    sudo port install rb-rubygems
    sudo port install rb-termios
    sudo port install rb-fcgi
    sudo port install rb-mysql (I had some errors on this one.)
    sudo port install imagemagick
  14. Install a bunch of useful gems, like rails and capistrano.

    sudo gem install --include-dependencies rake
    sudo gem install --include-dependencies rails
    sudo gem install --include-dependencies termios
    sudo gem install --include-dependencies capistrano


    sudo gem install daemons gem_plugin mongrel mongrel_cluster --include-dependencies
    sudo gem install --include-dependencies mongrel
    sudo gem install --include-dependencies mongrel_cluster


    sudo gem install mysql --
    --with-mysql-dir=/usr/local/mysql
    --with-mysql-include=/usr/local/mysql/include/
    --with-mysql-lib=/usr/local/mysql/lib/
    --with-mysql-config=/usr/local/mysql/bin/mysql_config

    (thanks to d. robert adams for the last bit)
  15. Create a rails app
    rails testapp
  16. Connect the rails app to mongrel

    cd /RAILS/ROOT/OF/TESTAPP
    mongrel_rails cluster::configure -e development -p 8000 -a 127.0.0.1 -N3 -c /RAILS/ROOT/OF/TESTAPP

How To Set Up Subversion, svnX, for TextDrive on OS X

I’m walking through the latest beta version of Agile Web Development with Rails 2nd Edition, specifically the new bits on deploying Rails apps. Capistrano – the preferred and recommended deployment utility. Thing is – Capistrano hinges on Subversion. Not something covered in AWDwR or appropriate to be covered. There’s plenty of other books on the subject.

Though, that left me stuck on how to set up a Subversion repository and access it.

I do my hosting at TextDrive, and in the interest of making this process just a hair simpler, I set up my svn repository there. Here’s how I did it:

  1. Set up repository on TextDrive domain in webmin.[your-server].textdrive.com:80.
    There’s a ‘subversion repository’ menu option right when you sign-in.
  2. Assign svn access rights to a TextDrive domain user.
    It’s a radio button and select list selection in their profile.
  3. Install Subversion on your local Mac – I did via macports
  4. Install svnX and in svnX preferences, confirm your path to svn in svnX (macports uses /opt/local/bin)
  5. Import your project into the TextDrive repository
    svn import /Users/your/local/path/to/the/app http://[your-domain]/svn/[repository-name]/ -m 'initial import' --username=[your-svn-account-name]
  6. Connect svnX to the repository
    Path: http://[your-domain]/svn/[your-repository-name]
    User: [your-svn-user-name]
    Pass: [your-svn-user-name-pass]
  7. Check out your project back on to your mac by clicking the ‘svn checkoutexport‘ button and picking a directory to put it (not your original directory). I created an /svn directory within my main project directory.
  8. Now, if everything worked, double-clicking the repository should load it up in a new window.
  9. I’ve got a weird proxy between me and the internet right now, so I’ll make sure the commits work tomorrow. UPDATE: Yep, it works. Yah!

Small MacBook Pro Joys

After living with a 17″ MacBook Pro for a couple weeks, there’s a couple things I’ve been pleasantly surprised with:

  1. MagSafe magnetic power connector
    Connecting the power cord takes far less precise alignment than before. Get the connector near the socket and it’s magnetically pulled in. Small joys.
  2. Horizontal scrolling trackpad
    No, I probably won’t be complaining about horizontal scrolling anymore…probably be encouraging it because it’s just so dang much fun.