I'm on the fence about whether it would be worth factoring out all of the common code here (which really is basically all of it) to a common function that also accepts a install/update/uninstall callable, and an error object. I imagine you thought about this too. Thoughts?