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

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

Към профила на Станимир Богданов

Резултати

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

Код

require 'digest/sha1'
class ObjectStore
def self.init(&block)
object_store = ObjectStore.new
object_store.instance_eval(&block) if block_given?
object_store
end
def add(name, object)
stage << [name, object, 'add']
ResponseWithResult.new("Added #{name} to stage.", true, object)
end
def commit(message)
if stage.empty?
Response.new("Nothing to commit, working directory clean.", false)
else
response_message = "#{message}\n\t#{stage.length} objects changed"
commit = @branch_manager.active_branch.add_commit(message)
ResponseWithResult.new(response_message, true, commit)
end
end
def remove(name)
object = @branch_manager.active_branch.get_object(name)
if object
stage << [name, object, 'remove']
ResponseWithResult.new("Added #{name} for removal.", true, object)
else
Response.new("Object #{name} is not committed.", false)
end
end
def checkout(commit_hash)
commit = @branch_manager.active_branch.get_commit(commit_hash)
if commit
@branch_manager.active_branch.head = commit
ResponseWithResult.new("HEAD is now at #{commit_hash}.", true, commit)
else
Response.new("Commit #{commit_hash} does not exist.", false)
end
end
def branch
@branch_manager
end
def log
commits = @branch_manager.active_branch.commits.reverse
if commits.empty?
branch_name = @branch_manager.active_branch.name
Response.new(
"Branch #{branch_name} does not have any commits yet.",
false
)
else
Response.new(build_log(commits), true)
end
end
def head
head = @branch_manager.active_branch.head
if head
ResponseWithResult.new(head.message, true, head)
else
branch_name = @branch_manager.active_branch.name
Response.new(
"Branch #{branch_name} does not have any commits yet.",
false
)
end
end
def get(name)
obj = @branch_manager.active_branch.get_object(name)
if obj
ResponseWithResult.new("Found object #{name}.", true, obj)
else
Response.new("Object #{name} is not committed.", false)
end
end
private
def initialize
@branch_manager = BranchManager.new
@branch_manager.create('master')
@branch_manager.set_active_branch('master')
end
def stage
@branch_manager.active_branch.stage
end
def build_log(commits)
commits.map do |commit|
"Commit #{commit.hash}\nDate: #{commit.formatted_date}" \
"\n\n\t#{commit.message}\n\n"
end.join.chomp.chomp
end
end
class Commit
attr_reader :objects, :hash, :date, :message
def initialize(message, date, stage, head)
@message = message
@date = date
@objects = fill_objects(stage, head)
@hash = gen_hash
end
def formatted_date
date.strftime("%a %b %d %H:%M %Y %z")
end
private
def gen_hash
Digest::SHA1.hexdigest("#{@date}#{@message}")
end
def fill_objects(stage, head)
to_be_added, to_be_removed = partition(stage)
objects = to_be_added.dup
objects += non_removed_objects(head, to_be_removed)
end
def non_removed_objects(head, to_be_removed)
head ? head.objects.reject { |obj| to_be_removed.include?(obj) } : []
end
def partition(stage)
stage.partition { |item| item[2] == 'add' }.map do |group|
group.map { |item| item.take(2) }
end
end
end
class Branch
attr_reader :name, :stage
attr_accessor :head
def initialize(name, commits = [])
@name = name
@stage = []
@commits = commits.dup
@head = @commits.last
end
def add_commit(message)
commit = Commit.new(message, Time.now, @stage, @head)
@commits << commit
@stage = []
@head = @commits.last
end
def get_object(name)
if head
entry = head.objects.select { |object| object[0] == name }.first
entry ? entry[1] : nil
end
end
def commits
head ? @commits.take_while { |commit| commit != head }.push(head) : []
end
def get_commit(commit_hash)
@commits.select { |commit| commit.hash == commit_hash }.first
end
end
class BranchManager
attr_reader :active_branch
def initialize
@branches = {}
end
def create(branch_name)
if @branches.keys.include?(branch_name)
Response.new("Branch #{branch_name} already exists.", false)
else
commits_in_current_branch = @active_branch ? @active_branch.commits : []
branch = Branch.new(branch_name, commits_in_current_branch)
@branches[branch_name] = branch
Response.new("Created branch #{branch_name}.", true)
end
end
def set_active_branch(branch_name)
@active_branch = @branches[branch_name]
end
def checkout(branch_name)
if @branches.keys.include?(branch_name)
set_active_branch(branch_name)
Response.new("Switched to branch #{branch_name}.", true)
else
Response.new("Branch #{branch_name} does not exist.", false)
end
end
def remove(branch_name)
if @branches.keys.include?(branch_name)
if branch_name == active_branch.name
Response.new("Cannot remove current branch.", false)
else
@branches.delete(branch_name)
Response.new("Removed branch #{branch_name}.", true)
end
else
Response.new("Branch #{branch_name} does not exist.", false)
end
end
def list
list = @branches.sort.map do |name, _|
name == active_branch.name ? "* #{name}\n" : " #{name}\n"
end.join.chomp
Response.new(list, true)
end
end
class Response
attr_reader :message
def initialize(message, status)
@message = message
@status = status
end
def success?
@status
end
def error?
not success?
end
end
class ResponseWithResult < Response
attr_reader :result
def initialize(message, status, result)
super(message, status)
@result = result
end
end

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

........FFFF................FF

Failures:

  1) 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 #<Response:0x007fae6ba7bb08 @message="Commit d6db186c82177a11d514bbd0e6a78fbe889c67c8\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tSo cool!", @status=true> to be success "Commit 020f94292ff683fc536310fe33c03adfbf64bbca\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tSo cool!"
     # /tmp/d20160111-5693-6zk20/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)>'

  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 #<Response:0x007fae6ba3b7d8 @message="Commit d6db186c82177a11d514bbd0e6a78fbe889c67c8\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tSo cool!", @status=true> to be success "Commit 020f94292ff683fc536310fe33c03adfbf64bbca\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tSo cool!"
     # /tmp/d20160111-5693-6zk20/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)>'

  3) 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 #<Response:0x007fae6ba172e8 @message="Commit d3e0f20e3d4b3fa1cc43401a11d2b007d196325a\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tSecond commit\n\nCommit acdd5e02d7c120bb175eaacd664d9eb01e53a169\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tFirst commit", @status=true> 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-6zk20/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)>'

  4) 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 #<Response:0x007fae6ba03018 @message="Commit acdd5e02d7c120bb175eaacd664d9eb01e53a169\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tFirst commit", @status=true> to be success "Commit 9a97b358afe869ba1e523d99dd2101dfc0570dc0\nDate: Mon Jan 11 11:55 2016 +0200\n\n\tFirst commit"
     # /tmp/d20160111-5693-6zk20/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)>'

  5) ObjectStore can show the objects in a repo after overwriting an object
     Failure/Error: expect(first_commit.objects).to match_array(["content1"])
       expected collection contained:  ["content1"]
       actual collection contained:    [["object1", "content1"]]
       the missing elements were:      ["content1"]
       the extra elements were:        [["object1", "content1"]]
     # /tmp/d20160111-5693-6zk20/spec.rb:243: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 the objects of a repo after removing an object
     Failure/Error: expect(first_commit.objects).to match_array(["content1", "content2", "content3"])
       expected collection contained:  ["content1", "content2", "content3"]
       actual collection contained:    [["object1", "content1"], ["object2", "content2"], ["object3", "content3"]]
       the missing elements were:      ["content1", "content2", "content3"]
       the extra elements were:        [["object1", "content1"], ["object2", "content2"], ["object3", "content3"]]
     # /tmp/d20160111-5693-6zk20/spec.rb:259: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.03845 seconds
30 examples, 6 failures

Failed examples:

rspec /tmp/d20160111-5693-6zk20/spec.rb:77 # ObjectStore can show log of changes for a single commit
rspec /tmp/d20160111-5693-6zk20/spec.rb:86 # ObjectStore can show log of changes for a single commit
rspec /tmp/d20160111-5693-6zk20/spec.rb:95 # ObjectStore can show log of changes for multiple commits
rspec /tmp/d20160111-5693-6zk20/spec.rb:111 # ObjectStore shows the log for the current branch only
rspec /tmp/d20160111-5693-6zk20/spec.rb:239 # ObjectStore can show the objects in a repo after overwriting an object
rspec /tmp/d20160111-5693-6zk20/spec.rb:253 # ObjectStore can show the objects of a repo after removing an object

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

Станимир обнови решението на 18.11.2015 10:22 (преди над 8 години)

+require 'digest/sha1'
+
+class ObjectStore
+ def self.init(&block)
+ if block_given?
+ ObjectStore.new.instance_eval(&block)
+ else
+ ObjectStore.new
+ end
+ end
+
+ def add(name, object)
+ stage << [name, object, 'add']
+ ResponseWithResult.new("Added #{name} to stage.", true, object)
+ end
+
+ def commit(message)
+ if stage.empty?
+ Response.new("Nothing to commit, working directory clean.", false)
+ else
+ response_message = "#{message}\n\t#{stage.length} objects changed"
+ commit = @branch_manager.active_branch.add_commit(message)
+ ResponseWithResult.new(response_message, true, commit)
+ end
+ end
+
+ def remove(name)
+ object = @branch_manager.active_branch.get_object(name)
+ if object
+ stage << [name, object, 'remove']
+ ResponseWithResult.new("Added #{name} for removal.", true, object)
+ else
+ Response.new("Object #{name} is not committed.", false)
+ end
+ end
+
+ def checkout(commit_hash)
+ commit = @branch_manager.active_branch.get_commit(commit_hash)
+ if commit
+ @branch_manager.active_branch.head = commit
+ ResponseWithResult.new("HEAD is now at #{commit_hash}.", true, commit)
+ else
+ Response.new("Commit #{commit_hash} does not exist.", false)
+ end
+ end
+
+ def branch
+ @branch_manager
+ end
+
+ def log
+ commits = @branch_manager.active_branch.commits.reverse
+ if commits.empty?
+ branch_name = @branch_manager.active_branch.name
+ Response.new(
+ "Branch #{branch_name} does not have any commits yet.",
+ false
+ )
+ else
+ log = commits.map do |commit|
+ "Commit #{commit.hash}\nDate: #{commit.date}\n\n\t#{commit.message}\n\n"
+ end.join
+ Response.new(log, true)
+ end
+ end
+
+ def head
+ head = @branch_manager.active_branch.head
+ if head
+ ResponseWithResult.new(head.message, true, head)
+ else
+ branch_name = @branch_manager.active_branch.name
+ Response.new(
+ "Branch #{branch_name} does not have any commits yet.",
+ false
+ )
+ end
+ end
+
+ def get(name)
+ obj = @branch_manager.active_branch.get_object(name)
+ if obj
+ ResponseWithResult.new("Found object #{name}.", true, obj)
+ else
+ Response.new("Object #{name} is not committed.", false)
+ end
+ end
+
+ private
+ def initialize
+ @branch_manager = BranchManager.new
+ @branch_manager.create('master')
+ @branch_manager.set_active_branch('master')
+ end
+
+ def stage
+ @branch_manager.active_branch.stage
+ end
+end
+
+class Commit
+ attr_reader :objects, :hash, :date, :message
+
+ def initialize(message, date, stage, head)
+ @message = message
+ @date = format_date(date)
+ @objects = fill_objects(stage, head)
+ @hash = gen_hash
+ end
+
+ private
+ def gen_hash
+ # "#{@message}"
+ Digest::SHA1.hexdigest("#{@date}#{@message}")
+ end
+
+ def format_date(date)
+ date.strftime("%a %b %d %H:%M %Y %z")
+ end
+
+ def fill_objects(stage, head)
+ to_be_added, to_be_removed = partition(stage)
+ objects = to_be_added.dup
+ objects += head.objects.reject { |obj| to_be_removed.include?(obj) } if head
+ objects
+ end
+
+ def partition(stage)
+ stage.partition { |item| item[2] == 'add' }.map do |group|
+ group.map { |item| item.take(2) }
+ end
+ end
+end
+
+class Branch
+ attr_reader :name, :stage
+ attr_accessor :head
+
+ def initialize(name, commits = [])
+ @name = name
+ @stage = []
+ @commits = commits.dup
+ @head = @commits.last
+ end
+
+ def add_commit(message)
+ c = Commit.new(message, Time.now, @stage, @head)
+ @commits << c
+ @stage = []
+ @head = @commits.last
+ c
+ end
+
+ def get_object(name)
+ entry = head.objects.select { |object| object[0] == name }.first
+ entry ? entry[1] : nil
+ end
+
+ def commits
+ head ? @commits.take_while { |commit| commit != head }.push(head) : []
+ end
+
+ def get_commit(commit_hash)
+ @commits.select { |commit| commit.hash == commit_hash }.first
+ end
+end
+
+class BranchManager
+ attr_reader :active_branch
+
+ def initialize
+ @branches = {}
+ end
+
+ def create(branch_name)
+ if @branches.keys.include?(branch_name)
+ Response.new("Branch #{branch_name} already exists.", false)
+ else
+ commits_in_current_branch = @active_branch ? @active_branch.commits : []
+ branch = Branch.new(branch_name, commits_in_current_branch)
+ @branches[branch_name] = branch
+ Response.new("Created branch #{branch_name}.", true)
+ end
+ end
+
+ def set_active_branch(branch_name)
+ @active_branch = @branches[branch_name]
+ end
+
+ def checkout(branch_name)
+ if @branches.keys.include?(branch_name)
+ set_active_branch(branch_name)
+ Response.new("Switched to branch #{branch_name}", true)
+ else
+ Response.new("Branch #{branch_name} does not exist.", false)
+ end
+ end
+
+ def remove(branch_name)
+ if @branches.keys.include?(branch_name)
+ if branch_name == active_branch.name
+ Response.new("Cannot remove current branch.", false)
+ else
+ @branches.delete(branch_name)
+ Response.new("Removed branch #{branch_name}.", true)
+ end
+ else
+ Response.new("Branch #{branch_name} does not exist.", false)
+ end
+ end
+
+ def list
+ @branches.sort.map do |name, _|
+ name == active_branch.name ? "* #{name}\n" : " #{name}\n"
+ end.join
+ end
+end
+
+class Response
+ attr_reader :message
+
+ def initialize(message, status)
+ @message = message
+ @status = status
+ end
+
+ def success?
+ @status
+ end
+
+ def error?
+ not success?
+ end
+end
+
+class ResponseWithResult < Response
+ attr_reader :result
+
+ def initialize(message, status, result)
+ super(message, status)
+ @result = result
+ end
+end

Станимир обнови решението на 19.11.2015 13:08 (преди над 8 години)

require 'digest/sha1'
class ObjectStore
def self.init(&block)
- if block_given?
- ObjectStore.new.instance_eval(&block)
- else
- ObjectStore.new
- end
+ object_store = ObjectStore.new
+ object_store.instance_eval(&block) if block_given?
+ object_store
end
def add(name, object)
stage << [name, object, 'add']
ResponseWithResult.new("Added #{name} to stage.", true, object)
end
def commit(message)
if stage.empty?
Response.new("Nothing to commit, working directory clean.", false)
else
response_message = "#{message}\n\t#{stage.length} objects changed"
commit = @branch_manager.active_branch.add_commit(message)
ResponseWithResult.new(response_message, true, commit)
end
end
def remove(name)
object = @branch_manager.active_branch.get_object(name)
if object
stage << [name, object, 'remove']
ResponseWithResult.new("Added #{name} for removal.", true, object)
else
Response.new("Object #{name} is not committed.", false)
end
end
def checkout(commit_hash)
commit = @branch_manager.active_branch.get_commit(commit_hash)
if commit
@branch_manager.active_branch.head = commit
ResponseWithResult.new("HEAD is now at #{commit_hash}.", true, commit)
else
Response.new("Commit #{commit_hash} does not exist.", false)
end
end
def branch
@branch_manager
end
def log
commits = @branch_manager.active_branch.commits.reverse
if commits.empty?
branch_name = @branch_manager.active_branch.name
Response.new(
"Branch #{branch_name} does not have any commits yet.",
false
)
else
- log = commits.map do |commit|
- "Commit #{commit.hash}\nDate: #{commit.date}\n\n\t#{commit.message}\n\n"
- end.join
- Response.new(log, true)
+ Response.new(build_log(commits), true)
end
end
def head
head = @branch_manager.active_branch.head
if head
ResponseWithResult.new(head.message, true, head)
else
branch_name = @branch_manager.active_branch.name
Response.new(
"Branch #{branch_name} does not have any commits yet.",
false
)
end
end
def get(name)
obj = @branch_manager.active_branch.get_object(name)
if obj
ResponseWithResult.new("Found object #{name}.", true, obj)
else
Response.new("Object #{name} is not committed.", false)
end
end
private
def initialize
@branch_manager = BranchManager.new
@branch_manager.create('master')
@branch_manager.set_active_branch('master')
end
def stage
@branch_manager.active_branch.stage
end
+
+ def build_log(commits)
+ commits.map do |commit|
+ "Commit #{commit.hash}\nDate: #{commit.formatted_date}" \
+ "\n\n\t#{commit.message}\n\n"
+ end.join.chomp.chomp
+ end
end
class Commit
attr_reader :objects, :hash, :date, :message
def initialize(message, date, stage, head)
@message = message
- @date = format_date(date)
+ @date = date
@objects = fill_objects(stage, head)
@hash = gen_hash
end
+ def formatted_date
+ date.strftime("%a %b %d %H:%M %Y %z")
+ end
+
private
def gen_hash
- # "#{@message}"
Digest::SHA1.hexdigest("#{@date}#{@message}")
end
- def format_date(date)
- date.strftime("%a %b %d %H:%M %Y %z")
- end
-
def fill_objects(stage, head)
to_be_added, to_be_removed = partition(stage)
objects = to_be_added.dup
- objects += head.objects.reject { |obj| to_be_removed.include?(obj) } if head
- objects
+ objects += non_removed_objects(head, to_be_removed)
end
+ def non_removed_objects(head, to_be_removed)
+ head ? head.objects.reject { |obj| to_be_removed.include?(obj) } : []
+ end
+
def partition(stage)
stage.partition { |item| item[2] == 'add' }.map do |group|
group.map { |item| item.take(2) }
end
end
end
class Branch
attr_reader :name, :stage
attr_accessor :head
def initialize(name, commits = [])
@name = name
@stage = []
@commits = commits.dup
@head = @commits.last
end
def add_commit(message)
- c = Commit.new(message, Time.now, @stage, @head)
- @commits << c
+ commit = Commit.new(message, Time.now, @stage, @head)
+ @commits << commit
@stage = []
@head = @commits.last
- c
end
def get_object(name)
- entry = head.objects.select { |object| object[0] == name }.first
- entry ? entry[1] : nil
+ if head
+ entry = head.objects.select { |object| object[0] == name }.first
+ entry ? entry[1] : nil
+ end
end
def commits
head ? @commits.take_while { |commit| commit != head }.push(head) : []
end
def get_commit(commit_hash)
@commits.select { |commit| commit.hash == commit_hash }.first
end
end
class BranchManager
attr_reader :active_branch
def initialize
@branches = {}
end
def create(branch_name)
if @branches.keys.include?(branch_name)
Response.new("Branch #{branch_name} already exists.", false)
else
commits_in_current_branch = @active_branch ? @active_branch.commits : []
branch = Branch.new(branch_name, commits_in_current_branch)
@branches[branch_name] = branch
Response.new("Created branch #{branch_name}.", true)
end
end
def set_active_branch(branch_name)
@active_branch = @branches[branch_name]
end
def checkout(branch_name)
if @branches.keys.include?(branch_name)
set_active_branch(branch_name)
- Response.new("Switched to branch #{branch_name}", true)
+ Response.new("Switched to branch #{branch_name}.", true)
else
Response.new("Branch #{branch_name} does not exist.", false)
end
end
def remove(branch_name)
if @branches.keys.include?(branch_name)
if branch_name == active_branch.name
Response.new("Cannot remove current branch.", false)
else
@branches.delete(branch_name)
Response.new("Removed branch #{branch_name}.", true)
end
else
Response.new("Branch #{branch_name} does not exist.", false)
end
end
def list
- @branches.sort.map do |name, _|
+ list = @branches.sort.map do |name, _|
name == active_branch.name ? "* #{name}\n" : " #{name}\n"
- end.join
+ end.join.chomp
+ Response.new(list, true)
end
end
class Response
attr_reader :message
def initialize(message, status)
@message = message
@status = status
end
def success?
@status
end
def error?
not success?
end
end
class ResponseWithResult < Response
attr_reader :result
def initialize(message, status, result)
super(message, status)
@result = result
end
end