GFX::Monk Home

Posts tagged: "programming" - page 8

rvm: Manage Your Rubies With an Ill-Managed Manager

rvm is a tool for maintaining multiple versions of ruby, as well as maintaining project-specific sets of gem dependencies. When I first learnt about it this week it sounded like a very useful tool, although it’s unfortunate that gems are so awkward to manage that it should be necessary in the first place.

Yesterday my first task was to update rspec. Which in turn required an update to rubygems before it would install. But who manages rubygems? It could be rvm, or rubygems itself, or apt, or even maybe bundler.

I looked through the documentation, and the most appropriate answer seemed to be that rvm should manage rubygems. I quote from the documentation:

rvm action [interpreter] [flags] [options]

where update is an action, and one of the flags is --rubygems:

--rubygems    - with update, updates rubygems for selected ruby

So I diligently typed

rvm update --rubygems

And what did rvm do? It proceeded to attempt to update itself, instead of rubygems. If you want to upgrade rubygems, you’re supposed to type:

rvm --rubygems update

(note that this is incorrect according to the above documentation, but is how I eventually coerced it into upgrading rubygems (this bug has since been fixed))

The accidental upgrade might have been okay, if its upgrade process were anything but Completely Insane. It goes thusly:

  • download a file from an unsecured HTTP location
  • without verifying any sort of checksum, signature or even HTTP status code, pipe the output directly into a bash shell
  • this script clones a github repository, and proceeds to install the absolute latest revision, whatever that might be

Hilarity ensues. I got a bash syntax error, but evidently not early enough in the process to stop rvm from destroying itself, requiring me to delete everything related to it and install from scratch.

Security? ignored.

Sanity checking? skipped.

Dependencies? get them yourself.

Update management? The website says “make sure you run this command frequently”.

I don’t know that I want such a tool trying to manage my dependencies, thank you very much…

The most painful thing, of course, is that it’s yet another buggy, language-specific implementation of the principals that zero-install does so much better (and simpler). If you don’t have global state, suddenly it’s really not that hard to keep things from interfering with each other.

Oh, and did I mention how rvm integrates with your shell, so that when you cd into a project directory, it automatically sets up your ruby version and gems? Except that when you open a new shell in the same location, you have to cd out of your project directory and then back in or else you’ll see the system version of ruby and your gems, and things will be broken in very odd ways. Splendid.

mocktest 0.5

Over the holidays, I’ve finally had the time to rewrite my mocking library for python, mocktest.

The original version had what turned out to be a confusing distinction between mock anchdors, mock wrappers and raw mocks. You should no longer need to know about that distinction when using mocktest 0.5, as it takes a more traditional approach using global methods like when() and expect() to differentiate between setting up the mock object and actually using it.

Please check out the brand-new documentation if you’re looking into a mocking library for python - it works with the standard unittest infrastructure, so it’ll work just fine with your favourite test runner (nosetests, surely….)

Speaking of documentation, this is my first time using sphinx. I am very impressed, and really quite keen to properly document a lot of my other code, when I get the time.

Jekyll Improvements

I’ve been using Jekyll to generate this blog for over a year now. It’s great. I don’t have to worry about security exploits, or replicating the arcane installation of PHP and associated libraries that my hosting provider happens to have installed. And it’s a blog. I shouldn’t need a CMS for what amounts to very static content.

The good thing about jekyll is that it’s easily hackable if it doesn’t do exactly what you want. The sucky thing is that over 400 people have done just that, making it incredibly difficult to get the right combination of features that actually work together. The franken-jekyll running this blog for the past year was a combination of mojombo’s master, mikewest’s tag_index and master, as well as some of my own fixes for bugs I came across or features I wanted.

So when I eventually got around to merging in new updates, things fell in a heap. Thankfully, in the past year, extending jekyll has become a whole lot cleaner. There is now jekyll_ext, which allows you to add features without changing the jekyll code itself. All of my original modifications have now either been fixed, or implemented in jekyll_ext.

So now I have, thanks to an upgraded markdown engine and some jekyll_ext plugins:

If you notice any post’s formatting is a bit off now due to the upgraded markdown engine, please leave a comment (or shoot me an email) and I’ll fix it up.

  1. Which I would never use spuriously. Except for this post, perhaps. 

Background Make for GVim

I haven’t used vim’s :make command much, mostly because I don’t often use compiled languages, and setting :errorformat correctly for nonstandard programs is a dark, dark art.

Recently I got :make and :errorformat working well enough with sbt, so the only remaining problem is that vim completely locks up while the make task is going. That really sucks, as sbt can take a good 20 seconds to even just compile and install an android app.

Enter background-make (for GVim only, sorry terminal freaks). It’s not perfect, but for non-pathological makeprg settings it seems to work very reliably. It adds a :Make command that does exactly what :make does, except it does it in the background.

And it tries its very best to not disrupt you - by default, it’ll send a system notification the moment that make finishes. But it will then wait until you are in either insert or normal mode, at which point it’ll take the opportunity to pop up the error window and restore your cursor position / mode. (It has to wait for normal or insert mode because these are the only ones I can figure out how to restore ;))

It’s implemented by firing off a background make process with the current vim instance’s v:servername so that it knows where to send the results (thus the GVim requirement). Once complete, it uses --remote-send to tell the originating vim instance to open the now-complete errorfile. Oh, and it also requires a python-enabled vim, because vimscript makes me wince.

What The Scala?

Here’s a puzzler for scala fans: What will be the console output of the following program:

def foo1() {
	println("> foo1()")
	return "foo1"
}

def foo2() {
	println("> foo2()")
	"foo2"
}

def foo3() = {
	println("> foo3()")
	"foo3"
}

def foo4():String {
	println("> foo4()")
	"foo4"
}

println(foo1())
println("---------------")
println(foo2())
println("---------------")
println(foo3())
println("---------------")
println(foo4())

Look carefully at each of the def lines, and write down what you think the output will be.

Why Zero-Install Will Succeed

Also known by the longer title: I Sure Hope Zero-Install Succeeds, Or Else We Might All Give Up On Package Managers Entirely.

If you’ve tried to run any of my software lately, you may have noticed that it’s all distributed and packaged via Zero-Install. I’ve posted about how awesome it is, but that was just an initial impression - I’m now familiar enough with the system to expand on those impressions.

After reading that the distros have killed python yesterday, I felt compelled to write in a little more detail how zero-install solves this and many other problems right now, across platforms and languages, and for much less effort than the current packaging practices.