Making Symlinks to a Directory Work in Dreamweaver CS5.5 on Snow Leopard: Hard Link Style

NOTE: This post is about symlinks and hardlinks as they relate to Adobe Dreamweaver CS 5,5 running on Mac OS X 10.6+ but also applies to very earlier version of Dreamweaver. ALSO NOTE: This technique totally works but be super careful. There is a reason links are treated in special way.

They work in every other IDE, but symlinks do not work in Dreamweaver. I'm sure there must be a reason, but I almost don't care. I want them to work so I can deal with directory structures that use them.

Scroll down to the SOLUTION to bypass all my comentary.

In general, symlinks can result in circular dependencies that can really mess things up but then again, programmers write infinite loops sometimes and seem to resolve them, so what gives Dreamweaver?

I came across this issue when researching sencha touch and making my way through a webinar. The presenter recommended a symlink for linking to the main API and it clicked - how perfect. So I stopped and configured my directory structure the same way and then looked at it in Dreamweaver :(

Dreamweaver hated this and instead of showing me the directory's content, it told me it couldn't find an editor for the file. Ugh.

Hard Linking vs. Symlinking / Shortcuts

A symlink is like a shortcut in Windows without the terribleness of Windows. Windows adds .lnk to the shortcut and doing so prevents the usefulness of treating the shortcut as if it were the actual file or directory.

To create a symlink, run a command like the one below:

$> ln -s /Users/scoobydoo/lib/apache-commons/commons-lang-1.2-4.jar commons-lang.jar

This creates a symlink (notice the -s) to commons-lang-1.2-4.jar named commons-lang.jar. This allows me to swap out different versions of commons-lang yet always refer to it as commons-lang.jar. For the record, that's probably a terrible idea, but you get my point.

Dreamweaver doesn't like this. In fact, it's quite hillarious what Dreamweaver actually does. If you open this link in Dreamweaver, it actually shows you - in a text file - the path to the linked file. Well, that is just cute. Useless, but cute.

SOLUTION

Hardlinks: A hardlink isn't really a shortcut but rather a direct link to a file's actual inode. Generally speaking hardlinks are not possible to directories, but Mac OSX allows it. Unfortunately it provides no means to actually make the link...big sad face.

With a hardlink, if you delete the "original" file, any hardlinks that were created still point to the inode, which means that the location in memory can still be accessed.  That's because deleting a file really translates to "unlinking a file." This is referred to as "awesome."

Let's try it out:

$> mkdir t

$> cd t

$> mkdir lib

$> touch original.txt

$> cd lib

$> ln ../original.txt copy.txt

$> cd ..

$> rm original.txt

$> cf lib

$> ls

You'll still see copy.txt because copy.txt does not link to original.txt, it "points" to the inode that original.txt pointed to. Typically, this only works with files and not directories.

Dreamweaver is fine with hardlinks because hardlinks in a way, aren't links, they are just files that point the same location as another filename.

The problem we are left with is how can we create a hardlink to a directory so that Dreamweaver won't flip out?

Easy, write a tiny C program. For real.

Greg Miller wrote pretty cool article Exploring Leopard with DTrace: How to use DTrace for debugging and exploration that includes the code I'm about to show you.

Copy/paste this code into a text editor and save it as hard-linkd.c (or something else).

#include <unistd.h>
#include <stdio.h>
int
main(int argc, char *argv[])
{
   if (argc != 3)
      return 1;
   int ret = link(argv[1], argv[2]);
   if (ret != 0)
      perror("link");
   return ret;
}

To compile it:

$> gcc -o hard-linkd hard-linkd.c -Wall
$> cp hard-linkd /usr/local/bin

Now you can use hard-linkd to hard link to a directory and make Dreamweaver happy.

$> hard-linkd src-directory dest-directory

I did this. It works. All is right again.