Symphonious

Living in a state of accord.

Mounting a Time Capsule Drive In Linux

Lots of articles out there that have almost the right solution here but nearly all of them miss one critical component, so for my future sanity, here’s what works for me:

sudo mount.cifs //timecapsule.local/Data/ /mnt/directory/ -o “pass=password,sec=ntlm”

If you don’t have zeroconf working in your Linux install you’ll have to use the time capsule’s IP instead of it’s .local name.  The “Data” part is the name of the disk you want to mount as shown in Airport Utility (make sure you escape any spaces with backslash.

Critically, you need to insist on NTLM authentication using the sec=ntlm option.  You may additionally want to specify file_mode, dir_mode and other standard mount options.

If you are using disk or device password based security you only need to specify the password, the username is ignored. However, if you’re using account based security you’ll need to also supply a user= option to specify the correct username.

Combining Output of Multiple Bash Commands Into One Line

I wanted to create a CSV file showing the number of JUnit tests in our codebase vs the number of Spock tests over time. I can count the number of tests, along with the revision pretty easily with:

git svn find-rev HEAD
find src/test -name '*Test.java' | wc -l
find src/test -name '*Spec.groovy' | wc -l

But that outputs the results on three separate lines and I really want them on one line with some separator (comma, space or tab). The simplest way to achieve that is:

echo "$(git svn find-rev HEAD), $(find src/test -name '*Test.java' | wc -l), $(find src/test -name '*Spec.groovy' | wc -l)"

It’s also very handy to remember that echo has a -n option which omits the trailing new line, so:

echo -n 'Revision: ' && git svn find-rev HEAD

outputs:

Revision: 55450

Why Are My JUnit Tests Running So Slow?

This is mostly a note to myself, but often when I setup a new Linux install, I find that JUnit tests run significantly slower than usual. The CPU is nearly entirely idle and there’s almost no IO-wait making it hard to work out what’s going on.

The problem is that JUnit (or something in our tests or test runner) is doing a DNS lookup on the machine’s hostname. That lookup should be really fast, but if you’re connected to a VPN it may search the remote DNS server which takes time and makes the tests take much longer than they should.

The solution is to make sure your hostname is in /etc/hosts pointing to 127.0.0.1 (and that /etc/hosts is searched first but it usually is). Then the lookup is lightning fast and the tests start maxing out the CPU like they should.

Uglify/Uglify2, Rickshaw, Requirejs and Minification

If you have:

  • A javascript project using require.js
  • Which is optimised using r.js
  • Includes Rickshaw or any other library that uses the prototype class system

Then you are very likely here because you’re trying to enable JavaScript optimization (minification) and finding that suddenly stuff breaks.

The problem is that the prototype class system allows overriding methods to call the original method by adding a $super as the first parameter to the function. From the prototype docs:

When you override a method in a subclass, but still want to be able to call the original method, you will need a reference to it. You can obtain that reference by defining those methods with an extra argument in the front: $super. Prototype will detect this and make the overridden method available to you through that argument. But to the outside world, the Pirate#say method still expects a single argument. Keep this in mind.

The problem is, the first parameter has to be called $super but enabling optimization causes it to be renamed to something shorter, thus breaking prototype’s class system.

The solution, which is easy to find on the internet is to exclude the $super parameter from renaming. What’s not as obvious to find is the exact way to do that since it depends on which optimization engine you’re using.

For uglify, you’re build.js should look a bit like:

({
  ...
  optimize: 'uglify',
  uglify: {
    except: ["$super"]
  },
  ...
})

 For uglify2, you’ll want:

({
  ...
  optimize: 'uglify2',
  uglify2: {
    mangle: {
      except: ["$super"]
    }
  },
  ...
})

 I’d highly recommend using uglify2 and then also enabling source maps with:

({
  ...
  generateSourceMaps: true,
  preserveLicenseComments: false,
  optimize: 'uglify2',
  uglify2: {
    mangle: {
      except: ["$super"]
    }
  }
  ...
})

The key part of getting configuration working for the optimizer is to get the magical nesting level right – lots of places point you towards the “except” config you need, but most put it in the wrong place so it has no effect.