login

Dzen published 2 weeks ago, tagged with arch, bash, linux

Here’s for a small change of pace…

I’d like to talk about a tool I’ve all but forgotten I’m even using (and that’s a compliment to its stability and unobtrusiveness).

dzen is a great little application from the folks at suckless. It’s one of those do one thing and do it well types of tools. It’s probably not useful at all for anyone with a bloated –ahem, excuse me– featureful desktop environment or window manager (or both).

In my case, I’m using just XMonad with its beautiful simplicity. This means, of course, that there’s no out-of-the box… anything.

I’ve already covered some of this from an XMonad perspective, so this post is more about dzen’s general usefulness.

Volume

First up, a small visual notification when I adjust my volume:

ossvol screenshot

It fades in (implicitly thanks to xcompmgr) for just a second when I adjust my volume and gives me that nice, unobtrusive indication of the volume level.

The actual volume adjustment can be done in many alsa or oss specific ways; for my implementation, just see the script as it is live. Completely separate of that, however, we can just use dzen to show the notification:

level=$(get_it_from_alsa_or_oss)

# we use a fifo to buffer the repeated commands that are common with 
# volume adjustment
pipe='/tmp/volpipe'

# define some arguments passed to dzen to determine size and color.
dzen_args=( -tw 200 -h 25 -x 50 -y 50 -bg '#101010' )

# similarly for gdbar
gdbar_args=( -w 180 -h 7 -fg '#606060' -bg '#404040' )

# spawn dzen reading from the pipe (unless it's in mid-action already).
if [[ ! -e "$pipe" ]]; then
  mkfifo "$pipe"
  (dzen2 "${dzen_args[@]}" < "$pipe"; rm -f "$pipe") &
fi

# send the text to the fifo (and eventually to dzen). oss reports 
# something like "15.5" on a scale from 0 to 25 so we strip the decimals 
# and send gdbar an optional "upper limit" argument
(echo ${level/.*/} 25 | gdbar "${gdbar_args[@]}"; sleep 1) >> "$pipe"

Pretty easy, and about as light-weight as you can get.

Status bar

Little known fact: you can use the ubiquitous conky to feed a simple statusbar via dzen. This means you can also use dzen escapes in your TEXT block to do cool things:

dzen screenshot

My statusbar has the following “features”

  • Shows CPU/Mem/Network
  • The time, of course
  • Shows “Now playing” information from MPD
  • The music state (playing/paused) can be clicked to toggle it
  • The track title, when clicked, will advance

And here’s the conkyrc to achieve it:

background no
out_to_console yes
out_to_x no
override_utf8_locale yes
update_interval 1
total_run_times 0
mpd_host 192.168.0.5
mpd_port 6600

TEXT
[ ^ca(1, mpc toggle)${mpd_status}^ca()

  ${if_mpd_playing}- ${mpd_elapsed}/${mpd_length}$endif ]

  ^fg(\#909090)^ca(1, mpc next)${mpd_title}^ca()^fg() by

  ^fg(\#909090)${mpd_artist}^fg() from

  ^fg(\#909090)${mpd_album}^fg()

  Cpu: ^fg(\#909090)${cpu}%^fg()

  Mem: ^fg(\#909090)${memperc}%^fg()

  Net: ^fg(\#909090)${downspeedf eth0} / ${upspeedf eth0}^fg()

  ${time %a %b %d %H:%M}
Line breaks added for clarity.

The most interesting part is the clickable areas: ^ca( ... )some text^ca() defines an area of “some text” that can be clicked. The two arguments inside the first parens are are “which mouse button” and “what command to run”. Pretty simple and damn convenient.

Then all you’ve got to do is call this from your startup script:

$ conky -c ~/path/to/that | dzen2 -p -other -args

The -p option just means “persist” so the dzen will never close.

Wrap-up

This was just two examples of some uses for a simple “pipe some text in and see it” GUI toolkit – there are plenty others.

This echoes one of the great things about open-source: something like this is so small, so simple, it could never have survived marketing meetings, planning sessions or cost-benefit analyses – but here it is, and I find it oh-so-very-useful.

Git Submodule Config published 3 weeks ago, tagged with git, linux

Git submodules are pretty great. They allow you to have nested git repositories so that modular parts of your app can exist as separate repos but be worked with as one file tree. Another benefit is that when submodules are pushed to github they appear simply as links to the repos they represent.

If your not familiar, go ahead and google then come back – how submodules work overall is not the point of this post.

One of the ways I use submodules is to take modular pieces of my dotfiles repo and separate them out into single purpose, independently clonable repos for oh-my-zsh, vim and screen. A level down, inside the vim submodule itself, I use additional submodules in accordance with tpope’s awesome pathogen plugin to bundle the various vim plugins I use. At both of these levels there exist submodules of which I am the author and an active developer.

When I work on these submodules, I like to do so from within the parent repo (vs independently in some other directory). This is especially important in vim so that I can test out my changes immediately. If I didn’t do this, I would have to hack on the submodule, commit, push, go into the vim repo’s copy and pull – all before seeing the affects (Bret Victor would not be very happy with that workflow).

What this means is the submodule must be added with a pushable remote. And since I like to push using ssh keys and not enter my github credentials each time, I use the git@github url for that. Problem is, when someone wants to clone my repo (that’s what it’s there for), they’re unable to recursively clone those submodules because they don’t have access to them using that url. For that to work, I would’ve had to have added the submodules using the https protocol which allows anonymous checkouts.

As it turns out, due to the unexpected (but perfectly reasonable) behavior of a git submodule add command, I can actually have my cake and eat it too.

You see, when you do a git submodule add <url> <directory>, it writes that url to .gitmodules. This is the file and url that’s used when you clone this repo anywhere else and init the submodules within. But this is not the url that’s used when you actually try to push or pull from within the submodules!

In addition to .gitmodules, the url of the remote also gets written into the .git/config of the submodule as the origin remote (this is just normal clone behavior). This is the url that’s used for push/pull from within the submodule. If you think about it, it makes perfect sense: you’re in a valid git repo; when executing a push, you wouldn’t expect it to use anything but the remote that was defined and stored in your .git/config.

In some versions of git, I find that a submodule’s .git is actually a file pointing to a .git/modules/name/ directory in the parent repo.

Finally, the url/directory mapping for the submodule also gets written into the parent repo’s .git/config. What purpose does that serve? If you figure it out, let me know…

So (however unlikely this is) if you find yourself in the same situation as I, this is how you do that:

$ git add submodule https://github.com/you/repo some/dir
$ git commit -m 'added submodule repo'
$ cd some/dir
$ git remote rm origin
$ git remote add origin git@github.com:you/repo

Now anyone who clones (recursively) will get the anonymous checkout version (as defined in .gitmodules), but the origin remote in the local submodule has been changed to the git@github version and is pushable using ssh keys.

Beware Never Expectations published on Apr 8, tagged with mocha, rails, ruby

Mocha expectations are incredibly useful for ruby unit testing. You can stub out all kinds of functionality you depend on, specify exactly what values those dependencies return, and validate that the object under test behaves exactly as you want it to, right down to the methods it does or doesn’t call.

Unfortunately, I’ve bumped up against one glaring case where this can get you into trouble. To make matters worse, the symptom of this situation is that your tests just always pass.

Expects never

Take a simple class like this:

class Foo
  def a_method
    another_method

  rescue => ex
    logger.error("#{ex}")
  end

  # ...

end

Say we want to update it so that another_method is only called if some condition is met.

Let’s play hardcore TDD here; we’ll write and run the test first:

class FooTest < Test::Unit::TestCase
  def test_a_method
    foo = Foo.new

    # condition met
    foo.stubs(:some_condition?).returns(true)

    # should call it
    foo.expects(:another_method).once
    foo.a_method

    # condition not met
    foo.stubs(:some_condition?).returns(false)

    # should not call it
    foo.expects(:another_method).never
    foo.a_method
  end
end

Simple, easy to follow – you should absolutely fail with “Unexpected invocation” on that second call due to the never expectation you’ve set. There’s no reason to run this test now right? You know it’s going to fail, right?

You run the test anyway, and it… Passes. Um, wat?

I know what you might be saying here, it’s as simple as a single postfix unless some_condition?. So why am I insisting on figuring this out, wasting time just to see this test fail before I implement?

Well, in actuality I didn’t do things in this order. I wrote the implementation, then ran the test, saw it pass and moved on. It was only later that I regressed, broke the implementation and didn’t find out for a good while because the test never started failing.

Luckily, it hadn’t gone to production, but this scenario makes a strong case for writing and running your tests before your implementations – it’s the only chance you have to ensure your test actually covers what it should.

Anti-rescue

Let me save you the frustration of debugging this. What’s happening here is that when the method gets (incorrectly) called, Mocha raises an ExpectationError which is (by design) promptly rescued and logged.

I’d personally like to see Mocha not use this approach; rather count the number of calls and compare that number against what was expected later outside of your (possibly rescued) logic. This is how not-called-enough is implemented, why not let called-too-much be handled the same way?

There are a couple of ways we can work around this limitation though. One approach could be to re-raise the error when testing:

  # ...

rescue => ex
  logger.error(...)

  raise ex if Rails.env.test?
end

That’s only moderately smelly and might suit you in most cases. In my case, I couldn’t do this because swallowing all errors was by-design and (of course) backed up with test coverage, so those would start failing if I re-raise in that environment.

That and I hate modifying implementation code specifically to support some testing-related concern.

Another option might be to specifically handle the Mocha exception:

  # ...

rescue Mocha::ExpectationException => ex
  raise ex
rescue => ex
  logger.error(...)
end

That exception class is not in scope when you’re running in production, so that wouldn’t be fun. And I’d be very against requiring the Mocha gem in non-test environments.

Rewrite never

Anyway, here’s the solution we ended up with: redefine the method to increment a class-level counter, then assert that it was never called by checking that counter afterwards.

class FooTest < Test::Unit::TestCase
  def test_a_method
    foo = Foo.new
    foo.stubs(:some_condition?).returns(false)

    assert_not_called(foo, :another_method) do
      foo.a_method
    end
  end

  private

  # Note: not thread-safe
  def assert_not_called(obj, method, &block)
    # set a class level counter
    @@counter = 0

    # redefine the method so, if called, it increments that counter
    obj.instance_eval %{
      def #{method}(*args)
        #{self.class}.instance_eval "@@counter += 1"
      end
    }

    # run your code
    yield

    # see if it was ever called
    assert_equal 0, @@counter, "#{obj}.#{method}: unexpected invocation."
  end
end

Now, do yourself a favor and run this test before you write the implementation. It’s the only way to be sure the test works and regressions will be caught down the line.

Anonymous Classes In Ruby published on Mar 24, tagged with ruby

Often times, I find myself wanting something anonymous. This occurs quite frequently in code when you need to define, pass or call some functionality which is usually very short and only useful in this moment. Many languages provide anonymous functions (usually called lambdas) for this sort of thing: haskell has \x y -> x + y and ruby has lambda {|x,y| x + y}, Proc.new and the new ->(x,y) syntax which I’m actually not very fond of.

Sometimes, in ruby, I find myself wanting an anonymous class for much the same reasons. At first, this seemed like a silly thing to do, so I didn’t expect it to be clean or easy – but in fact, it is. Ruby itself uses anonymous classes for all sorts of things, and the syntax we’ll use to do it is almost comically obvious.

Testing

Sometimes if you’re writing a test for a module, you need to include or extend it into something to accurately test it. Here’s one approach to doing that:

# assume MyModule is defined as a module, which you want to test

class ModuleTest < Test::Unit::TestCase
  def test_the_thing
    klass = MyClass.new

    # assert something about klass now that it's included your module
  end

  private

  class MyClass
    include MyModule

    # ...

  end
end

This is fairly contrived, but I think we all agree that sometimes you need a new class to test something (like modules). Putting in some private subclass for the purposes of testing seems fairly appropriate, albeit pretty smelly.

Let’s see how an anonymous class can help:

class ModuleTest < Test::Unit::TestCase
  def test_the_thing
    klass = Class.new do
      include MyModule

      # ...

    end.new

    # assert something about klass
  end
end

Not only is this a bit shorter, but I’d say it’s clearer too now that the object under test is made more prominent.

Rake tasks

I like to write rake tasks to do useful things. Sometimes one of those tasks wants to move files around. FileUtils is great for this, and it’s best used when mixed into a class.

I won’t bore you with the non-anonymous version, so here’s the one using Class.new, hopefully you can imagine it with more boilerplate:

require 'fileutils'

desc "do the damn thing"
task :run do
  Class.new do
    include FileUtils

    def run!
      mv this, that

      cp here, there

      rm the_thing
    end
  end.new.run!
end

So short!

This really speaks to ruby’s flexibility when it comes to “everything is an object” and hopefully illustrates that if you understand the benefits of anonymous functions, why not start thinking about how to use anonymous classes too?

Escalate Your Scripts published on Mar 24, tagged with bash, ruby

Anyone who knows me knows I love the shell. I got my “start” in bash and still have a plethora of scripts lying around doing all sorts of useful and fun things for me. Recently, however, I tackled a task that I had attempted many times in shell script always to be met with frustration. How did I finally figure it out? I made it a rake task and did it in ruby.

Ask me last month what I thought the best tool for this job would’ve been, and 99 times out of 100 I would’ve said “shell script”. But guess what, I couldn’t do it – just never worked out. Now, after having written quite a nice little Rakefile, I can say confidently that I wish I had thought to do this sooner – and I hope I’ll think to do it again.

I want to write about this exercise mainly because I found the process to be quite enjoyable. When I needed to do imperative flow control, call system commands, and move things about the file system, I felt no resistance. More importantly, I could use all of the higher-level features to keep the code clear and clean.

And this is not just praise for ruby (though it does a good job), I’m more recommending that when presented with a task that makes sense as a shell script – think for a second if it might not be possible to do in a higher-level language, you might be surprised.

The Problem

I’ve got a repo (as a lot of you probably do) that contains my main dotfiles. It’s a collection of files that are usually scattered throughout my home directory which I’ve centralized into one folder and placed under version control. The normal approach with this is to symlink these files from the central location out into the proper placed under $HOME.

I wanted to automate this process. I wanted to be able to setup a new box by cloning this repo and running a single script. After that script completes, I want as much of my environment as is generally applicable to be fully configured.

The challenges here were that not all of the files in the repo made sense on every machine, some required parent directories to exist and, of course, I had to be careful not to clobber anything already present.

Nothing about this is insurmountable; the (albeit self-imposed) challenge is to do it as simply and maintainably as possible.

Objectify

The interesting thing about this script is what parts are higher level and what parts are not. So first, here are all of the higher-level bits with the scriptier parts left out:

require 'fileutils'

module Dotfiles
  def self.each(&block)
    [
      '.xcolors/jasonwryan.xcolors',
      '.xcolors/zenburn.xcolors',
      '.gitconfig',
      '.gitignore',
      '.htoprc',
      '.dir_colors',
      '.Xdefaults',
      '.zshrc',
      '.oh-my-zsh',
      '.screen',
      '.vim'
    ].each do |file|
      yield Dotfile.new(file)
    end
  end

  class Dotfile
    include FileUtils

    attr_reader :dotfile
    attr_accessor :source, :target

    def initialize(dotfile)
      @dotfile = dotfile
      @source  = File.join(pwd, dotfile)
      @target  = File.join(ENV['HOME'], dotfile)
    end

    def install!

      #
      # ...
      #

    end
  end
end

desc "updates all submodules"
task :submodules do

  #
  # ...
  #

end

desc "installs all dotfiles into the proper places"
task :install => [:submodules] do

  #
  # ...
  #

end

task :default => :install

This shows the pattern I most often follow when scripting in ruby (which is very different than programming in ruby): one, top-level module to hold any script-wide logic or constants as well as classes to represent the data your working with.

With an overall module and a clean API of classes and methods, you provide yourself a useful set of commands above and beyond the flow control and backtick-interpolation you would normally lean on.

You’ll also notice, in that each method, something I’m calling a Parallel Good Decision. I decided to hardcode the list of dotfile paths relative to the repo. This solved a number of problems that were leading to very smelly code. I could’ve used git ls-files or a normal glob-and-blacklist approach, but simply hardcoding this list allows finer control over what files are linked and if they are treated as files or directories.

Had I made this decision in isolation, it might have been enough for me to get that shell script approach working – but I didn’t. For some reason, only when cleaning up everything else and approaching the problem from a (slightly) higher level did I see that a simple list of relative file paths made the most sense here.

Script It Out

Now that the skeleton-slash-library code is in place, we can fill in the gaps:

require 'fileutils'

module Dotfiles
  def self.each(&block)
    # ... 
  end

  class Dotfile
    # ...

    def install!
      puts "--> installing #{dotfile} as #{target}..."
      if File.exists?(target)
        if File.symlink?(target)
          rm target, :verbose => true
        else
          mv target, "#{target}.backup", :verbose => true
        end
      end

      ln_s source, target, :verbose => true
    end
  end
end

desc "updates all submodules"
task :submodules do
  unless system('git submodule update --init --recursive')
    raise 'error initializing submodules'
  end
end

desc "installs all dotfiles into the proper places"
task :install => [:submodules] do
  Dotfiles.each(&:install!)

  vimrc = Dotfiles::Dotfile.new('.vimrc')
  vimrc.source = File.join(ENV['HOME'], '.vim', 'vimrc')
  vimrc.install!
end

task :default => :install

The stuff that’s easy is easy, the stuff that’s hard is easier and overall, the code is very clean and maintainable.

Oh, and I guess it’s nice that it works.