require most commands to succeed; cleanup on install failure

add `run!` method which raises if command does not succeed

now we use `run!` when the command we are running must succeed for
things to move forward. this should help produce clearer error messages
in failure scenarios.