Alieniloquent


SVN + Git + 1 = Still Awesome

February 22nd, 2008

Yesterday I wrote about using SVN and Git together to have version control away from the network your SVN server is on. Now, I’ll admit, I wrote that shortly after figuring it out and doing it. So, at that time, I hadn’t actually come back into the office and merged my changes with the repository and committed them. Having done that a couple of times now, I’m here to say that this setup is fantastic.

So using this system you’re either at the office, so you can use SVN, or you’re not, so you have to use Git. I’ll give steps to follow for each. You should probably read the documentation available from the Git website to familiarize yourself further with these commands.

These steps assume that you’ve made a Git branch using the following command:

$ git branch home

Taking your work home: SVN -> Git

Make sure your SVN working copy is as up to date as you want it. Ideally, commit any changes. But, if you’re in the middle of a change set, that’s fine.

$ git commit -a -m "Merging in changes from SVN since last commit"
$ git checkout home
$ git merge master

Now you’re ready to use Git to continue making your changes while you’re away from the office.

Getting back to work: Git -> SVN

Make sure your Git changes are all committed to the home branch.
$ git checkout master
$ svn up

Resolve any conflicts from SVN.

$ git merge home

Resolve any conflicts from Git.

Now you can continue with your changes using SVN, or commit them right away if they’re already perfect.

SVN + Git = Awesome

February 20th, 2008

I’ve been a big fan of SVN for several years now. I even helped my former employer migrate from VSS a couple of years ago after I sold everybody on the idea. I have lots of love for SVN, but it has its limitations, especially the need to have network connectivity to a central repository. I know at least some people would love to have a way to still commit code when offline. So, here’s how I did it with SVN and Git.

Git is a DVCS that works differently than SVN. Instead of making changes in your working copy and submitting them to a central repository, your working copy is your repository. You can push changes to another repository or you can pull changes from another repository. It’s a nice way of working, and it’s what they use on the Linux kernel. The Git folks have a nice tutorial for SVN users.

The key feature of Git that makes it well suited for use alongside SVN is that it keeps all of its metadata in one folder at the top of your repository. It does not put one in each directory like SVN does. So you can make your SVN working copy into a Git repository and then ignore the folder and SVN knows nothing about it. Here’s what you do.

At the top level of your SVN working copy:

$ git init
$ echo .svn > .gitignore
$ git add *
$ git add .gitignore
$ git commit -m "Initial commit"

Now we just need to teach SVN to ignore the Git stuff. So open up your ~/.subversion/config file and find the [miscellany] section. You should see a commented out setting for global-ignores. Uncomment it and add .git* to it like this:

[miscellany]
### Set global-ignores to a set of whitespace-delimited globs
### which Subversion will ignore in its 'status' output, and
### while importing or adding files and directories.
global-ignores = *.o *.lo *.la \#*\# .*.rej *.rej .*~ *~ .\#* .DS_Store .git*

And voila! When you’re able to connect to your SVN repo, you can use SVN. But when you’re offline and still want the ability to use version control to incrementally save your changes, you can use Git. They’re working on the same files, so they play together very nicely.

Crunch Mode

February 18th, 2008

James Golick writes about crunch mode and how it can turn a team of even the best all-star code artists in to mediocre programmers.

I have been on an agile team full of all-star programmers. Every one of them as bright as the sun, and every one of them dedicated to writing quality software. Sure, we inherited a legacy code base of nearly a million lines of not-so-all-star code, but that’s the same situation everybody else is in too, right? It took us a couple of years to really get the agile juices flowing, but once we did, it was great. Except for crunch mode.

I’ve seen what James is talking about first hand. I’ve been what James is talking about. What I’ve never understood is why crunch mode seems more appealing to managers than facilitating the things a team needs to truly deliver on the promise of constantly shippable code. To me, the value proposition of being able to ship after any week- or month-long iteration is a big win over going into crunch mode to hit a date.

But I’m a developer, what do I know about managing projects, right?

Beauty is Important

February 18th, 2008

I was reminded of one of my favorite quotes today.

Beauty is more important in computing than anywhere else in technology because software is so complicated. Beauty is the ultimate defense against complexity.

Machine Beauty: Elegance and the Heart of Computing, David Gelernter

String transforms using Enumerable#inject

February 15th, 2008

I love functional programming, and I love Ruby. One of the most awesome things about Ruby is how much it borrows from the functional programming mindset. One of the most powerful concepts that functional programming brings to the table is higher-order functions. Ruby’s Enumerable module is a great example of how it embraces the idea of higher-order functions to abstract out the various things you do with a collection and let you focus on the operation for each item.

One of the most mysterious methods on Enumerable is Enumerable#inject. The example that’s always given is this:

irb> [1, 2, 3, 4].inject(0) {|sum, i| sum + i}
10

That’s fine, and usually makes sense. But when you try to branch out into more esoteric uses of inject, it can get confusing. So I’m going to give an example of accomplishing something useful with inject that you hopefully find useful.

I always find myself doing a sequence of substitutions on a string. For example, when I implement a Telnet client, I like to normalize the line endings I’m sending so that they’re sane. I accomplish that by translating “\r\n” to “\n”, then translating “\r” to “\n”, then translating “\n” to “\r\n”. It’s a simple thing to do, and I could do it like this:

string.gsub("\r\n", "\n").gsub("\r", "\n").gsub("\n", "\r\n")

But that’s not very extensible. I’d like to apply this idea of a sequence of substitutions in an abstract way so that I can do dynamically. And while I could do something with Object#send, that’s like cheating. This is where inject comes to the rescue.

def normalize_line_endings(string)
  transforms = [proc {|s| s.gsub("\r\n", "\n")},
                proc {|s| s.gsub("\r", "\n")},
                proc {|s| s.gsub("\n", "\r\n")}]
  transforms.inject(string) {|s, transform| transform.call(s)}
end

Kernel#proc (or Kernel#lambda if you prefer) is Ruby’s way of making higher-order functions. It returns a block which you can then call with an argument. In the above code, I make an array of transforms that take a string and return a string. The call to inject at the end is where the magic happens. It calls the first transform with string which was provided as the argument to inject. Then it calls the second transform with the result of the first, and it calls the third transform with the result of the second. That list could be as big as you want. It could even be dynamically generated.

That’s nice, but it’s still a a little verbose. I like to hide my use of Kernel#proc behind a declarative interface when I’m doing this sort of thing with it. So here’s how we can rewrite the method.

def transform(string, specifications = [])
  transforms = specifications.collect do |spec|
    proc {|s| s.gsub(spec[:from], spec[:to])}
  end
  transforms.inject(string) {|s, transform| transform.call(s)}
end

def normalize_line_endings(string)
  transform(string, [{:from => "\r\n", :to => "\n"},
                     {:from => "\r", :to => "\n"},
                     {:from => "\n", :to => "\r\n"}])
end

Of course, at that point, we don’t really need to create the procs. We can just use inject right on the specifications array, so the final code I came up with for this was:

def transform(string, specifications = [])
  specifications.inject(string) do |s, spec|
    s.gsub(spec[:from], spec[:to])
  end
end

def normalize_line_endings(string)
  transform(string, [{:from => "\r\n", :to => "\n"},
                     {:from => "\r", :to => "\n"},
                     {:from => "\n", :to => "\r\n"}])
end

Now that can be used with any list of transformations. Those transformations can be dynamically generated, and it’s a very clean implementation. That is the power of Enumerable#inject.

OCaml Talk

February 6th, 2008

So, I was going to give a talk on OCaml at ODYNUG last night. But, well, snow happened, and the meeting was canceled.

I will be giving the talk next month, on March 4th along with Brent Adkisson who will be giving a talk about Android.

Adding files to auto-mode-alist

January 31st, 2008

One of the things that I require from an editor is decent syntax highlighting. Emacs provides me that, and it also provides me with awesome indentation (I’ve grown addicted to hitting TAB and having my text just go to the right place regardless of where my cursor is). Emacs has a mode for every occasion and typically will load the right one based on the name of the file or its content. Recently, mine stopped doing that.

At first it was annoying. I’d open a LaTeX file and it wouldn’t change to latex-mode, or I’d open a C file and it wouldn’t go into c-mode, and worst of all, I’d load Emacs lisp files and they wouldn’t load in emacs-lisp-mode. I would just switch the mode by hand, but my patience could only last for so long.

Yesterday I finally took the time to find the trouble, shoot it, and replace it with better code. In my .emacs I had this:

(setq auto-mode-alist
      (append
        '(("\\.dtd$" . xml-mode)
          ("\\.xml$" . xml-mode)
          ("\\.yml$" . conf-mode)
          ("bash_profile$" . sh-mode)
          ("bashrc$" . sh-mode))
        auto-mode-alist))

I’ve seen that same code all over the internet, and it used to work just fine. But for some reason, now it does something to my auto-mode-alist and makes Emacs hate it for some reason. So I do some research. The recommended way to put stuff in an alist like that is ADD-TO-LIST.

So the above code becomes this:

(mapcar (lambda (mapping) (add-to-list 'auto-mode-alist mapping))
        '(("\\.dtd$" . xml-mode)
          ("\\.xml$" . xml-mode)
          ("\\.yml$" . conf-mode)
          ("bash_profile$" . sh-mode)
          ("bashrc$" . sh-mode)))

Putting that code in fixed my problems, and now all of my modes load correctly.

Living In the House That Rails Built

January 29th, 2008

I wanted to share a snippet of code. This code will print a call stack to STDOUT every time a Ruby class definition is evaluated. It is particularly useful when you find that class constants are being mysteriously redefined.

class Foo
  puts "\nRequired from:\n  #{Kernel.caller.join("\n  ")}"
  # ...
end

What inspired me to write that code? Rails did. The key to writing Ruby on Rails is that you’re writing Ruby on Rails. You don’t follow the Rails best practices because they’re convenient. You follow the Rails best practices because your program won’t work unless you do. Just like trains, you stay on the track and everything is great. If you try to take your train off-track, then it’s gruesome enough to make the nightly news.

How did I derail my application such that I cared how and where a file was being required? I wrote a unit test that explicitly required a model object. Oops. Remember that the semantics of require is load-once based on the name. So:

require "foo"

and:

require "models/foo"

are very different to require. Rails is super helpful and requires everything that it makes for you. So it requires models for you, even when you run your unit tests.

So take this code:

class Foo < ActiveRecord::Base
  RAILS_IS_A_GHETTO = true
end

And then write a test for something that Rails didn’t generate (such as something in the lib directory like I did):

# Require some other stuff
require "foo"

class TestTruth < Test::Unit::TestCase
  def test_truth
    assert true
  end
end

If you rake test you will get an error complaining that RAILS_IS_A_GHETTO was reinitialized, and that’s because Rails loads it for you as “models/foo” and you load it as “foo” so it gets loaded twice.

The moral of the story is: let Rails load the things it built, and you load the things you built.

Making Terminal Bearable

January 3rd, 2008

I’ve been using Macintosh computers for several years now, but I came to them from the Unix world. There were several expectations I had from my terminal emulator. Among them were that the key that says Alt on it should be my Meta key for Emacs key-chords, and that the Page Up and Page Down keys should page up and page down in my application. None of those behaviors are the default, so fixing them is one of the first things I do when I get a Mac.

In Leopard these settings are all in the Settings section of Preferences (Cmd-, or Terminal > Preferences…), but in previous versions they are in the Window Settings screen (Terminal > Window Settings…).

First, to take care of the Alt key issue, go to the Keyboard section of the settings. There is a checkbox toward the bottom that says “Use option key as meta.” Check it.

With that problem solved, all that is left are the paging keys. The default behavior is to have Shift Page Up send Page Up to the terminal and Page Up and do the same for Page Down. In the Keyboard Settings you should see a grid with keystrokes on the left and text on the right. In many cases it will be an ANSI escape sequence to send to the terminal, in some cases it will be a special action. Here’s what you want to set things to.

  • page down = send string to shell: \033[6~
  • page up = send string to shell: \033[5~
  • shift page down = scroll to next page in buffer
  • shift page up = scroll to previous page in buffer

That effectively just swaps the keys, so that you still have the ability to scroll your Terminal buffer with the keyboard.

After I fix the keyboard, I like to fiddle with colors and other things, which will all be in the same preferences dialogs. Then, after all the tweaks and fixes, Terminal is ready to use.

Make SLIME load faster

December 29th, 2007

I have joined up with some of the guys from ODYNUG who have started meeting for breakfast and learning Common Lisp together. We are all using some version of Emacs, SLIME, and SBCL.

Blaine shared a cool way to make SLIME load much faster by taking advantage of the fact that Lisp uses images like Smalltalk (or more accurately, Smalltalk uses images like Lisp). He posted it for the group to see, but I wanted to post it here for my readers.

SBCL allows you to specify an image, or as they call it a core, by passing the --core option along with (as far as I can tell) an absolute path to the core file (well, at least it doesn’t know that ~ means $HOME). It, of course, also provides a way to create these core files, so you can load a bunch of stuff in, and then save a core file that has all of that already loaded.

So first, go into your SLIME directory and copy swank-loader.lisp to swank-loader-original.lisp. Then make swank-loader.lisp look like this (changing slime-dir to be wherever your SLIME is, of course):

(if (not (find-package 'swank-loader))
    ;; Edit SLIME-DIR to be where you have SLIME installed.
    (let ((slime-dir (merge-pathnames ".elisp/slime/" (user-homedir-pathname))))
      (load (merge-pathnames "swank-loader-original" slime-dir))))

Then, make a file called bootstrap.lisp with the following content:

;; Load Swank
(load (merge-pathnames ".elisp/slime/swank-loader" (user-homedir-pathname)))

;; Save image
(sb-ext:save-lisp-and-die "sbcl-with-slime.core")

And run this command:

$ sbcl --load bootstrap.lisp

Then copy sbcl-with-slime.core somewhere safe, I put mine in with my slime code to keep it all together. Then you just have to add the following to your .emacs:

(let* ((slime-dir (concat elisp-dir "/slime"))
       (core-file (concat slime-dir "/sbcl-with-slime.core")))
  (setq inferior-lisp-program (concat "sbcl --core " core-file)))

Then you can M-x slime and it will be super fast.

Layout, design, graphics, photography and text all © 2005-2010 Samuel Tesla unless otherwise noted.

Portions of the site layout use Yahoo! YUI Reset, Fonts & Grids.