Wednesday, 8 July 2015

Commandline VLC with global hotkeys (using QuickSilver and Karabiner)

TL;DR;

Create a trigger in QuickSilver that pipes the word 'pause' to the rcold interface of VLC.

Details

Imagine having a Mac and not wanting to use iTunes.  Imagine hating iTunes so much that you'd rather use an interface that looks like this:
Unlikely, I realise, but that's where I'm at.  I really don't need or want a complicated media center [sic] application that puts the kettle on while it tries to download album art, so I use the VLC NCurses interface.  It's far from perfect, but I really, really hate iTunes, so this it's an OK option.

However, what I do miss is having a single key to pause music play back, whether the player has focus or not i.e. what I used to have with the F8/play-pause in iTunes. It turns out there are ways to achieve this.

First up, this is how I launch VLC

Which basically says, launch VLC using the NCurses interface, starting in the following browse directory, also use an extra interface, Old Remote Control and while you're at it create a socket to communicate with it called /tmp/vlc.sock. Which means that I now have two interfaces controlling VLC: NCurses, which I use to browse for music from my music library, and oldrc, which I use to be able to stop and start playback using a global hotkey.

As I mainly use my laptop keyboard I'm missing a few function keys that would be really handy here.  Enter Karabiner which allows me to map Fn + SPACE to F13, with something like this in the private.xml

The final step is to create a hotkey using QuickSilver which is done in the Triggers section of the QuickSilver Configuration. Click the '+' symbol and select 'HotKey'.  Paste the following
into the 'Select an item' field and set the action to 'Run Command in Shell'.

Job done, every time I hit 'Fn + SPACE' I send the command 'pause' to that socket.  On the other end of that socket the VLC rc interface understands that and toggles pause/play. Unfortunately there is a minor irritation in that the rc interface produces output like this:
status change: ( play state: 3 )
pause: returned 0 (no error)
status change: ( pause state: 3 ): Pause

that is then dumped out onto the NCurses console space (which looks terrible).  A simple solution is to hit 'Ctrl + l' to clear the UI.  Ideally I'd stop this happening at all, but I haven't figured out how.  Yet.

Monday, 6 July 2015

Parallels, Ubuntu, Emacs - weird Meta key behaviour

I'd been tearing my hair out over an issue I was having with Emacs (24.3.1) on an Ubuntu (14.04) VM running under Parallels (10.1.2) where I had to hold down the Meta key and hit the character key twice in order to make it work i.e. in order to get Emacs to respond to M-x I had to type M-x-x, or for M-w I had to type M-w-w.  Whilst this wasn't the end of the world, it was annoying as I want a consistent experience across environments when using Emacs.

I'm not sure where the problem stemmed from, but I do use Karabiner to remap my OSX modifier keys, so that I have Command, Control,  Option, Space, Option, Control, as that way I have two sets of Control and Meta keys, one under each hand.  Anyway, after spending too long trying to do more and more convoluted remapping in Karabiner to work around the problem (and failing) I discovered a far simpler solution in Parallels itself.

Opening up the configuration for the VM (Actions > Configure ...) then selecting the 'Hardware' tab, then 'Mouse & Keyboard' and clicking 'Shortcuts' presents you with a list of keyboard mappings (e.g. Command+x -> Ctrl+x).  Clicking the '+' symbol allows you to add further mappings and if you select 'Alt' in the 'From' row and 'Alt' in the 'To' row this maps 'Option' to 'Alt' and voila the Meta key works as expected in Emacs in the Ubuntu VM.

Sunday, 22 March 2015

Overriding dependencies with Castle Windsor in SpecFlow tests

At DrDoctor we have a reasonable set of Spec tests using SpecFlow.  These tests tend to be a lot more involved than our unit tests as they always exercise most (close to all) of an application - and sometimes even multiple applications that make up portions of the entire system.  We don't have hard and fast rules about how much of the system a set of specs should cover, but they tend to end up as fairly significant integration tests, almost always hitting the database for example.

As these specs tend to be written prior to the implementation* we often start with dependencies mocked out and as we implement the system under test move to real objects.  For instance, we might start with a mock IGetThatObjectYouNeed data access class that ends up being implemented as part of the functionality we are building.

However, once the functionality is built, we finish in a situation where the component we have been working on has its dependencies composed using an IoC container (Castle Windsor) and the specs build up the required dependency graph manually.  While that's not catastrophic, we really like our specs because they show up problems with an application in a way that unit tests don't, so knowing that the application is composed in the same way in the specs and in the real world also helps us sleep easy.  It's kind of like the difference between knowing that all the parts of a car work and knowing that all the parts work and they've been put together the right way.

A fairly simple way to do this is to use Castle's fluent registration to call your application's installer e.g.
var container = new WindsorContainer().Install(new YourApplication.Installers.YourInstaller());
var sut = container.Resolve<ApplicationEntryPoint>();

A problem with this though is that it may use every concrete implementation that your application requires, which might not be what you want for tests that are run many times a day.  For instance if your application sends SMSes via a 3rd party service, you probably don't want your automated tests using that.

In order to avoid this, you can have multiple installers in Windsor and then only call the installers you need.  We have a separate BusInstaller for exactly this reason, so that we can use a different implementation in our tests.  Having said that you probably want your installers separated out into areas that make sense for your application, not that make sense for your specs.  Also, you probably don't want to have to change your installers because of modifications to your specs.

In order to avoid using specific implementations that are registered in an installer that you don't want to modify, you can use another feature of Castle Windsor that allows you to register multiple implementations of a type and declare one as default (http://docs.castleproject.org/Windsor.Registering-components-one-by-one.ashx)

Thus you might have an installer that looks something like this:
public class MyComponentInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {
        container.Register(
            Component.For<IDoSomethingYouCareAbout>().ImplementedBy<SpecificImplementation>(),
            Component.For<IStuffRepository>().ImplementedBy<StuffRepository>(),
            Component.For<IHitAnExternalResource>().ImplementedBy<ServiceYouDoNotWantToHit>(), // don't want this to be used in the specs
            Component.For<IAmAlsoUsefulToTest>().ImplementedBy<AnotherSpecificImplementation>(),
            Component.For<IAmAnotherRepository>().ImplementedBy<AnotherRepository>(),
            Component.For<ApplicationEntryPoint>());
    }
}

Then in your spec wherever you set up your system under test:

var container = new WindsorContainer().Install(new MyApplication.MyComponentInstaller());
container.Register(Component.For<IHitAnExternalResource>().UsingFactoryMethod(Mock.Of<IHitAnExternalResource>).IsDefault());
systemUnderTest = container.Resolve<ApplicationEntryPoint>();

The second line, using 'IsDefault()', means that rather than having to remove the 'ServiceYouDoNotWantToHit' from the container, we override it with our mock (we're using MOQ, if you're wondering about the syntax), by setting it as the default implementation that Castle returns.

In this way you can avoid whichever concrete implementations you want, but still have quite a high level of confidence that your actual application is composed correctly.


*we're not purist BDDers, but it's a style that works well for us a lot of the time.

Monday, 10 November 2014

Launching Windows applications in Parallels from OSX without UAC prompts

TL;DR; 

Use a scheduled task to avoid UAC prompts in Windows; create a shortcut to the scheduled task; use a shell script to tell Parallels to use Windows Explorer to open the shortcut.

Details ... 

As a .Net developer using an OSX machine I'm a big fan of Parallels Desktop. I'm also a big fan of not taking my hands off the keyboard as I find that using a trackpad or mouse gives me some pain in the back of my hand and wrist. One way I help myself with this is by not using the mouse to launch applications. In both Windows and OSX this is relatively straightforward, but in Windows two of the applications I use a lot I really need to use with admin privileges (the console/command line and Visual Studio). The best way I've found to avoid doing extra mouse work (or just extra key presses) is to use a Scheduled Task in Windows and create a shortcut to it. Details of how to do this here: http://www.7tutorials.com/use-task-scheduler-launch-programs-without-uac-prompts

Great, so now I don't have to say "yes, please let me run this application as an administrator" every time I want to use Visual Studio. But I want more. I want a single way of launching applications on Windows and OSX.

Step forward QuickSilver - free and awesome. It used to be the case that I could just double-click on my Windows Shortcut (.lnk) files to launch the applications in OSX, so I kept them in my Quick Silver catalog and just used QuickSilver in the normal way, but recently this stopped working.

Double clicking on the shortcut in Windows still worked, double-clicking or right-clicking and selecting 'Open with' either 'Parallels Link' or 'Windows Explorer' didn't work either.

I never worked out what had changed (Windows? Parallels? Sun spot activity?) but I did find a solution. I now have a bunch of shell-scripts that look like this:
Which means that I can easily launch the applications I use most, without UAC prompts, from OSX.

Saturday, 27 September 2014

OSX, .NET vNext and file paths

I've been playing around with .Net vNext on my OSX laptop and hit a stupid issue with file paths that might possibly trip someone else up.  I was trying to get a .NET program to launch another application and open a file (VLC and an mp3). I had code that looked like this:
var filePath = "/Volumes/StorageHD/Audio/iTunes Music/Air/Talkie Walkie/01 Venus.mp3";
var p = new Process();
p.StartInfo.FileName = "/Applications/VLC.app/Contents/MacOS/VLC";
p.StartInfo.Arguments= filePath;
p.Start();
Console.ReadKey();

This code launches VLC, but each space in the file path is parsed as a new file name, so VLC attempts (and fails) to play iTunes, Talkie, Walkie, 01 and Venus.mp3.

My first attempt to fix this was to escape the file path as a Unix file path i.e.
"/Volumes/StorageHD/Audio/iTunes\ Music/Air/Talkie\ Walkie/01\ Venus.mp3"
which is what I'd use if I were trying to do something similar from the shell:
$ vlc /Volumes/StorageHD/Audio/iTunes\ Music/Air/Talkie\ Walkie/01\ Venus.mp3

This was not the correct option ;) - my little console application threw a lot of stack-tracey goodness, but the main point was "Unrecognized escape sequence".

Instead I needed to escape the path as I would on windows, with the path with spaces in wrapped in double quotes:

var filePath = "\"/Volumes/StorageHD/Audio/iTunes Music/Air/Talkie Walkie/01 Venus.mp3\"";
Notice the escape character ("\") before the wrapping quote.
The final full code is available as a gist https://gist.github.com/StephenFriend/593aa94366cd4733be46

Monday, 25 August 2014

Scripting Parallels VM backup

In an attempt to automate all the things, I've scripted the backup of my Parallels VM for disaster recovery.  Ultimately I plan on using something like this in conjunction with Launchd, but for now the script is available as a gist:
https://gist.github.com/StephenFriend/69477732bbb1423942f4

Hopefully someone else will find it useful.

Saturday, 21 June 2014

Lean and Agile - what does that actually mean in practice at DrDoctor?

At DrDoctor there is a very strong belief that the business should be Lean (note the capital 'L'), so we analyse data on how our services are used in order to guide product development.  An important aspect of that is that we need to get features out there in order to see how they're used, which fits neatly with a Scrum-based, Agile approach.  We do favour working software over comprehensive documentation and we aim to deliver that working software every sprint (i.e. every two weeks).  Worse than that, following lean principles, we don't just value responding to change over following a plan we acknowledging that a core strength is our ability to change our plans.  Yes there is a vision, but no, I don't pretend to know for certain what I'll be working on in two months' time.

What does this mean in practice?  At a very high level, it means that we need to be able to release features easily.  Or put another way, having a 'release sprint' (which I've seen in lots of places) means we've failed.  We haven't always succeeded in this, but we're getting there and we are now at the stage where we have decent CI and automated deployment, we can ...
  • Push changes to our central code repository
  • Which triggers a build on our build server
  • Which runs our test suite (unit tests, integration tests that exercise the DB and bigger 'Spec' tests that lean on even more infrastructure)
  • We're notified if the build passes or fails
  • With 5 button clicks we can deploy the build to our 'smoke test' environment where we can do a full end-to-end test - our product owners get to run through the feature they've asked for
  • 5 more button clicks and we've deployed to production
To achieve all of this, we use Git, BitBucket, TeamCity, NUnit, SpecFlow, HipChat and Octopus Deploy and I'll write a post on some of the technical details of how that's set up.

However, the main point isn't about the tools, it's about the mindset.  Lots of companies talk about Lean and Agile but don't deliver (if you've ever sat through a 30 minute "stand-up", you know what I'm talking about), but at DrDoctor the value of delivering software rapidly is understood, which translates into investing time into making delivery easy.  There is a lot more to do, but the whole company agrees that we don't say a story is delivered unless the code is running somewhere.