Permalink
Browse files

convert to Grit module, refactor to be more OO

  • Loading branch information...
1 parent a47fd41 commit d01a4cfad6ea50285c4710243e3cbe019d381eba @mojombo committed Oct 10, 2007
Showing with 145 additions and 87 deletions.
  1. +3 −2 lib/grit.rb
  2. +1 −1 lib/grit/commit.rb
  3. +1 −1 lib/grit/errors.rb
  4. +24 −0 lib/grit/git.rb
  5. +0 −71 lib/grit/grit.rb
  6. +44 −3 lib/grit/head.rb
  7. +53 −0 lib/grit/repo.rb
  8. +2 −0 test/helper.rb
  9. +6 −0 test/suite.rb
  10. +8 −0 test/test_git.rb
  11. +3 −9 test/{test_grit.rb → test_repo.rb}
View
@@ -6,10 +6,11 @@
# internal requires
require 'grit/errors'
+require 'grit/git'
require 'grit/head'
require 'grit/commit'
-require 'grit/grit'
+require 'grit/repo'
-class Grit
+module Grit
VERSION = '1.0.0'
end
View
@@ -1,3 +1,3 @@
-class Grit
+module Grit
Commit = Struct.new(:id, :parents, :tree, :author, :authored_date, :committer, :committed_date)
end
View
@@ -1,4 +1,4 @@
-class Grit
+module Grit
class InvalidGitRepositoryError < StandardError
end
end
View
@@ -0,0 +1,24 @@
+module Grit
+
+ class Git
+ class << self
+ attr_accessor :git_binary
+ end
+
+ self.git_binary = "/usr/bin/env git"
+
+ # Run the given git command with the specified arguments and return
+ # the result as a chomped String
+ # +cmd+ is the command
+ # +args+ is the list of arguments (to be joined by spaces)
+ #
+ # Examples
+ # Grit::Git.rev_list('--parents', '--history')
+ #
+ # Returns String
+ def self.method_missing(cmd, *args)
+ `#{Git.git_binary} #{cmd.to_s.gsub(/_/, '-')} #{args.join(' ')}`.chomp
+ end
+ end # Git
+
+end # Grit
View
@@ -1,71 +0,0 @@
-class Grit
- class << self
- attr_accessor :git_binary
- end
-
- self.git_binary = "/usr/bin/env git"
-
- # The path of the git repo as a String
- attr_accessor :path
-
- # Create a new Grit instance
- # +path+ is the path to either the root git directory or the bare git repo
- #
- # Examples
- # g = Grit.new("/Users/tom/dev/grit")
- # g = Grit.new("/Users/tom/public/grit.git")
- #
- # Returns Grit
- def initialize(path)
- if File.exist?(File.join(path, '.git'))
- self.path = File.join(path, '.git')
- elsif File.exist?(path) && path =~ /\.git$/
- self.path = path
- else
- raise InvalidGitRepositoryError.new(path) unless File.exist?(path)
- end
- end
-
- # Return the project's description. Taken verbatim from REPO/description
- #
- # Returns String
- def description
- File.open(File.join(self.path, 'description')).read.chomp
- end
-
- # Return an array of Head objects representing the available heads in
- # this repo
- #
- # Returns Grit::Head[]
- def heads
- output = git("for-each-ref",
- # "--count=1",
- "--sort=-committerdate",
- "--format='%(objectname) %(refname) %(subject)%00%(committer)'",
- "refs/heads")
-
- heads = []
-
- output.split("\n").each do |line|
- ref_info, committer_info = line.split("\0")
- id, name, message = ref_info.split(" ", 3)
- m, committer, epoch, tz = *committer_info.match(/^(.*) ([0-9]+) (.*)$/)
- date = Time.at(epoch.to_i)
- heads << Head.new(id, name, message, committer, date)
- end
-
- heads
- end
-
- # private
-
- # Run the given git command with the specified arguments and return
- # the result as a chomped String
- # +cmd+ is the command
- # +args+ is the list of arguments (to be joined by spaces)
- #
- # Returns String
- def git(cmd, *args)
- `#{Grit.git_binary} #{cmd} #{args.join(' ')}`.chomp
- end
-end
View
@@ -1,3 +1,44 @@
-class Grit
- Head = Struct.new(:id, :name, :message, :committer, :date)
-end
+module Grit
+
+ class Head
+ attr_accessor :id
+ attr_accessor :name
+ attr_accessor :message
+ attr_accessor :committer
+ attr_accessor :date
+
+ def initialize(id, name, message, committer, date)
+ self.id = id
+ self.name = name
+ self.message = message
+ self.committer = committer
+ self.date = date
+ end
+
+ # Create a new Head instance from the given string.
+ # +line+ is the formatted head information
+ #
+ # Format
+ # id: [0-9A-Fa-f]{40}
+ # <space>
+ # name: [^ ]*
+ # <space>
+ # message: [^\0]*
+ # <null byte>
+ # committer: .*
+ # <space>
+ # epoch: [0-9]+
+ # <space>
+ # tz: .*
+ #
+ # Returns Grit::Head
+ def self.from_string(line)
+ ref_info, committer_info = line.split("\0")
+ id, name, message = ref_info.split(" ", 3)
+ m, committer, epoch, tz = *committer_info.match(/^(.*) ([0-9]+) (.*)$/)
+ date = Time.at(epoch.to_i)
+ self.new(id, name, message, committer, date)
+ end
+ end # Head
+
+end # Grit
View
@@ -0,0 +1,53 @@
+module Grit
+
+ class Repo
+ # The path of the git repo as a String
+ attr_accessor :path
+
+ # Create a new Repo instance
+ # +path+ is the path to either the root git directory or the bare git repo
+ #
+ # Examples
+ # g = Repo.new("/Users/tom/dev/grit")
+ # g = Repo.new("/Users/tom/public/grit.git")
+ #
+ # Returns Repo
+ def initialize(path)
+ if File.exist?(File.join(path, '.git'))
+ self.path = File.join(path, '.git')
+ elsif File.exist?(path) && path =~ /\.git$/
+ self.path = path
+ else
+ raise InvalidGitRepositoryError.new(path) unless File.exist?(path)
+ end
+ end
+
+ # Return the project's description. Taken verbatim from REPO/description
+ #
+ # Returns String
+ def description
+ File.open(File.join(self.path, 'description')).read.chomp
+ end
+
+ # Return an array of Head objects representing the available heads in
+ # this repo
+ #
+ # Returns Grit::Head[]
+ def heads
+ output = Git.for_each_ref(
+ "--sort=-committerdate",
+ # "--count=1",
+ "--format='%(objectname) %(refname) %(subject)%00%(committer)'",
+ "refs/heads")
+
+ heads = []
+
+ output.split("\n").each do |line|
+ heads << Head.from_string(line)
+ end
+
+ heads
+ end
+ end # Repo
+
+end # Grit
View
@@ -5,3 +5,5 @@
require 'mocha'
GRIT_REPO = File.join(File.dirname(__FILE__), *%w[..])
+
+include Grit
View
@@ -0,0 +1,6 @@
+require 'test/unit'
+
+tests = Dir["#{File.dirname(__FILE__)}/test_*.rb"]
+tests.each do |file|
+ require file
+end
View
@@ -0,0 +1,8 @@
+require File.dirname(__FILE__) + '/helper'
+
+class TestGit < Test::Unit::TestCase
+
+ def test_method_missing
+ assert_match /^git version [\d\.]*$/, Git.version
+ end
+end
@@ -1,8 +1,8 @@
require File.dirname(__FILE__) + '/helper'
-class TestGrit < Test::Unit::TestCase
+class TestRepo < Test::Unit::TestCase
def setup
- @g = Grit.new(GRIT_REPO)
+ @g = Repo.new(GRIT_REPO)
end
# descriptions
@@ -20,7 +20,7 @@ def test_heads_should_return_array_of_head_objects
end
def test_heads_should_populate_head_data
- @g.expects(:git).returns("634396b2f541a9f2d58b00be1a07f0c358b999b3 refs/heads/master \
+ Git.expects(:for_each_ref).returns("634396b2f541a9f2d58b00be1a07f0c358b999b3 refs/heads/master \
initial grit setup\0Tom Preston-Werner <tom@mojombo.com> 1191997100 -0700")
head = @g.heads.first
@@ -31,10 +31,4 @@ def test_heads_should_populate_head_data
assert_equal 'Tom Preston-Werner <tom@mojombo.com>', head.committer
assert_equal Time.at(1191997100), head.date
end
-
- # git
-
- def test_git
- assert_match /^git version [\d\.]*$/, @g.git('version')
- end
end

0 comments on commit d01a4cf

Please sign in to comment.