Category Archive for Agile

Setting the git commit author to pair programmers' names

August 31, 2008

Are you using git? Are you writing all your code that needs to be maintained in pairs? Great. Your commits probably look something like this:

commit a5ab4d39be608280fbea6ba9710aea4593f20bc6
Author: Bryan Helmkamp <bryan@brynary.com>
Date:   Fri Aug 29 18:47:29 2008 -0400

    Some important refactoring LM/BH

Subversion has limited support for tracking authors, so we used to manually add the initials of the programmers working on a changeset for future reference. With git, however, we can specify arbitrary author names for each commit. Now our commits look like this:

commit a5ab4d39be608280fbea6ba9710aea4593f20bc6
Author: Luke Melia and Bryan Helmkamp <developers@weplay.com>
Date:   Fri Aug 29 18:47:29 2008 -0400

    Some important refactoring

To simplify updating the git author configuration as we switch pairs, I whipped up a quick Ruby shell script called pair. Called with a list of developers' initials, it configures the git author name and email fields. Called with no arguments, it unsets the per-project git author configuration so your global settings take effect.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
#!/usr/bin/env ruby

# Configures the git author to a list of developers when pair programming
# 
# Usage: pair lm bh (Sets the author to 'Luke Melia and Bryan Helmkamp')
#        pair       (Unsets the author so the git global config takes effect)
# 
# Author: Bryan Helmkamp (http://brynary.com)

#######################################################################
## Configuration

PAIR_EMAIL = "developers@weplay.com"

AUTHORS = {
  "bh" => "Bryan Helmkamp",
  "lm" => "Luke Melia"
  # ...
}

## End of configuration
#######################################################################

unless File.exists?(".git")
  puts "This doesn't look like a git repository."
  exit 1
end

authors = ARGV.map do |initials|
  if AUTHORS[initials.downcase]
    AUTHORS[initials.downcase]
  else
    puts "Couldn't find author name for initials: #{initials}"
    exit 1
  end
end

if authors.any?
  if authors.size == 1
    authors = authors.first
  elsif authors.size == 2
    authors = authors.join(" and ")
  else
    authors = authors[0..-2].join(", ") + " and " + authors.last
  end
  
  `git config user.name '#{authors}'`
  `git config user.email '#{PAIR_EMAIL}'`
  
  puts "user.name = #{authors}"
  puts "user.email = #{PAIR_EMAIL}"
else
  `git config --unset user.name`
  `git config --unset user.email`
  
  puts "Unset user.name and user.email"
end

Note: If you're using GitHub, it's important to choose a PAIR_EMAIL value that does not correspond to a GitHub account. Otherwise, GitHub will resolve the email address to a GitHub user and display their username instead of the value of the author.name. We just made one up.

Story Driven Development slides posted

April 26, 2008

Just wrapped up my Story Driven Development talk at GoRuCo 2008. There were some great questions at the end, and I'm looking forward to more hallway track conversations about SDD.

Download the slides as a PDF (1.6 MB)

Note: Confreaks is recording the talks today, so a full video of my presentation should be online soon.

Presenting at GoRuCo in NYC

February 09, 2008

I just received word that my proposal to speak at NYC’s very own second annual GoRuCo has been accepted. The conference is set for Saturday, April 26th at Pace University downtown. My topic will be the same as my Scotland on Rails presentation.

I’m really excited to have the opportunity to present at home, in front of many of my friends and colleagues. Now I just need to make sure I don’t suck. Better get back to working on my slide deck…

Presenting at Scotland on Rails

January 31, 2008

I’m going to be presenting on Story Driven Development at the first Scottish Ruby on Rails conference, Scotland on Rails. I’ll be exploring the concept of Story-first development from both an agile process and implementation standpoint.

Topics will include:

  • Collaborating with the product owner on stories
  • What makes good stories and scenarios?
  • Driving stories with a browser simulator like Webrat
  • Potential pitfalls and ways to avoid them

If you’re going to be in Edinburgh for the conference, let me know.

How much money is your slow build wasting?

September 09, 2007

Recently, I've noticed a trend of unnecessarily slow builds hurting development velocity. I fear that developers may be overlooking the fact that a build composed of great code with great coverage is only truly useful if it can be run quickly.

Slow builds hurt development velocity in two primary ways. First, the developers must wait while the build is running. Remember how compiling provided ample time for extra coffee breaks or checking email and RSS feeds? If running the build is filing that gap, you've got a problem.

The second impact is harder to quantify, but equally important. Slower builds get ran less often. That means an increased feedback loop between code modifications and confirmation of their correctness. Tightening that loop is a central tenet of TDD, and it is what allows programmers to efficiently write code with confidence that it works.

If your continuous integration build fails because someone didn't run all of the tests before checking in, you're seeing another side effect of this problem. Continuous Integration is there to catch integration issues, not serve as a substitute for running the build locally.

Below I've setup a simple calculator to estimate the money directly wasted by a slow build. Five day work weeks are assumed. On a recent project I roughly estimated a loss of at least $7,500 per week due to unnecessarily slow builds.

Full-time developers
Old build duration minutes
New build duration minutes
Development rate dollars per hour
Builds per developer per day

The slow ass build is wasting at least $0 per week. Ouch.

Monitor builds from your desktop with CCMenu

September 01, 2007

So let’s just say you’re being a good developer and you’re writing tests. They are have good coverage (because you’re writing them first), they run fast, and you’ve setup a continuous integration (CI) server (like CruiseControl.rb) to run the build on every checkin.

CI servers can generally send email notifications for build failures and fixes, but when I’m in heads down development I often don’t check my email for hours at a time. Hours is far too long for a build to sit broken, especially when there are many other developers working on the project.

CCMenu tightens that feedback loop so I get immediate build status information in my menu bar. It uses Growl for notifications and provides a dashboard view of each project and its detailed build status. That’s a big improvement, and will help hold me over for a bit longer while I convince my boss to get us a build-controlled traffic light in the office.

Add SVN revision number to page titles for QA

August 30, 2007

At EastMedia, we generally run a development server which gets deployed from the trunk of each projects repository on a regular basis. One way we have improved the bug reports we get as part of our QA process is asking the testers to note the revision number of the build they were looking at when the bug occurred. To make this as easy as possible, during development we include the SVN revision number in the <title> tag of every page.

The code to determine the revision number lives in application_helper.rb:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def revision
  @revision ||= if svn_info_from_working_copy 
    svn_info_from_working_copy["Revision"].value
  else
    last_revision_in_log
  end
rescue
  @revision = "UNKNOWN"
end

def svn_info_from_working_copy
  @svn_info ||= YAML.parse(`svn info #{RAILS_ROOT}`)
end

def last_revision_in_log
  File.readlines(RAILS_ROOT + "/../../revisions.log").last.split[3]
end

And the header RHTML looks like this:


<title>r<%= revision  %> | ...Normal page title...</title>

GoRuCo talk: Business Natural Language

April 21, 2007

Presented by Jay Fields

  • Business Natural Language (BNL) is Domain Specific Language (DSL)
  • Traditional feedback loop: Business <- Developer -> QA
  • With DSLs: Business stakeholders update logic

Benefits

  • Managers—Improve efficiency
  • Developers—Technical decisions not business decisions
  • Business—Reduce time to market

(BNL == BSL) # => false

So?

  • Concise or verbose?
    • Less technical users might need more verbose DSL
  • Who’s the author?

“DSL” is too general

  • BNL is a subset of DSL
  • BNL characteristics differ from general DSL characteristics

The Difference

  • Written as natural language
  • Written by business people
    • Subject matter experts

Example specification

  • “Award 2 points if the fare class is A, C, D, J, Z”
  • account.award 2.points if [A,C,D,J,Z].include?(fare)

How?

  • Use preprocessor…
  • account.instance_eval removes need for account.
  • Use gsub to downcase fares (to avoid them being read as constants)
  • Fixnum.point does nothing. It’s syntax sugar.
  • Remove the word “class”. Not needed by Ruby.
  • gsub to add brackets around a list
  • gsub to remove words without business meaning (i.e. “the”)

Result: Specification == Code

  • Specification is code
  • Specification is readable documentation

Descriptive and maintainable phrases (DAMP)

  • More verbose, but verbosity makes them maintainable.
  • Since the business users control the logic, it’s easier to maintain

Do not sacrifice readability for conciseness

  • Staff changes
  • Other people will eventually need to read it

Who is the user?

  • Who are you designing for?
  • Verbose phrases are not strictly necessary but help subject matter expert maintain the language

Training

  • BNL has room for improvement if it requires any training to understand
  • Make your language fit the requirements instead of the requirements fitting your language
Applications can be built 80% faster with DSL
  • Actually, that’s bullshit.
  • But… “A change that used to take 3-4 days now takes 10 minutes.”

Why not offload non-interesting parts of the application to people who actually care about the rules?

Getting it to execute

  • BusinessLogic returns the rules from the DB
  • eval it once when we change the method, then save it as a method
  • One run eval again when rules change

Deployment?

  • New workflow: Business <> Approver <> Production
  • Developer not in the process
  • Flag scripts as “active”, expire old scripts

Programmers: Are you out of a job?

  • Absolutely not
  • Still need:
    • Language workbench
    • Workflow
    • Syntax checking
    • Test environment

Syntax checking

  • Very important
  • Needed for subject matter experts
  • Usually need contextual recommendations (i.e. “when the far” => “Did you mean ‘fare flass’?”)
  • Can be done with AJAX

Commercial language workbenches

  • MPS – JetBrains
    • Beta, but usable
    • Fowler has “hello world” examples
  • Intentional—Not available

Another example—Employee compensation

  • Verbose, but everyone can read it

When is BNL a bad choice?

  • Broad, unrelated project
  • Not necessary for programmers

How to decide?

  • Who is the author?
  • How frequently will the logic change?

How is this relevant to Ruby?

  • Not required, but easier than in Java or others
  • Need eval

More information

Clients are like crocodiles

March 30, 2007

Crocodile teeth The late Steve Irwin, Crocodile Hunter, was an expert at handling dangerous animals. Occasionally, even Steve get bit.

After a bite, Steve was always quick to point out that it was not the animal’s fault. An animal, of course, is a dangerous predator, but it’s not able to understand the consequences of its actions.

On the other hand, It is the animal handler’s responsibility to ensure the animal is never given the opportunity to bite a person. Because, when given the opportunity, a predator will always do what nature and instinct has taught it to do.

As software developers, we must take the role of the animal trainer. Our clients are like the crocodiles. If the client causes you harm (by changing requirements or deadlines, for example), you cannot blame the client, as it was just acting on its instincts.

Photo by maggie_p_au licensed under Creative Commons BY.