Решение на Пета задача от Николай Коцев

Обратно към всички решения

Към профила на Николай Коцев

Резултати

  • 0 точки от тестове
  • 0 бонус точки
  • 0 точки общо
  • 1 успешни тест(а)
  • 29 неуспешни тест(а)

Код

require 'digest/sha1'
require 'date'
class Branch
attr_reader :name, :stage
# commit list
def initialize(name, state = [], stage = {})
@name = name
@commit_list = state
@add_stage = stage[:add] || {}
@remove_stage = stage[:remove] || []
end
def add(name, object)
@remove_stage.delete(name)
@add_stage[name] = object
Result.new("Added #{name} to stage.", true, object)
end
def remove(name)
unless head.include? name
return Result.new("Object #{name} is not commited", false)
end
# Git would give you error in the case, but ...
removed_object = @add_stage.remove(name)
@remove_stage << name
Result.new("Added #{name} for removal", true, removed_object)
end
def commit(message)
if stage.empty?
return Result.new("Nothing to commit, working directory clean", false)
end
state = head ? head.state : []
result_message = "#{message}\n\t#{@add_stage.count + @remove_stage.count}" +
" objects changed"
result = Result.new(result_message, true)
commit = Commit.new(message, state, stage, result)
@commit_list << commit
end
def stage
stage_object = {}
stage_object[:add] = @add_stage unless @add_stage.empty?
stage_object[:remove] = @remove_stage unless @remove_stage.empty?
stage_object
end
def log
@commit_list.reverse.each_with_object("") do |commit, log|
log << commit.log + "\n"
end
end
def head
@commit_list.last
end
end
class Commit
attr_reader :state, :message, :hash, :date, :result
def initialize(message, state, changes, result)
if changes[:add]
changes[:add].each { |name, object| state << {state => object} }
end
changes[:remove].each { |name| state.remove(name) } if changes[:remove]
@state = state
@message = message
@hash = generate_hash
@date = Time.now
@result = result
end
def include?(name)
@state.has_key?(name)
end
def generate_hash
@hash = Digest::SHA1.hexdigest(Date.today.to_s + @message)
end
def log
"Commit #{@hash}\nDate: #{@time.asctime}\n\n\t#{message}"
end
alias objects state
end
class ObjectStore
def self.init(&block)
ObjectStore.new(&block)
end
def initialize
@current_branch = Branch.new("master")
@head = @current_branch.head
@branches = [@current_branch]
yield if block_given?
end
def log
@current_branch.log
end
def add(name, object)
@current_branch.add(name, object)
end
def commit(message)
@current_branch.commit(message)
end
def remove(name)
@current_branch.remove(name)
end
def branch
@current_branch
end
def head
@current_branch.head
end
end
class Result
attr_reader :message, :result
def initialize(message, success, result = nil)
@message = message
@success = success
@result = result
end
def success?
not not @success
end
def error?
not @success
end
end

Лог от изпълнението

.FFFFFFFFFFFFFFFFFFFFFFFFFFFFF

Failures:

  1) ObjectStore can commit objects
     Failure/Error: actual.message == message &&
     NoMethodError:
       undefined method `message' for #<Array:0x007fd1c6687348>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:6:in `block (3 levels) in <top (required)>'
     # /tmp/d20160111-5693-1t8utxm/spec.rb:30:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  2) ObjectStore cannot commit without changed objects
     Failure/Error: expect(repo.commit("So cool!!")).to be_error("Nothing to commit, working directory clean.")
       expected #<Result:0x007fd1c6678cd0 @message="Nothing to commit, working directory clean", @success=false, @result=nil> to be error "Nothing to commit, working directory clean."
     # /tmp/d20160111-5693-1t8utxm/spec.rb:35:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  3) ObjectStore can remove objects
     Failure/Error: expect(repo.remove("object1")).to be_success("Added object1 for removal.", "content1")
     NoMethodError:
       undefined method `has_key?' for [{[...]=>"content1"}, {[...]=>"content2"}]:Array
     # /tmp/d20160111-5693-1t8utxm/solution.rb:77:in `include?'
     # /tmp/d20160111-5693-1t8utxm/solution.rb:21:in `remove'
     # /tmp/d20160111-5693-1t8utxm/solution.rb:116:in `remove'
     # /tmp/d20160111-5693-1t8utxm/spec.rb:43:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  4) ObjectStore can commit changes which include only removed objects
     Failure/Error: repo.remove("object2")
     NoMethodError:
       undefined method `has_key?' for [{[...]=>"content1"}, {[...]=>"content2"}]:Array
     # /tmp/d20160111-5693-1t8utxm/solution.rb:77:in `include?'
     # /tmp/d20160111-5693-1t8utxm/solution.rb:21:in `remove'
     # /tmp/d20160111-5693-1t8utxm/solution.rb:116:in `remove'
     # /tmp/d20160111-5693-1t8utxm/spec.rb:52:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  5) ObjectStore cannot remove objects that are not committed
     Failure/Error: expect(repo.remove("object2")).to be_error("Object object2 is not committed.")
     NoMethodError:
       undefined method `has_key?' for [{[...]=>"content1"}]:Array
     # /tmp/d20160111-5693-1t8utxm/solution.rb:77:in `include?'
     # /tmp/d20160111-5693-1t8utxm/solution.rb:21:in `remove'
     # /tmp/d20160111-5693-1t8utxm/solution.rb:116:in `remove'
     # /tmp/d20160111-5693-1t8utxm/spec.rb:60:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  6) ObjectStore can show head
     Failure/Error: last_commit = repo.commit("There we go").result
     NoMethodError:
       undefined method `result' for #<Array:0x007fd1c6666210>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:68:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  7) ObjectStore cannot show head for empty repository
     Failure/Error: result.message == message &&
     NoMethodError:
       undefined method `message' for nil:NilClass
     # /tmp/d20160111-5693-1t8utxm/spec.rb:15:in `block (3 levels) in <top (required)>'
     # /tmp/d20160111-5693-1t8utxm/spec.rb:74:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  8) ObjectStore can show log of changes for a single commit
     Failure/Error: commit = repo.commit("So cool!").result
     NoMethodError:
       undefined method `result' for #<Array:0x007fd1c60de928>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:81:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  9) ObjectStore can show log of changes for a single commit
     Failure/Error: commit = repo.commit("So cool!").result
     NoMethodError:
       undefined method `result' for #<Array:0x007fd1c62dcc20>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:90:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  10) ObjectStore can show log of changes for multiple commits
     Failure/Error: commit1 = repo.commit("First commit").result
     NoMethodError:
       undefined method `result' for #<Array:0x007fd1c62cdd38>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:98:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  11) ObjectStore shows the log for the current branch only
     Failure/Error: commit1 = repo.commit("First commit").result
     NoMethodError:
       undefined method `result' for #<Array:0x007fd1c62b74e8>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:114:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  12) ObjectStore cannot show log for empty repository
     Failure/Error: result.message == message &&
     NoMethodError:
       undefined method `message' for "":String
     # /tmp/d20160111-5693-1t8utxm/spec.rb:15:in `block (3 levels) in <top (required)>'
     # /tmp/d20160111-5693-1t8utxm/spec.rb:133:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  13) ObjectStore can list branches
     Failure/Error: repo.branch.create("develop")
     NoMethodError:
       undefined method `create' for #<Branch:0x007fd1c6276100>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:138:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  14) ObjectStore can create branches
     Failure/Error: expect(repo.branch.create("develop")).to be_success("Created branch develop.")
     NoMethodError:
       undefined method `create' for #<Branch:0x007fd1c626d6b8>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:145:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  15) ObjectStore cannot create branch if already exists
     Failure/Error: expect(repo.branch.create("master")).to be_error("Branch master already exists.")
     NoMethodError:
       undefined method `create' for #<Branch:0x007fd1c625a310>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:150:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  16) ObjectStore can switch branches
     Failure/Error: first_commit = repo.commit("First commit").result
     NoMethodError:
       undefined method `result' for #<Array:0x007fd1c6258178>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:156:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  17) ObjectStore cannot switch to nonexisting branch
     Failure/Error: expect(repo.branch.checkout("develop")).to be_error("Branch develop does not exist.")
     NoMethodError:
       undefined method `checkout' for #<Branch:0x007fd1c6251350>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:168:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  18) ObjectStore can remove branch
     Failure/Error: repo.branch.create("develop")
     NoMethodError:
       undefined method `create' for #<Branch:0x007fd1c623c838>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:173:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  19) ObjectStore cannot remove current branch
     Failure/Error: expect(repo.branch.remove("master")).to be_error("Cannot remove current branch.")
     NoMethodError:
       undefined method `include?' for nil:NilClass
     # /tmp/d20160111-5693-1t8utxm/solution.rb:21:in `remove'
     # /tmp/d20160111-5693-1t8utxm/spec.rb:179:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  20) ObjectStore cannot remove nonexisting branch
     Failure/Error: expect(repo.branch.remove("develop")).to be_error("Branch develop does not exist.")
     NoMethodError:
       undefined method `include?' for nil:NilClass
     # /tmp/d20160111-5693-1t8utxm/solution.rb:21:in `remove'
     # /tmp/d20160111-5693-1t8utxm/spec.rb:184:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  21) ObjectStore can be initialized with block
     Failure/Error: add("object1", "content1")
     NoMethodError:
       undefined method `add' for #<RSpec::Core::ExampleGroup::Nested_1:0x007fd1c61f4330>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:189:in `block (3 levels) in <top (required)>'
     # /tmp/d20160111-5693-1t8utxm/solution.rb:100:in `initialize'
     # /tmp/d20160111-5693-1t8utxm/solution.rb:93:in `new'
     # /tmp/d20160111-5693-1t8utxm/solution.rb:93:in `init'
     # /tmp/d20160111-5693-1t8utxm/spec.rb:188:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  22) ObjectStore can return objects
     Failure/Error: expect(repo.get("number")).to be_success("Found object number.", 21)
     NoMethodError:
       undefined method `get' for #<ObjectStore:0x007fd1c61db268>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:202:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  23) ObjectStore cannot return not committed objects
     Failure/Error: expect(repo.get("string")).to be_error("Object string is not committed.")
     NoMethodError:
       undefined method `get' for #<ObjectStore:0x007fd1c61d5390>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:209:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  24) ObjectStore cannot return objects when no commits
     Failure/Error: expect(repo.get("string")).to be_error("Object string is not committed.")
     NoMethodError:
       undefined method `get' for #<ObjectStore:0x007fd1c61c1b38>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:214:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  25) ObjectStore can checkout commits
     Failure/Error: first_commit = repo.commit("First commit").result
     NoMethodError:
       undefined method `result' for #<Array:0x007fd1c614a0b0>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:220:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  26) ObjectStore cannot checkout commits with nonexisting hashes
     Failure/Error: expect(repo.checkout("[not-present]")).to be_error("Commit [not-present] does not exist.")
     NoMethodError:
       undefined method `checkout' for #<ObjectStore:0x007fd1c612ff08>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:231:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  27) ObjectStore cannot checkout commits in empty repository
     Failure/Error: expect(repo.checkout("[not-present]")).to be_error("Commit [not-present] does not exist.")
     NoMethodError:
       undefined method `checkout' for #<ObjectStore:0x007fd1c611b418>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:236:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  28) ObjectStore can show the objects in a repo after overwriting an object
     Failure/Error: first_commit = repo.commit("First commit").result
     NoMethodError:
       undefined method `result' for #<Array:0x007fd1c6115b58>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:242:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

  29) ObjectStore can show the objects of a repo after removing an object
     Failure/Error: first_commit = repo.commit("First commit").result
     NoMethodError:
       undefined method `result' for #<Array:0x007fd1c60ffe98>
     # /tmp/d20160111-5693-1t8utxm/spec.rb:258:in `block (2 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (3 levels) in <top (required)>'
     # ./lib/language/ruby/run_with_timeout.rb:5:in `block (2 levels) in <top (required)>'

Finished in 0.01469 seconds
30 examples, 29 failures

Failed examples:

rspec /tmp/d20160111-5693-1t8utxm/spec.rb:26 # ObjectStore can commit objects
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:33 # ObjectStore cannot commit without changed objects
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:38 # ObjectStore can remove objects
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:46 # ObjectStore can commit changes which include only removed objects
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:56 # ObjectStore cannot remove objects that are not committed
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:63 # ObjectStore can show head
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:72 # ObjectStore cannot show head for empty repository
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:77 # ObjectStore can show log of changes for a single commit
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:86 # ObjectStore can show log of changes for a single commit
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:95 # ObjectStore can show log of changes for multiple commits
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:111 # ObjectStore shows the log for the current branch only
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:131 # ObjectStore cannot show log for empty repository
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:136 # ObjectStore can list branches
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:143 # ObjectStore can create branches
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:148 # ObjectStore cannot create branch if already exists
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:153 # ObjectStore can switch branches
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:166 # ObjectStore cannot switch to nonexisting branch
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:171 # ObjectStore can remove branch
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:177 # ObjectStore cannot remove current branch
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:182 # ObjectStore cannot remove nonexisting branch
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:187 # ObjectStore can be initialized with block
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:198 # ObjectStore can return objects
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:205 # ObjectStore cannot return not committed objects
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:212 # ObjectStore cannot return objects when no commits
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:217 # ObjectStore can checkout commits
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:227 # ObjectStore cannot checkout commits with nonexisting hashes
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:234 # ObjectStore cannot checkout commits in empty repository
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:239 # ObjectStore can show the objects in a repo after overwriting an object
rspec /tmp/d20160111-5693-1t8utxm/spec.rb:253 # ObjectStore can show the objects of a repo after removing an object

История (1 версия и 0 коментара)

Николай обнови решението на 23.11.2015 16:55 (преди над 8 години)

+require 'digest/sha1'
+require 'date'
+
+class Branch
+ attr_reader :name, :stage
+ # commit list
+ def initialize(name, state = [], stage = {})
+ @name = name
+ @commit_list = state
+ @add_stage = stage[:add] || {}
+ @remove_stage = stage[:remove] || []
+ end
+
+ def add(name, object)
+ @remove_stage.delete(name)
+ @add_stage[name] = object
+ Result.new("Added #{name} to stage.", true, object)
+ end
+
+ def remove(name)
+ unless head.include? name
+ return Result.new("Object #{name} is not commited", false)
+ end
+ # Git would give you error in the case, but ...
+ removed_object = @add_stage.remove(name)
+ @remove_stage << name
+ Result.new("Added #{name} for removal", true, removed_object)
+ end
+
+ def commit(message)
+ if stage.empty?
+ return Result.new("Nothing to commit, working directory clean", false)
+ end
+ state = head ? head.state : []
+ result_message = "#{message}\n\t#{@add_stage.count + @remove_stage.count}" +
+ " objects changed"
+ result = Result.new(result_message, true)
+ commit = Commit.new(message, state, stage, result)
+ @commit_list << commit
+ end
+
+ def stage
+ stage_object = {}
+ stage_object[:add] = @add_stage unless @add_stage.empty?
+ stage_object[:remove] = @remove_stage unless @remove_stage.empty?
+ stage_object
+ end
+
+ def log
+ @commit_list.reverse.each_with_object("") do |commit, log|
+ log << commit.log + "\n"
+ end
+ end
+
+ def head
+ @commit_list.last
+ end
+
+end
+
+class Commit
+ attr_reader :state, :message, :hash, :date, :result
+
+ def initialize(message, state, changes, result)
+ if changes[:add]
+ changes[:add].each { |name, object| state << {state => object} }
+ end
+ changes[:remove].each { |name| state.remove(name) } if changes[:remove]
+ @state = state
+ @message = message
+ @hash = generate_hash
+ @date = Time.now
+ @result = result
+ end
+
+ def include?(name)
+ @state.has_key?(name)
+ end
+
+ def generate_hash
+ @hash = Digest::SHA1.hexdigest(Date.today.to_s + @message)
+ end
+
+ def log
+ "Commit #{@hash}\nDate: #{@time.asctime}\n\n\t#{message}"
+ end
+
+ alias objects state
+end
+
+class ObjectStore
+ def self.init(&block)
+ ObjectStore.new(&block)
+ end
+
+ def initialize
+ @current_branch = Branch.new("master")
+ @head = @current_branch.head
+ @branches = [@current_branch]
+ yield if block_given?
+ end
+
+ def log
+ @current_branch.log
+ end
+
+ def add(name, object)
+ @current_branch.add(name, object)
+ end
+
+ def commit(message)
+ @current_branch.commit(message)
+ end
+
+ def remove(name)
+ @current_branch.remove(name)
+ end
+
+ def branch
+ @current_branch
+ end
+
+ def head
+ @current_branch.head
+ end
+end
+
+class Result
+ attr_reader :message, :result
+
+ def initialize(message, success, result = nil)
+ @message = message
+ @success = success
+ @result = result
+ end
+
+ def success?
+ not not @success
+ end
+
+ def error?
+ not @success
+ end
+end