Thursday, February 25, 2016

Disabling Plugins in Jenkins

If a plugin upgrade causes problems, Jenkins may not restart. You'll be welcomed by an error message and a stack trace. Don't panic! Go into your Jenkins plugin directory, list files by date, and then disable the most recent ones:
$ cd $JENKINS_HOME/plugins
$ ls -ltr *.jpi
-rw-r--r--. 1 root root   169194 Feb 22 10:12 script-security.jpi
-rw-r--r--. 1 root root   516115 Feb 22 10:12 next-executions.jpi
-rw-r--r--. 1 root root   739004 Feb 22 10:12 email-ext.jpi
$ touch email-ext.jpi.disabled next-executions.jpi.disabled script-security.jpi.disabled
$ service jenkins restart
Files ending in .disabled instruct Jenkins to disable the corresponding plugin. Delete the disabling files until you've found the offending plugin. Then you can go into Jenkins and revert it to an earlier version. Word of advice: Upgrade plugins in small batches. Doing so helps you isolate early problematic plugins.

Thursday, February 18, 2016

Big list of files to edit? vim to the rescue (again)

Did you know that you can treat the text under the cursor as a filename, and open that up for editing right in vim? Here's how:

  • gf will open the filename under the cursor in the current window
  • ^Wf will open it in a split window
  • ^Wgf will open it in a new window

Thursday, February 11, 2016

Thursday, February 4, 2016

Private methods are collaborators in disguise

Private methods cannot be unit tested, only integration tested through whatever public methods call them. I find this unsettling. I want to unit test private methods, so that I know the public methods are composed of independently verified code. What to do?

My first tactic is to avoid private methods. When behaviors are small enough, the need for private methods diminishes.

My second tactic is to promote them to public, but document that they aren't part of the API. This feels like a hack. A trick that's necessary because I've not thought about the design deep enough. I do this more than I like, honestly, because it's so quick and cheap to do.

Today, I thought of another approach that reinforces the first tactic. Maybe the apparent need for private methods is a signal that what I really want is a collaborator. Instead of privately doing a bit of work in furtherance of a class behavior goal, delegate that work to a first-class worker. Example? Sure!

Suppose I'm writing a class to model a web request. Part of web requests are MIME content type headers. These headers have specific formats for which a parser is needed. I could build parsing into my web request class, undoubtedly through several private methods that implement MIME content type parsing RFC 2045. These will be hard to test.

Instead of those private methods to parse the headers, I want to defer the parsing to a first class delegate. An actual, red-blooded class that knows only how to parse RFC 2045. Turns out, open source libraries already exist, and I don't have to do the work. A happy side effect.