Решение на Пета задача от Изтрит профил

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

Към профила на Изтрит профил

Резултати

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

Код

require 'digest/sha1'
class ObjectStore
def self.init(&f)
repo = Repo.new()
repo.instance_eval(&f) if block_given?
repo
end
end
class Repo
def initialize
@added_objects = {}
@removed_objects = {}
@branches_objects_map = {}
@branches_map = {}
@current_branch = "master"
callback = lambda { |branch| @current_branch = branch }
@branch = Branch.new(@branches_map, @branches_objects_map, callback)
@branch.create("master")
@branch.checkout("master")
end
def add(name, object)
@added_objects[name] = object
Result.new("Added #{name} to stage.", :success, object)
end
def commit(message)
if @added_objects.empty? and @removed_objects.empty?
Result.new("Nothing to commit, working directory clean.", :error)
else
num_changed = @added_objects.length + @removed_objects.length
objects = merge_objects()
commit = Commit.new(message, Time.now, objects.values)
@branches_map[@current_branch].push(commit)
@added_objects = {}
@removed_objects = {}
Result.new("#{message}\n\t#{num_changed} " +
"objects changed", :success, commit)
end
end
def merge_objects
objects = @branches_objects_map[@current_branch]
objects.merge!(@added_objects)
objects.delete_if { |key, value| @removed_objects.has_key? key }
objects
end
def remove(name)
obj = @branches_objects_map[@current_branch][name]
if obj
@removed_objects[name] = obj
Result.new("Added #{name} for removal.", :success, obj)
else
Result.new("Object #{name} is not committed.", :error)
end
end
def checkout(commit_hash)
new_commits = []
current_commit = nil
@branches_map[@current_branch].each do |commit|
new_commits.push(commit)
if commit.hash == commit_hash
current_commit = commit
break
end
end
@branches_map[@current_branch] = new_commits
if current_commit
Result.new("HEAD is now at #{commit_hash}.", :success, current_commit)
else
Result.new("Commit #{commit_hash} does not exist.", :error)
end
end
def branch
@branch
end
def log
commits = @branches_map[@current_branch]
if commits.empty?
Result.new("Branch #{@current_branch} " +
"does not have any commits yet.", :error)
else
logs = []
commits.each do |commit|
logs.push(commit.log)
end
Result.new(logs.join("\n\n"), :success)
end
end
def head
commits = @branches_map[@current_branch]
if commits.empty?
Result.new("Branch #{current_branch} " +
"does not have any commits yet.", :error)
else
Result.new(commits.last.message, :success, commits.last)
end
end
def get(name)
commits = @branches_map[@current_branch]
obj = @branches_objects_map[@current_branch][name]
if commits.last && commits.last.objects.include?(obj)
Result.new("Found object #{name}.", :success, obj)
else
Result.new("Object #{name} is not committed.", :error)
end
end
end
class Branch
def initialize(branches_map, branches_objects_map, checkout_callback)
@branches_map = branches_map
@branches_objects_map = branches_objects_map
@checkout_callback = checkout_callback
end
def create(branch_name)
if @branches_map.has_key? branch_name
Result.new("Branch #{branch_name} already exists.", :error)
else
@branches_map[branch_name] =
@current_branch ? @branches_map[@current_branch].dup : []
@branches_objects_map[branch_name] =
@current_branch ? @branches_objects_map[@current_branch].clone : {}
Result.new("Created branch #{branch_name}.", :success)
end
end
def checkout(branch_name)
if not @branches_map[branch_name]
Result.new("Branch #{branch_name} does not exist.", :error)
else
@current_branch = branch_name
@checkout_callback.call(branch_name)
Result.new("Switched to branch #{branch_name}.", :success)
end
end
def remove(branch_name)
if not @branches_map[branch_name]
Result.new("Branch #{branch_name} does not exist.", :error)
elsif branch_name == @current_branch
Result.new("Cannot remove current branch.", :error)
else
@branches_map.delete(branch_name)
@branches_objects_map.delete(branch_name)
Result.new("Removed branch #{branch_name}.", :success)
end
end
def list
result = []
@branches_map.keys.sort!.each do |name|
if name == @current_branch
result.push("* #{name}")
else
result.push(" #{name}")
end
end
Result.new(result.join("\n"), :success)
end
end
class Commit
def initialize(message, date, objects)
@message = message
@date = date
@objects = objects
date_str = date.strftime("%a %b %d %H:%M:%S %Y %z")
@hash = Digest::SHA1.hexdigest "#{date_str}#{@message}"
end
def hash
@hash
end
def message
@message
end
def objects
@objects
end
def date
@date
end
def log
date_str = date
"Commit #{@hash}\nDate: #{date_str}\n\n\t#{@message}"
end
end
class Result
def initialize(message, state, result = nil)
@message = message
@state = state
@result = result
if result
define_singleton_method(:result) do
@result
end
end
end
def message
@message
end
def success?
@state == :success
end
def error?
@state == :error
end
end

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

.......FFFFF..................

Failures:

  1) ObjectStore cannot show head for empty repository
     Failure/Error: expect(repo.head).to be_error("Branch master does not have any commits yet.")
     NameError:
       undefined local variable or method `current_branch' for #<Repo:0x007f14c90dbc60>
     # /tmp/d20160111-5693-kt5bdj/solution.rb:107:in `head'
     # /tmp/d20160111-5693-kt5bdj/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)>'

  2) ObjectStore can show log of changes for a single commit
     Failure/Error: expect(repo.log).to be_success("Commit #{commit_hash}\nDate: #{Time.now.strftime("%a %b %d %H:%M %Y %z")}\n\n\tSo cool!")
       expected #<Result:0x007f14c90d7c28 @message="Commit 46d61710f8c683a754b8a295b217f12ef3cfb95f\nDate: 2016-01-11 11:55:24 +0200\n\n\tSo cool!", @state=:success, @result=nil> to be success "Commit 020f94292ff683fc536310fe33c03adfbf64bbca\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tSo cool!"
     # /tmp/d20160111-5693-kt5bdj/spec.rb:83: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: expect(repo.log).to be_success("Commit #{commit_hash}\nDate: #{Time.now.strftime("%a %b %d %H:%M %Y %z")}\n\n\tSo cool!")
       expected #<Result:0x007f14c90d2818 @message="Commit 46d61710f8c683a754b8a295b217f12ef3cfb95f\nDate: 2016-01-11 11:55:24 +0200\n\n\tSo cool!", @state=:success, @result=nil> to be success "Commit 020f94292ff683fc536310fe33c03adfbf64bbca\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tSo cool!"
     # /tmp/d20160111-5693-kt5bdj/spec.rb:92: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 multiple commits
     Failure/Error: expect(repo.log).to be_success("Commit #{commit2_hash}\nDate: #{current_time}\n\n\tSecond commit\n\nCommit #{commit1_hash}\nDate: #{current_time}\n\n\tFirst commit")
       expected #<Result:0x007f14c90c0cd0 @message="Commit 3793da810cdc9d4ea32c02cb58506226d69166d4\nDate: 2016-01-11 11:55:24 +0200\n\n\tFirst commit\n\nCommit 5ea4d7c889cf057c4651151832f5f510333b5dc8\nDate: 2016-01-11 11:55:24 +0200\n\n\tSecond commit", @state=:success, @result=nil> to be success "Commit a6bf7130a3150d375443c25d06c1bf8077e4b4fb\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tSecond commit\n\nCommit 9a97b358afe869ba1e523d99dd2101dfc0570dc0\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tFirst commit"
     # /tmp/d20160111-5693-kt5bdj/spec.rb:108: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 shows the log for the current branch only
     Failure/Error: expect(repo.log).to be_success("Commit #{commit1_hash}\nDate: #{current_time}\n\n\tFirst commit")
       expected #<Result:0x007f14c90ba4e8 @message="Commit 3793da810cdc9d4ea32c02cb58506226d69166d4\nDate: 2016-01-11 11:55:24 +0200\n\n\tFirst commit", @state=:success, @result=nil> to be success "Commit 9a97b358afe869ba1e523d99dd2101dfc0570dc0\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tFirst commit"
     # /tmp/d20160111-5693-kt5bdj/spec.rb:128: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.0305 seconds
30 examples, 5 failures

Failed examples:

rspec /tmp/d20160111-5693-kt5bdj/spec.rb:72 # ObjectStore cannot show head for empty repository
rspec /tmp/d20160111-5693-kt5bdj/spec.rb:77 # ObjectStore can show log of changes for a single commit
rspec /tmp/d20160111-5693-kt5bdj/spec.rb:86 # ObjectStore can show log of changes for a single commit
rspec /tmp/d20160111-5693-kt5bdj/spec.rb:95 # ObjectStore can show log of changes for multiple commits
rspec /tmp/d20160111-5693-kt5bdj/spec.rb:111 # ObjectStore shows the log for the current branch only

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

Изтрит обнови решението на 21.11.2015 05:38 (преди около 9 години)

+require 'digest/sha1'
+
+class ObjectStore
+ def self.init(&f)
+ repo = Repo.new()
+ repo.instance_eval(&f) if block_given?
+ repo
+ end
+end
+
+class Repo
+ def initialize
+ @added_objects = {}
+ @removed_objects = {}
+ @branches_objects_map = {}
+ @branches_map = {}
+ @current_branch = "master"
+
+ callback = lambda { |branch| @current_branch = branch }
+ @branch = Branch.new(@branches_map, @branches_objects_map, callback)
+ @branch.create("master")
+ @branch.checkout("master")
+ end
+
+ def add(name, object)
+ @added_objects[name] = object
+ Result.new("Added #{name} to stage.", :success, object)
+ end
+
+ def commit(message)
+ if @added_objects.empty? and @removed_objects.empty?
+ Result.new("Nothing to commit, working directory clean.", :error)
+ else
+ num_changed = @added_objects.length + @removed_objects.length
+
+ objects = merge_objects()
+
+ commit = Commit.new(message, Time.now, objects.values)
+ @branches_map[@current_branch].push(commit)
+ @added_objects = {}
+ @removed_objects = {}
+ Result.new("#{message}\n\t#{num_changed} " +
+ "objects changed", :success, commit)
+ end
+ end
+
+ def merge_objects
+ objects = @branches_objects_map[@current_branch]
+ objects.merge!(@added_objects)
+ objects.delete_if { |key, value| @removed_objects.has_key? key }
+ objects
+ end
+
+ def remove(name)
+ obj = @branches_objects_map[@current_branch][name]
+ if obj
+ @removed_objects[name] = obj
+ Result.new("Added #{name} for removal.", :success, obj)
+ else
+ Result.new("Object #{name} is not committed.", :error)
+ end
+ end
+
+ def checkout(commit_hash)
+ new_commits = []
+ current_commit = nil
+
+ @branches_map[@current_branch].each do |commit|
+ new_commits.push(commit)
+ if commit.hash == commit_hash
+ current_commit = commit
+ break
+ end
+ end
+
+ @branches_map[@current_branch] = new_commits
+
+ if current_commit
+ Result.new("HEAD is now at #{commit_hash}.", :success, current_commit)
+ else
+ Result.new("Commit #{commit_hash} does not exist.", :error)
+ end
+ end
+
+ def branch
+ @branch
+ end
+
+ def log
+ commits = @branches_map[@current_branch]
+ if commits.empty?
+ Result.new("Branch #{@current_branch} " +
+ "does not have any commits yet.", :error)
+ else
+ logs = []
+ commits.each do |commit|
+ logs.push(commit.log)
+ end
+
+ Result.new(logs.join("\n\n"), :success)
+ end
+ end
+
+ def head
+ commits = @branches_map[@current_branch]
+ if commits.empty?
+ Result.new("Branch #{current_branch} " +
+ "does not have any commits yet.", :error)
+ else
+ Result.new(commits.last.message, :success, commits.last)
+ end
+ end
+
+ def get(name)
+ commits = @branches_map[@current_branch]
+ obj = @branches_objects_map[@current_branch][name]
+
+ if commits.last && commits.last.objects.include?(obj)
+ Result.new("Found object #{name}.", :success, obj)
+ else
+ Result.new("Object #{name} is not committed.", :error)
+ end
+ end
+end
+
+class Branch
+ def initialize(branches_map, branches_objects_map, checkout_callback)
+ @branches_map = branches_map
+ @branches_objects_map = branches_objects_map
+ @checkout_callback = checkout_callback
+ end
+
+ def create(branch_name)
+ if @branches_map.has_key? branch_name
+ Result.new("Branch #{branch_name} already exists.", :error)
+ else
+ @branches_map[branch_name] =
+ @current_branch ? @branches_map[@current_branch].dup : []
+ @branches_objects_map[branch_name] =
+ @current_branch ? @branches_objects_map[@current_branch].clone : {}
+ Result.new("Created branch #{branch_name}.", :success)
+ end
+ end
+
+ def checkout(branch_name)
+ if not @branches_map[branch_name]
+ Result.new("Branch #{branch_name} does not exist.", :error)
+ else
+ @current_branch = branch_name
+ @checkout_callback.call(branch_name)
+ Result.new("Switched to branch #{branch_name}.", :success)
+ end
+ end
+
+ def remove(branch_name)
+ if not @branches_map[branch_name]
+ Result.new("Branch #{branch_name} does not exist.", :error)
+ elsif branch_name == @current_branch
+ Result.new("Cannot remove current branch.", :error)
+ else
+ @branches_map.delete(branch_name)
+ @branches_objects_map.delete(branch_name)
+ Result.new("Removed branch #{branch_name}.", :success)
+ end
+ end
+
+ def list
+ result = []
+ @branches_map.keys.sort!.each do |name|
+ if name == @current_branch
+ result.push("* #{name}")
+ else
+ result.push(" #{name}")
+ end
+ end
+
+ Result.new(result.join("\n"), :success)
+ end
+end
+
+class Commit
+ def initialize(message, date, objects)
+ @message = message
+ @date = date
+ @objects = objects
+ date_str = date.strftime("%a %b %e %H:%M:%S %Y %z")
+ @hash = Digest::SHA1.hexdigest "#{date_str}#{@message}"
+ end
+
+ def hash
+ @hash
+ end
+
+ def message
+ @message
+ end
+
+ def objects
+ @objects
+ end
+
+ def date
+ @date
+ end
+
+ def log
+ date_str = date
+ "Commit #{@hash}\nDate: #{date_str}\n\n\t#{@message}"
+ end
+end
+
+class Result
+ def initialize(message, state, result = nil)
+ @message = message
+ @state = state
+ @result = result
+
+ if result
+ define_singleton_method(:result) do
+ @result
+ end
+ end
+ end
+
+ def message
+ @message
+ end
+
+ def success?
+ @state == :success
+ end
+
+ def error?
+ @state == :error
+ end
+end

Изтрит обнови решението на 21.11.2015 05:40 (преди около 9 години)

require 'digest/sha1'
class ObjectStore
def self.init(&f)
repo = Repo.new()
repo.instance_eval(&f) if block_given?
repo
end
end
class Repo
def initialize
@added_objects = {}
@removed_objects = {}
@branches_objects_map = {}
@branches_map = {}
@current_branch = "master"
callback = lambda { |branch| @current_branch = branch }
@branch = Branch.new(@branches_map, @branches_objects_map, callback)
@branch.create("master")
@branch.checkout("master")
end
def add(name, object)
@added_objects[name] = object
Result.new("Added #{name} to stage.", :success, object)
end
def commit(message)
if @added_objects.empty? and @removed_objects.empty?
Result.new("Nothing to commit, working directory clean.", :error)
else
num_changed = @added_objects.length + @removed_objects.length
objects = merge_objects()
commit = Commit.new(message, Time.now, objects.values)
@branches_map[@current_branch].push(commit)
@added_objects = {}
@removed_objects = {}
Result.new("#{message}\n\t#{num_changed} " +
"objects changed", :success, commit)
end
end
def merge_objects
objects = @branches_objects_map[@current_branch]
objects.merge!(@added_objects)
objects.delete_if { |key, value| @removed_objects.has_key? key }
objects
end
def remove(name)
obj = @branches_objects_map[@current_branch][name]
if obj
@removed_objects[name] = obj
Result.new("Added #{name} for removal.", :success, obj)
else
Result.new("Object #{name} is not committed.", :error)
end
end
def checkout(commit_hash)
new_commits = []
current_commit = nil
@branches_map[@current_branch].each do |commit|
new_commits.push(commit)
if commit.hash == commit_hash
current_commit = commit
break
end
end
@branches_map[@current_branch] = new_commits
if current_commit
Result.new("HEAD is now at #{commit_hash}.", :success, current_commit)
else
Result.new("Commit #{commit_hash} does not exist.", :error)
end
end
def branch
@branch
end
def log
commits = @branches_map[@current_branch]
if commits.empty?
Result.new("Branch #{@current_branch} " +
"does not have any commits yet.", :error)
else
logs = []
commits.each do |commit|
logs.push(commit.log)
end
Result.new(logs.join("\n\n"), :success)
end
end
def head
commits = @branches_map[@current_branch]
if commits.empty?
Result.new("Branch #{current_branch} " +
"does not have any commits yet.", :error)
else
Result.new(commits.last.message, :success, commits.last)
end
end
def get(name)
commits = @branches_map[@current_branch]
obj = @branches_objects_map[@current_branch][name]
if commits.last && commits.last.objects.include?(obj)
Result.new("Found object #{name}.", :success, obj)
else
Result.new("Object #{name} is not committed.", :error)
end
end
end
class Branch
def initialize(branches_map, branches_objects_map, checkout_callback)
@branches_map = branches_map
@branches_objects_map = branches_objects_map
@checkout_callback = checkout_callback
end
def create(branch_name)
if @branches_map.has_key? branch_name
Result.new("Branch #{branch_name} already exists.", :error)
else
@branches_map[branch_name] =
@current_branch ? @branches_map[@current_branch].dup : []
@branches_objects_map[branch_name] =
@current_branch ? @branches_objects_map[@current_branch].clone : {}
Result.new("Created branch #{branch_name}.", :success)
end
end
def checkout(branch_name)
if not @branches_map[branch_name]
Result.new("Branch #{branch_name} does not exist.", :error)
else
@current_branch = branch_name
@checkout_callback.call(branch_name)
Result.new("Switched to branch #{branch_name}.", :success)
end
end
def remove(branch_name)
if not @branches_map[branch_name]
Result.new("Branch #{branch_name} does not exist.", :error)
elsif branch_name == @current_branch
Result.new("Cannot remove current branch.", :error)
else
@branches_map.delete(branch_name)
@branches_objects_map.delete(branch_name)
Result.new("Removed branch #{branch_name}.", :success)
end
end
def list
result = []
@branches_map.keys.sort!.each do |name|
if name == @current_branch
result.push("* #{name}")
else
result.push(" #{name}")
end
end
Result.new(result.join("\n"), :success)
end
end
class Commit
def initialize(message, date, objects)
@message = message
@date = date
@objects = objects
- date_str = date.strftime("%a %b %e %H:%M:%S %Y %z")
+ date_str = date.strftime("%a %b %d %H:%M:%S %Y %z")
@hash = Digest::SHA1.hexdigest "#{date_str}#{@message}"
end
def hash
@hash
end
def message
@message
end
def objects
@objects
end
def date
@date
end
def log
date_str = date
"Commit #{@hash}\nDate: #{date_str}\n\n\t#{@message}"
end
end
class Result
def initialize(message, state, result = nil)
@message = message
@state = state
@result = result
if result
define_singleton_method(:result) do
@result
end
end
end
def message
@message
end
def success?
@state == :success
end
def error?
@state == :error
end
end