Решение на Пета задача от Георги Стефанов

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

Към профила на Георги Стефанов

Резултати

  • 5 точки от тестове
  • 0 бонус точки
  • 5 точки общо
  • 23 успешни тест(а)
  • 7 неуспешни тест(а)

Код

require 'digest/sha1'
class Feedback
attr_accessor :message
def initialize(message, success, result = nil)
@message = message
@success = success
@result = result
end
def success?
@success == true
end
def error?
@success == false
end
def result
@result == nil ?
begin raise NoMethodError, "No 'result' method for this action." end :
@result
end
end
class ObjectStore
attr_accessor :stage, :deleted, :branches, :current_branch
def self.init(&block)
repository, repository.stage, repository.deleted = self.new, {}, {}
master_branch = Branch.new("master", repository)
repository.branches, repository.current_branch = [], master_branch
repository.branches << master_branch
repository.instance_eval(&block) if block_given?
repository
end
def add(name, object)
stage[name] = object
message = "Added #{name} to stage."
Feedback.new(message, true, object)
end
def has_commits?
branch.commits.any?
end
def remove(name)
error = "Object #{name} is not committed."
success = "Added #{name} for removal."
object = current_branch.commits.last.state[name] if has_commits?
object = nil unless has_commits?
deleted[name] = object if object
object ? Feedback.new(success, true, object) :
Feedback.new(error, false)
end
def commit(message)
changed, count = (stage.any? or deleted.any?), stage.merge(deleted).size
error = "Nothing to commit, working directory clean."
success = "#{message}" + "\n\t#{count} objects changed."
new_state = {}.merge(stage).reject { |name| deleted.has_key?(name) }
new_state = branch.commits.last.state.merge(stage).
reject { |name| deleted.has_key?(name) } if has_commits?
result = Commit.new(new_state, message)
current_branch.commits.push(result) if changed
@stage, @deleted = {}, {}
changed ? Feedback.new(success, true, result) : Feedback.new(error, false)
end
def checkout(commit_hash)
error = "Commit #{commit_hash} does not exist."
success = "HEAD is now at #{commit_hash}."
hash_values = branch.commits.map { |commit| commit.hash }
has_hash = hash_values.include?(commit_hash)
last_commit = hash_values.find_index(commit_hash) if has_hash
branch.commits.slice!(last_commit + 1...branch.commits.size) if has_hash
result = branch.commits.last
has_hash ? Feedback.new(success, true, result) : Feedback.new(error, false)
end
def branch
current_branch
end
def log
error = "Branch #{branch.name} does not have any commits yet."
success = branch.commits.map do |commit|
"Commit #{ commit.hash }\nDate: " \
"#{ commit.date }\n\n\t#{ commit.message }"
end
success = success.reverse.join("\n\n")
has_commits? ? Feedback.new(success, true) : Feedback.new(error, false)
end
def get(name)
error = "Object #{ name } is not committed."
success = "Found object #{ name }."
result = branch.commits.last.state[name] if has_commits?
is_committed = branch.commits.last.state.has_key?(name) if has_commits?
(has_commits? and is_committed) ? Feedback.new(success, true, result) :
Feedback.new(error, false)
end
def head
error = "Branch #{ branch.name } does not have any commits yet."
success = "#{ branch.commits.last.message }" if has_commits?
result = branch.commits.last if has_commits?
has_commits? ? Feedback.new(success, true, result) :
Feedback.new(error, false)
end
end
class Branch
attr_accessor :name, :repository, :commits
def initialize(name, repository)
@name = name
@repository = repository
@commits = []
end
def has_branch?(name)
repository.branches.any? { |branch| branch.name == name }
end
def create(name)
success = "Created branch #{ name }."
error = "Branch #{ name } already exists."
name_taken = has_branch?(name)
branch_out = Branch.new(name, repository) unless name_taken
branch_out.commits = commits.dup unless name_taken
repository.branches << branch_out unless name_taken
name_taken ? Feedback.new(error, false) :
Feedback.new(success, true)
end
def checkout(name)
success = "Switched to branch #{ name }."
error = "Branch #{ name } does not exist."
new_current = nil
repository.branches.each do |branch|
new_current = branch if branch.name == name
end
repository.current_branch = new_current if new_current
new_current ? Feedback.new(success, true) : Feedback.new(error, false)
end
def remove(name)
success = "Removed branch #{ name }."
error_current = "Cannot remove current branch."
no_branch = "Branch #{ name } does not exist."
is_current = name == repository.branch.name
no_problem = (has_branch?(name) and not is_current)
repository.branches.keep_if { |branch| branch.name != name } if no_problem
no_problem ? Feedback.new(success, true) :
is_current ? Feedback.new(error_current, false) :
Feedback.new(no_branch, false)
end
def list
named = repository.branches.map { |branch| branch.name }
sorted = named.sort!
sorted.
map! { |name| name == repository.branch.name ? " *" + name : " " + name }
message = sorted.join("\n")
Feedback.new("#{ message }", true)
end
end
class Commit
attr_accessor :state, :message
def initialize(state, message)
@state = state
@message = message
@date = Time.now
end
def date
@date.strftime('%a %b %-d %H:%M %Y %z')
end
def hash
Digest::SHA1.hexdigest(date.to_s + message)
end
def objects
state.values
end
end

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

.F..F...FFFF.F................

Failures:

  1) ObjectStore can commit objects
     Failure/Error: expect(repo.commit("So cool!")).to be_success("So cool!\n\t2 objects changed", repo.head.result)
       expected #<Feedback:0x007f40a19d3580 @message="So cool!\n\t2 objects changed.", @success=true, @result=#<Commit:0x007f40a19d3620 @state={"object1"=>"content1", "object2"=>"content2"}, @message="So cool!", @date=2016-01-11 11:55:14 +0200>> to be success "So cool!\n\t2 objects changed" and #<Commit:0x007f40a19d3620 @state={"object1"=>"content1", "object2"=>"content2"}, @message="So cool!", @date=2016-01-11 11:55:14 +0200>
     # /tmp/d20160111-5693-1821gb6/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 can commit changes which include only removed objects
     Failure/Error: expect(repo.commit("Removed object2")).to be_success("Removed object2\n\t1 objects changed", repo.head.result)
       expected #<Feedback:0x007f40a16417c8 @message="Removed object2\n\t1 objects changed.", @success=true, @result=#<Commit:0x007f40a1641bd8 @state={"object1"=>"content1"}, @message="Removed object2", @date=2016-01-11 11:55:14 +0200>> to be success "Removed object2\n\t1 objects changed" and #<Commit:0x007f40a1641bd8 @state={"object1"=>"content1"}, @message="Removed object2", @date=2016-01-11 11:55:14 +0200>
     # /tmp/d20160111-5693-1821gb6/spec.rb:53: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 show log of changes for a single commit
     Failure/Error: commit_hash = Digest::SHA1.hexdigest("#{commit.date.strftime("%a %b %d %H:%M %Y %z")}#{commit.message}")
     NoMethodError:
       undefined method `strftime' for "Mon Jan 11 11:55 2016 +0200":String
     # /tmp/d20160111-5693-1821gb6/spec.rb:82: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 show log of changes for a single commit
     Failure/Error: commit_hash = Digest::SHA1.hexdigest("#{commit.date.strftime("%a %b %d %H:%M %Y %z")}#{commit.message}")
     NoMethodError:
       undefined method `strftime' for "Mon Jan 11 11:55 2016 +0200":String
     # /tmp/d20160111-5693-1821gb6/spec.rb:91: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 can show log of changes for multiple commits
     Failure/Error: commit1_hash = Digest::SHA1.hexdigest("#{commit1.date.strftime(time_format)}#{commit1.message}")
     NoMethodError:
       undefined method `strftime' for "Mon Jan 11 11:55 2016 +0200":String
     # /tmp/d20160111-5693-1821gb6/spec.rb:105: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 shows the log for the current branch only
     Failure/Error: commit1_hash = Digest::SHA1.hexdigest("#{commit1.date.strftime(time_format)}#{commit1.message}")
     NoMethodError:
       undefined method `strftime' for "Mon Jan 11 11:55 2016 +0200":String
     # /tmp/d20160111-5693-1821gb6/spec.rb:126: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 can list branches
     Failure/Error: expect(repo.branch.list).to be_success("  develop\n  feature\n* master")
       expected #<Feedback:0x007f40a15502d8 @message="  develop\n  feature\n *master", @success=true, @result=nil> to be success "  develop\n  feature\n* master"
     # /tmp/d20160111-5693-1821gb6/spec.rb:140: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.03258 seconds
30 examples, 7 failures

Failed examples:

rspec /tmp/d20160111-5693-1821gb6/spec.rb:26 # ObjectStore can commit objects
rspec /tmp/d20160111-5693-1821gb6/spec.rb:46 # ObjectStore can commit changes which include only removed objects
rspec /tmp/d20160111-5693-1821gb6/spec.rb:77 # ObjectStore can show log of changes for a single commit
rspec /tmp/d20160111-5693-1821gb6/spec.rb:86 # ObjectStore can show log of changes for a single commit
rspec /tmp/d20160111-5693-1821gb6/spec.rb:95 # ObjectStore can show log of changes for multiple commits
rspec /tmp/d20160111-5693-1821gb6/spec.rb:111 # ObjectStore shows the log for the current branch only
rspec /tmp/d20160111-5693-1821gb6/spec.rb:136 # ObjectStore can list branches

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

Георги обнови решението на 23.11.2015 14:30 (преди над 8 години)

+require 'digest/sha1'
+
+class Feedback
+ def initialize(message, success, result = nil)
+ @message = message
+ @success = success
+ @result = result
+ end
+
+ def message
+ @message
+ end
+
+ def success?
+ @success == true
+ end
+
+ def error?
+ @success == false
+ end
+
+ def result
+ @result == nil ?
+ begin raise NoMethodError, "No 'result' method for this action." end :
+ @result
+ end
+end
+
+class ObjectStore
+ attr_accessor :stage, :deleted, :branches, :current_branch
+
+ def self.init(&block)
+ repository, repository.stage, repository.deleted = self.new, {}, {}
+ master_branch = Branch.new("master", repository)
+
+ repository.branches, repository.current_branch = [], master_branch
+ repository.branches << master_branch
+
+ repository.instance_eval(&block) if block_given?
+ repository
+ end
+
+ def add(name, object)
+ stage[name] = object
+ message = "Added #{name} to stage."
+
+ Feedback.new(message, true, object)
+ end
+
+ def has_commits?
+ branch.commits.any?
+ end
+
+
+ def remove(name)
+ error = "Object #{name} is not committed."
+ success = "Added #{name} for removal."
+
+ object = current_branch.commits.last.state[name] if has_commits?
+ object = nil unless has_commits?
+ deleted[name] = object if object
+
+
+ object ? Feedback.new(success, true, object) :
+ Feedback.new(error, false)
+ end
+
+ def commit(message)
+ changed, count = (stage.any? or deleted.any?), stage.merge(deleted).size
+ error = "Nothing to commit, working directory clean."
+ success = "#{message}" + "\n\t#{count} objects changed."
+
+ new_state = {}.merge(stage).reject { |name| deleted.has_key?(name) }
+
+ new_state = branch.commits.last.state.merge(stage).
+ reject { |name| deleted.has_key?(name) } if has_commits?
+
+ result = Commit.new(new_state, message)
+ current_branch.commits.push(result) if changed
+
+ @stage, @deleted = {}, {}
+ changed ? Feedback.new(success, true, result) : Feedback.new(error, false)
+ end
+
+ def checkout(commit_hash)
+ error = "Commit #{commit_hash} does not exist."
+ success = "HEAD is now at #{commit_hash}."
+
+ hash_values = branch.commits.map { |commit| commit.hash }
+ has_hash = hash_values.include?(commit_hash)
+
+ last_commit = hash_values.find_index(commit_hash) if has_hash
+ branch.commits.slice!(last_commit + 1...branch.commits.size) if has_hash
+ result = branch.commits.last
+
+ has_hash ? Feedback.new(success, true, result) : Feedback.new(error, false)
+ end
+
+ def branch
+ current_branch
+ end
+
+ def log
+ error = "Branch #{branch.name} does not have any commits yet."
+
+ success = branch.commits.map do |commit|
+ "Commit #{ commit.hash }\nDate: " \
+ "#{ commit.date }\n\n\t#{ commit.message }"
+ end
+ success = success.reverse.join("\n\n")
+
+ has_commits? ? Feedback.new(success, true) : Feedback.new(error, false)
+ end
+
+ def get(name)
+ error = "Object #{ name } is not committed."
+ success = "Found object #{ name }."
+
+ result = branch.commits.last.state[name] if has_commits?
+ is_committed = branch.commits.last.state.has_key?(name) if has_commits?
+
+ (has_commits? and is_committed) ? Feedback.new(success, true, result) :
+ Feedback.new(error, false)
+ end
+
+ def head
+ error = "Branch #{ branch.name } does not have any commits yet."
+ success = "#{ branch.commits.last.message }" if has_commits?
+ result = branch.commits.last if has_commits?
+
+ has_commits? ? Feedback.new(success, true, result) :
+ Feedback.new(error, false)
+ end
+
+end
+
+class Branch
+ attr_accessor :name, :repository, :commits
+
+ def initialize(name, repository)
+ @name = name
+ @repository = repository
+ @commits = []
+ end
+
+ def has_branch?(name)
+ repository.branches.any? { |branch| branch.name == name }
+ end
+
+ def create(name)
+ success = "Created branch #{ name }."
+ error = "Branch #{ name } already exists."
+
+ name_taken = has_branch?(name)
+
+ branch_out = Branch.new(name, repository) unless name_taken
+ branch_out.commits = commits.dup unless name_taken
+ repository.branches << branch_out unless name_taken
+
+ name_taken ? Feedback.new(error, false) :
+ Feedback.new(success, true)
+ end
+
+ def checkout(name)
+ success = "Switched to branch #{ name }."
+ error = "Branch #{ name } does not exist."
+
+ new_current = nil
+ repository.branches.each do |branch|
+ new_current = branch if branch.name == name
+ end
+ repository.current_branch = new_current if new_current
+
+ new_current ? Feedback.new(success, true) : Feedback.new(error, false)
+ end
+
+ def remove(name)
+ success = "Removed branch #{ name }."
+ error_current = "Cannot remove current branch."
+ no_branch = "Branch #{ name } does not exist."
+
+ is_current = name == repository.branch.name
+ no_problem = (has_branch?(name) and not is_current)
+
+ repository.branches.keep_if { |branch| branch.name != name } if no_problem
+ return Feedback.new(success, true) if no_problem
+
+ return Feedback.new(error_current, false) if is_current
+ return Feedback.new(no_branch, false) if has_branch?(name) == false
+ end
+
+ def list
+ named = repository.branches.map { |branch| branch.name }
+ sorted = named.sort!
+
+ sorted.
+ map! { |name| name == repository.branch.name ? " *" + name : " " + name }
+ message = sorted.join("\n")
+
+ Feedback.new("#{ message }", true)
+ end
+
+end
+
+class Commit
+ attr_accessor :state, :message
+
+ def initialize(state, message)
+ @state = state
+ @message = message
+ @date = Time.now
+ end
+
+ def date
+ @date.strftime('%a %b %-d %H:%M %Y %z')
+ end
+
+ def hash
+ Digest::SHA1.hexdigest(date.to_s + message)
+ end
+
+ def objects
+ state.values
+ end
+end

Георги обнови решението на 23.11.2015 14:40 (преди над 8 години)

require 'digest/sha1'
class Feedback
+ attr_accessor :message
+
def initialize(message, success, result = nil)
@message = message
@success = success
@result = result
- end
-
- def message
- @message
end
def success?
@success == true
end
def error?
@success == false
end
def result
@result == nil ?
begin raise NoMethodError, "No 'result' method for this action." end :
@result
end
end
class ObjectStore
attr_accessor :stage, :deleted, :branches, :current_branch
def self.init(&block)
repository, repository.stage, repository.deleted = self.new, {}, {}
master_branch = Branch.new("master", repository)
repository.branches, repository.current_branch = [], master_branch
repository.branches << master_branch
repository.instance_eval(&block) if block_given?
repository
end
def add(name, object)
stage[name] = object
message = "Added #{name} to stage."
Feedback.new(message, true, object)
end
def has_commits?
branch.commits.any?
end
def remove(name)
error = "Object #{name} is not committed."
success = "Added #{name} for removal."
object = current_branch.commits.last.state[name] if has_commits?
object = nil unless has_commits?
deleted[name] = object if object
object ? Feedback.new(success, true, object) :
Feedback.new(error, false)
end
def commit(message)
changed, count = (stage.any? or deleted.any?), stage.merge(deleted).size
error = "Nothing to commit, working directory clean."
success = "#{message}" + "\n\t#{count} objects changed."
new_state = {}.merge(stage).reject { |name| deleted.has_key?(name) }
new_state = branch.commits.last.state.merge(stage).
reject { |name| deleted.has_key?(name) } if has_commits?
result = Commit.new(new_state, message)
current_branch.commits.push(result) if changed
@stage, @deleted = {}, {}
changed ? Feedback.new(success, true, result) : Feedback.new(error, false)
end
def checkout(commit_hash)
error = "Commit #{commit_hash} does not exist."
success = "HEAD is now at #{commit_hash}."
hash_values = branch.commits.map { |commit| commit.hash }
has_hash = hash_values.include?(commit_hash)
last_commit = hash_values.find_index(commit_hash) if has_hash
branch.commits.slice!(last_commit + 1...branch.commits.size) if has_hash
result = branch.commits.last
has_hash ? Feedback.new(success, true, result) : Feedback.new(error, false)
end
def branch
current_branch
end
def log
error = "Branch #{branch.name} does not have any commits yet."
success = branch.commits.map do |commit|
"Commit #{ commit.hash }\nDate: " \
"#{ commit.date }\n\n\t#{ commit.message }"
end
success = success.reverse.join("\n\n")
has_commits? ? Feedback.new(success, true) : Feedback.new(error, false)
end
def get(name)
error = "Object #{ name } is not committed."
success = "Found object #{ name }."
result = branch.commits.last.state[name] if has_commits?
is_committed = branch.commits.last.state.has_key?(name) if has_commits?
(has_commits? and is_committed) ? Feedback.new(success, true, result) :
Feedback.new(error, false)
end
def head
error = "Branch #{ branch.name } does not have any commits yet."
success = "#{ branch.commits.last.message }" if has_commits?
result = branch.commits.last if has_commits?
has_commits? ? Feedback.new(success, true, result) :
Feedback.new(error, false)
end
end
class Branch
attr_accessor :name, :repository, :commits
def initialize(name, repository)
@name = name
@repository = repository
@commits = []
end
def has_branch?(name)
repository.branches.any? { |branch| branch.name == name }
end
def create(name)
success = "Created branch #{ name }."
error = "Branch #{ name } already exists."
name_taken = has_branch?(name)
branch_out = Branch.new(name, repository) unless name_taken
branch_out.commits = commits.dup unless name_taken
repository.branches << branch_out unless name_taken
name_taken ? Feedback.new(error, false) :
Feedback.new(success, true)
end
def checkout(name)
success = "Switched to branch #{ name }."
error = "Branch #{ name } does not exist."
new_current = nil
repository.branches.each do |branch|
new_current = branch if branch.name == name
end
repository.current_branch = new_current if new_current
new_current ? Feedback.new(success, true) : Feedback.new(error, false)
end
def remove(name)
success = "Removed branch #{ name }."
error_current = "Cannot remove current branch."
no_branch = "Branch #{ name } does not exist."
is_current = name == repository.branch.name
no_problem = (has_branch?(name) and not is_current)
repository.branches.keep_if { |branch| branch.name != name } if no_problem
return Feedback.new(success, true) if no_problem
return Feedback.new(error_current, false) if is_current
return Feedback.new(no_branch, false) if has_branch?(name) == false
end
def list
named = repository.branches.map { |branch| branch.name }
sorted = named.sort!
sorted.
map! { |name| name == repository.branch.name ? " *" + name : " " + name }
message = sorted.join("\n")
Feedback.new("#{ message }", true)
end
end
class Commit
attr_accessor :state, :message
def initialize(state, message)
@state = state
@message = message
@date = Time.now
end
def date
@date.strftime('%a %b %-d %H:%M %Y %z')
end
def hash
Digest::SHA1.hexdigest(date.to_s + message)
end
def objects
state.values
end
end

Георги обнови решението на 23.11.2015 14:47 (преди над 8 години)

require 'digest/sha1'
class Feedback
attr_accessor :message
def initialize(message, success, result = nil)
@message = message
@success = success
@result = result
end
def success?
@success == true
end
def error?
@success == false
end
def result
@result == nil ?
begin raise NoMethodError, "No 'result' method for this action." end :
@result
end
end
class ObjectStore
attr_accessor :stage, :deleted, :branches, :current_branch
def self.init(&block)
repository, repository.stage, repository.deleted = self.new, {}, {}
master_branch = Branch.new("master", repository)
repository.branches, repository.current_branch = [], master_branch
repository.branches << master_branch
repository.instance_eval(&block) if block_given?
repository
end
def add(name, object)
stage[name] = object
message = "Added #{name} to stage."
Feedback.new(message, true, object)
end
def has_commits?
branch.commits.any?
end
def remove(name)
error = "Object #{name} is not committed."
success = "Added #{name} for removal."
object = current_branch.commits.last.state[name] if has_commits?
object = nil unless has_commits?
deleted[name] = object if object
object ? Feedback.new(success, true, object) :
Feedback.new(error, false)
end
def commit(message)
changed, count = (stage.any? or deleted.any?), stage.merge(deleted).size
error = "Nothing to commit, working directory clean."
success = "#{message}" + "\n\t#{count} objects changed."
new_state = {}.merge(stage).reject { |name| deleted.has_key?(name) }
new_state = branch.commits.last.state.merge(stage).
reject { |name| deleted.has_key?(name) } if has_commits?
result = Commit.new(new_state, message)
current_branch.commits.push(result) if changed
@stage, @deleted = {}, {}
changed ? Feedback.new(success, true, result) : Feedback.new(error, false)
end
def checkout(commit_hash)
error = "Commit #{commit_hash} does not exist."
success = "HEAD is now at #{commit_hash}."
hash_values = branch.commits.map { |commit| commit.hash }
has_hash = hash_values.include?(commit_hash)
last_commit = hash_values.find_index(commit_hash) if has_hash
branch.commits.slice!(last_commit + 1...branch.commits.size) if has_hash
result = branch.commits.last
has_hash ? Feedback.new(success, true, result) : Feedback.new(error, false)
end
def branch
current_branch
end
def log
error = "Branch #{branch.name} does not have any commits yet."
success = branch.commits.map do |commit|
"Commit #{ commit.hash }\nDate: " \
"#{ commit.date }\n\n\t#{ commit.message }"
end
success = success.reverse.join("\n\n")
has_commits? ? Feedback.new(success, true) : Feedback.new(error, false)
end
def get(name)
error = "Object #{ name } is not committed."
success = "Found object #{ name }."
result = branch.commits.last.state[name] if has_commits?
is_committed = branch.commits.last.state.has_key?(name) if has_commits?
(has_commits? and is_committed) ? Feedback.new(success, true, result) :
Feedback.new(error, false)
end
def head
error = "Branch #{ branch.name } does not have any commits yet."
success = "#{ branch.commits.last.message }" if has_commits?
result = branch.commits.last if has_commits?
has_commits? ? Feedback.new(success, true, result) :
Feedback.new(error, false)
end
end
class Branch
attr_accessor :name, :repository, :commits
def initialize(name, repository)
@name = name
@repository = repository
@commits = []
end
def has_branch?(name)
repository.branches.any? { |branch| branch.name == name }
end
def create(name)
success = "Created branch #{ name }."
error = "Branch #{ name } already exists."
name_taken = has_branch?(name)
branch_out = Branch.new(name, repository) unless name_taken
branch_out.commits = commits.dup unless name_taken
repository.branches << branch_out unless name_taken
name_taken ? Feedback.new(error, false) :
Feedback.new(success, true)
end
def checkout(name)
success = "Switched to branch #{ name }."
error = "Branch #{ name } does not exist."
new_current = nil
repository.branches.each do |branch|
new_current = branch if branch.name == name
end
repository.current_branch = new_current if new_current
new_current ? Feedback.new(success, true) : Feedback.new(error, false)
end
def remove(name)
success = "Removed branch #{ name }."
error_current = "Cannot remove current branch."
no_branch = "Branch #{ name } does not exist."
is_current = name == repository.branch.name
no_problem = (has_branch?(name) and not is_current)
repository.branches.keep_if { |branch| branch.name != name } if no_problem
- return Feedback.new(success, true) if no_problem
- return Feedback.new(error_current, false) if is_current
- return Feedback.new(no_branch, false) if has_branch?(name) == false
+ no_problem ? Feedback.new(success, true) :
+ is_current ? Feedback.new(error_current, false) :
+ Feedback.new(no_branch, false)
end
def list
named = repository.branches.map { |branch| branch.name }
sorted = named.sort!
sorted.
map! { |name| name == repository.branch.name ? " *" + name : " " + name }
message = sorted.join("\n")
Feedback.new("#{ message }", true)
end
end
class Commit
attr_accessor :state, :message
def initialize(state, message)
@state = state
@message = message
@date = Time.now
end
def date
@date.strftime('%a %b %-d %H:%M %Y %z')
end
def hash
Digest::SHA1.hexdigest(date.to_s + message)
end
def objects
state.values
end
end