Решение на Пета задача от Петър Иванов

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

Към профила на Петър Иванов

Резултати

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

Код

require 'digest/sha1'
class ObjectStore
def initialize
@branch_manager = BranchManager.new
end
def self.init(&block)
instance = self.new
if block_given?
instance.instance_eval(&block)
end
instance
end
def add(name, object)
@current_branch = @branch_manager.get_current_branch
new_file = File.new(name, object)
update_file(new_file)
@current_branch.changes += 1
OperationResult.new("Added #{new_file.name} to stage.", true, object)
end
def commit(message)
if @branch_manager.get_current_branch.changes == 0
OperationResult.new("Nothing to commit, working directory clean.", false)
else
new_commit = Commit.new(@current_branch.local_all_files,
message, Time.now)
@current_branch.commits << new_commit
@current_branch.global_all_files = @current_branch.local_all_files.clone
changes = @current_branch.changes
@current_branch.changes = 0
OperationResult.new("#{new_commit.message}\n\t#{changes}" +
" objects changed", true, new_commit)
end
end
def update_file(new_file)
@current_branch = @branch_manager.get_current_branch
existing_file = @current_branch.local_all_files.select { |f|
f.name == new_file.name }
if existing_file != []
@current_branch.local_all_files -= existing_file
@current_branch.local_all_files << new_file
else
@current_branch.local_all_files << new_file
end
end
def remove(name)
@current_branch = @branch_manager.get_current_branch
old_file = @current_branch.local_all_files.select { |f| f.name == name }
if old_file != []
@current_branch.local_all_files -= old_file
@current_branch.changes += 1
OperationResult.new("Added #{name} for removal.", true, old_file.
first.obj)
else
OperationResult.new("Object #{name} is not committed.", false)
end
end
def checkout(commit_hash)
@current_branch = @branch_manager.get_current_branch
new_head = @current_branch.commits.select { |c| c.hash == commit_hash }
if new_head != []
@current_branch.commits = @current_branch.commits[
0..@current_branch.commits.index(new_head.first)]
update_branch(new_head.first)
OperationResult.new("HEAD is now at #{commit_hash}.", true,
new_head.first)
else
OperationResult.new("Commit #{commit_hash} does not exist.", false)
end
end
def update_branch(new_commit)
@current_branch = @branch_manager.get_current_branch
@current_branch.global_all_files = new_commit.objects.clone
@current_branch.local_all_files = new_commit.objects.clone
end
def branch
@branch_manager
end
def log
if @branch_manager.get_current_branch.commits.size == 0
OperationResult.new("Branch #{@branch_manager.get_current_branch
.name} does" + " not have any commits yet.", false)
else
message = []
@branch_manager.get_current_branch.commits.reverse.each do |commit|
message << "Commit #{commit.hash}\nDate: " +
"#{commit.date.strftime("%a %b %d %H:%M %Y %z")}" +
"\n\n\t#{commit.message}"
end
message = message.join("\n\n")
OperationResult.new(message, true)
end
end
def head
@current_branch = @branch_manager.get_current_branch
if @current_branch.commits.size == 0
OperationResult.new("Branch #{@current_branch.name} does" +
" not have any commits yet.", false)
else
OperationResult.new("#{@current_branch.commits[-1].message}", true,
@current_branch.commits[-1])
end
end
def get(name)
@current_branch = @branch_manager.get_current_branch
file = @current_branch.global_all_files.select { |f| f.name == name }
if file != []
OperationResult.new("Found object #{name}.", true, file.first.obj)
else
OperationResult.new("Object #{name} is not committed.", false)
end
end
class Branch
attr_accessor :commits
attr_accessor :global_all_files
attr_accessor :local_all_files
attr_accessor :changes
attr_reader :name
def initialize(name)
@name = name
@commits = []
@global_all_files = []
@local_all_files = []
@changes = 0
end
end
class BranchManager
def initialize
@branches = []
new_branch = Branch.new("master")
@branches << new_branch
@current_branch = new_branch
end
def get_current_branch
@current_branch
end
def create(branch_name)
existing_branch = @branches.select { |b| b.name == branch_name }
if existing_branch == []
new_branch = Branch.new(branch_name)
new_branch.commits = @current_branch.commits.clone
new_branch.global_all_files = @current_branch.global_all_files.clone
new_branch.local_all_files = @current_branch.local_all_files.clone
@branches << new_branch
OperationResult.new("Created branch #{branch_name}.", true)
else
OperationResult.new("Branch #{branch_name} already exists.", false)
end
end
def checkout(branch_name)
existing_branch = @branches.select { |b| b.name == branch_name }
if existing_branch != []
@current_branch = existing_branch.first
OperationResult.new("Switched to branch #{branch_name}.", true)
else
OperationResult.new("Branch #{branch_name} does not exist.", false)
end
end
def remove(branch_name)
old_branch = @branches.select { |b| b.name == branch_name }
if @current_branch.name == branch_name
OperationResult.new("Cannot remove current branch.", false)
elsif old_branch != []
@branches -= old_branch
OperationResult.new("Removed branch #{branch_name}.", true)
else
OperationResult.new("Branch #{branch_name} does not exist.", false)
end
end
def list
message = []
@branches.sort_by { |b| b.name }.each do |branch|
if branch == @current_branch
message << "* #{branch.name}"
else
message << " #{branch.name}"
end
end
message = message.join("\n")
OperationResult.new(message, true)
end
end
class Commit
attr_reader :message, :hash, :date
attr_accessor :objects
def initialize(files, message, date)
@objects = files.clone
@message = message
@date = date
@hash = Digest::SHA1.hexdigest(
@date.strftime("%a %b %d %H:%M %Y %z") + @message)
end
end
class OperationResult
attr_reader :message, :result
def initialize(message, state, result = nil)
@message = message
@state = state
@result = result
end
def success?
@state ? true : false
end
def error?
@state ? false : true
end
end
class File < Struct.new(:name, :obj)
def to_s
"#{name.to_s} - #{obj.to_s}"
end
end
end

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

............................FF

Failures:

  1) 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:    [#<struct ObjectStore::File name="object1", obj="content1">]
       the missing elements were:      ["content1"]
       the extra elements were:        [#<struct ObjectStore::File name="object1", obj="content1">]
     # /tmp/d20160111-5693-mpv7s2/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)>'

  2) 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:    [#<struct ObjectStore::File name="object1", obj="content1">, #<struct ObjectStore::File name="object2", obj="content2">, #<struct ObjectStore::File name="object3", obj="content3">]
       the missing elements were:      ["content1", "content2", "content3"]
       the extra elements were:        [#<struct ObjectStore::File name="object1", obj="content1">, #<struct ObjectStore::File name="object2", obj="content2">, #<struct ObjectStore::File name="object3", obj="content3">]
     # /tmp/d20160111-5693-mpv7s2/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.02999 seconds
30 examples, 2 failures

Failed examples:

rspec /tmp/d20160111-5693-mpv7s2/spec.rb:239 # ObjectStore can show the objects in a repo after overwriting an object
rspec /tmp/d20160111-5693-mpv7s2/spec.rb:253 # ObjectStore can show the objects of a repo after removing an object

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

Петър обнови решението на 21.11.2015 21:28 (преди над 8 години)

+require 'digest/sha1'
+
+class ObjectStore
+ def initialize
+ @branch_manager = BranchManager.new
+ end
+
+ def self.init(&block)
+ instance = self.new
+ if block_given?
+ instance.instance_eval(&block)
+ end
+ instance
+ end
+
+ def add(name, object)
+ @current_branch = @branch_manager.get_current_branch
+
+ new_file = File.new(name, object)
+ update_file(new_file)
+ @current_branch.changes += 1
+
+ OperationResult.new("Added #{new_file.name} to stage.", true, object)
+ end
+
+ def commit(message)
+ if @branch_manager.get_current_branch.changes == 0
+ OperationResult.new("Nothing to commit, working directory clean.", false)
+ else
+ new_commit = Commit.new(@current_branch.local_all_files,
+ message, Time.now)
+ @current_branch.commits << new_commit
+ @current_branch.global_all_files = @current_branch.local_all_files.clone
+ changes = @current_branch.changes
+ @current_branch.changes = 0
+ OperationResult.new("#{new_commit.message}\n\t#{changes}" +
+ " objects changed", true, new_commit)
+ end
+ end
+
+ def update_file(new_file)
+ @current_branch = @branch_manager.get_current_branch
+
+ existing_file = @current_branch.local_all_files.select { |f|
+ f.name == new_file.name }
+ if existing_file != []
+ @current_branch.local_all_files -= existing_file
+ @current_branch.local_all_files << new_file
+ else
+ @current_branch.local_all_files << new_file
+ end
+ end
+
+ def remove(name)
+ @current_branch = @branch_manager.get_current_branch
+
+ old_file = @current_branch.local_all_files.select { |f| f.name == name }
+ if old_file != []
+ @current_branch.local_all_files -= old_file
+ @current_branch.changes += 1
+ OperationResult.new("Added #{name} for removal.", true, old_file.
+ first.obj)
+ else
+ OperationResult.new("Object #{name} is not committed.", false)
+ end
+ end
+
+ def checkout(commit_hash)
+ @current_branch = @branch_manager.get_current_branch
+
+ new_head = @current_branch.commits.select { |c| c.hash == commit_hash }
+ if new_head != []
+ @current_branch.commits = @current_branch.commits[
+ 0..@current_branch.commits.index(new_head.first)]
+ update_branch(new_head.first)
+ OperationResult.new("HEAD is now at #{commit_hash}.", true,
+ new_head.first)
+ else
+ OperationResult.new("Commit #{commit_hash} does not exist.", false)
+ end
+ end
+
+ def update_branch(new_commit)
+ @current_branch = @branch_manager.get_current_branch
+
+ @current_branch.global_all_files = new_commit.objects.clone
+ @current_branch.local_all_files = new_commit.objects.clone
+ end
+
+ def branch
+ @branch_manager
+ end
+
+ def log
+ if @branch_manager.get_current_branch.commits.size == 0
+ OperationResult.new("Branch #{@branch_manager.get_current_branch
+ .name} does" + " not have any commits yet.", false)
+ else
+ message = []
+ @branch_manager.get_current_branch.commits.reverse.each do |commit|
+ message << "Commit #{commit.hash}\nDate: " +
+ "#{commit.date.strftime("%a %b %d %H:%M %Y %z")}" +
+ "\n\n\t#{commit.message}"
+ end
+ message = message.join("\n\n")
+ OperationResult.new(message, true)
+ end
+ end
+
+ def head
+ @current_branch = @branch_manager.get_current_branch
+
+ if @current_branch.commits.size == 0
+ OperationResult.new("Branch #{@current_branch.name} does" +
+ " not have any commits yet.", false)
+ else
+ OperationResult.new("#{@current_branch.commits[-1].message}", true,
+ @current_branch.commits[-1])
+ end
+ end
+
+ def get(name)
+ @current_branch = @branch_manager.get_current_branch
+
+ file = @current_branch.global_all_files.select { |f| f.name == name }
+ if file != []
+ OperationResult.new("Found object #{name}.", true, file.first.obj)
+ else
+ OperationResult.new("Object #{name} is not committed.", false)
+ end
+ end
+
+ class Branch
+ attr_accessor :commits
+ attr_accessor :global_all_files
+ attr_accessor :local_all_files
+ attr_accessor :changes
+ attr_reader :name
+
+ def initialize(name)
+ @name = name
+ @commits = []
+ @global_all_files = []
+ @local_all_files = []
+ @changes = 0
+ end
+ end
+
+ class BranchManager
+ def initialize
+ @branches = []
+ new_branch = Branch.new("master")
+ @branches << new_branch
+ @current_branch = new_branch
+ end
+
+ def get_current_branch
+ @current_branch
+ end
+
+ def create(branch_name)
+ existing_branch = @branches.select { |b| b.name == branch_name }
+ if existing_branch == []
+ new_branch = Branch.new(branch_name)
+ new_branch.commits = @current_branch.commits.clone
+ @branches << new_branch
+ OperationResult.new("Created branch #{branch_name}.", true)
+ else
+ OperationResult.new("Branch #{branch_name} already exists.", false)
+ end
+ end
+
+ def checkout(branch_name)
+ existing_branch = @branches.select { |b| b.name == branch_name }
+ if existing_branch != []
+ @current_branch = existing_branch.first
+ OperationResult.new("Switched to branch #{branch_name}.", true)
+ else
+ OperationResult.new("Branch #{branch_name} does not exist.", false)
+ end
+ end
+
+ def remove(branch_name)
+ old_branch = @branches.select { |b| b.name == branch_name }
+
+ if @current_branch.name == branch_name
+ OperationResult.new("Cannot remove current branch.", false)
+ elsif old_branch != []
+ @branches -= old_branch
+ OperationResult.new("Removed branch #{branch_name}.", true)
+ else
+ OperationResult.new("Branch #{branch_name} does not exist.", false)
+ end
+ end
+
+ def list
+ message = []
+ @branches.sort_by { |b| b.name }.each do |branch|
+ if branch == @current_branch
+ message << "* #{branch.name}"
+ else
+ message << " #{branch.name}"
+ end
+ end
+ message = message.join("\n")
+ OperationResult.new(message, true)
+ end
+ end
+
+ class Commit
+ attr_reader :message, :hash, :date
+ attr_accessor :objects
+
+ def initialize(files, message, date)
+ @objects = files.clone
+ @message = message
+ @date = date
+ @hash = Digest::SHA1.hexdigest(
+ @date.strftime("%a %b %d %H:%M %Y %z") + @message)
+ end
+ end
+
+ class OperationResult
+ attr_reader :message, :result
+
+ def initialize(message, state, result = nil)
+ @message = message
+ @state = state
+ @result = result
+ end
+
+ def success?
+ @state ? true : false
+ end
+
+ def error?
+ @state ? false : true
+ end
+ end
+
+ class File < Struct.new(:name, :obj)
+ def to_s
+ "#{name.to_s} - #{obj.to_s}"
+ end
+ end
+end

Петър обнови решението на 23.11.2015 11:11 (преди над 8 години)

require 'digest/sha1'
class ObjectStore
def initialize
@branch_manager = BranchManager.new
end
def self.init(&block)
instance = self.new
if block_given?
instance.instance_eval(&block)
end
instance
end
def add(name, object)
@current_branch = @branch_manager.get_current_branch
new_file = File.new(name, object)
update_file(new_file)
@current_branch.changes += 1
OperationResult.new("Added #{new_file.name} to stage.", true, object)
end
def commit(message)
if @branch_manager.get_current_branch.changes == 0
OperationResult.new("Nothing to commit, working directory clean.", false)
else
new_commit = Commit.new(@current_branch.local_all_files,
message, Time.now)
@current_branch.commits << new_commit
@current_branch.global_all_files = @current_branch.local_all_files.clone
changes = @current_branch.changes
@current_branch.changes = 0
OperationResult.new("#{new_commit.message}\n\t#{changes}" +
" objects changed", true, new_commit)
end
end
def update_file(new_file)
@current_branch = @branch_manager.get_current_branch
existing_file = @current_branch.local_all_files.select { |f|
f.name == new_file.name }
if existing_file != []
@current_branch.local_all_files -= existing_file
@current_branch.local_all_files << new_file
else
@current_branch.local_all_files << new_file
end
end
def remove(name)
@current_branch = @branch_manager.get_current_branch
old_file = @current_branch.local_all_files.select { |f| f.name == name }
if old_file != []
@current_branch.local_all_files -= old_file
@current_branch.changes += 1
OperationResult.new("Added #{name} for removal.", true, old_file.
first.obj)
else
OperationResult.new("Object #{name} is not committed.", false)
end
end
def checkout(commit_hash)
@current_branch = @branch_manager.get_current_branch
new_head = @current_branch.commits.select { |c| c.hash == commit_hash }
if new_head != []
@current_branch.commits = @current_branch.commits[
0..@current_branch.commits.index(new_head.first)]
update_branch(new_head.first)
OperationResult.new("HEAD is now at #{commit_hash}.", true,
new_head.first)
else
OperationResult.new("Commit #{commit_hash} does not exist.", false)
end
end
def update_branch(new_commit)
@current_branch = @branch_manager.get_current_branch
@current_branch.global_all_files = new_commit.objects.clone
@current_branch.local_all_files = new_commit.objects.clone
end
def branch
@branch_manager
end
def log
if @branch_manager.get_current_branch.commits.size == 0
OperationResult.new("Branch #{@branch_manager.get_current_branch
.name} does" + " not have any commits yet.", false)
else
message = []
@branch_manager.get_current_branch.commits.reverse.each do |commit|
message << "Commit #{commit.hash}\nDate: " +
"#{commit.date.strftime("%a %b %d %H:%M %Y %z")}" +
"\n\n\t#{commit.message}"
end
message = message.join("\n\n")
OperationResult.new(message, true)
end
end
def head
@current_branch = @branch_manager.get_current_branch
if @current_branch.commits.size == 0
OperationResult.new("Branch #{@current_branch.name} does" +
" not have any commits yet.", false)
else
OperationResult.new("#{@current_branch.commits[-1].message}", true,
@current_branch.commits[-1])
end
end
def get(name)
@current_branch = @branch_manager.get_current_branch
file = @current_branch.global_all_files.select { |f| f.name == name }
if file != []
OperationResult.new("Found object #{name}.", true, file.first.obj)
else
OperationResult.new("Object #{name} is not committed.", false)
end
end
class Branch
attr_accessor :commits
attr_accessor :global_all_files
attr_accessor :local_all_files
attr_accessor :changes
attr_reader :name
def initialize(name)
@name = name
@commits = []
@global_all_files = []
@local_all_files = []
@changes = 0
end
end
class BranchManager
def initialize
@branches = []
new_branch = Branch.new("master")
@branches << new_branch
@current_branch = new_branch
end
def get_current_branch
@current_branch
end
def create(branch_name)
existing_branch = @branches.select { |b| b.name == branch_name }
if existing_branch == []
new_branch = Branch.new(branch_name)
new_branch.commits = @current_branch.commits.clone
+ new_branch.global_all_files = @current_branch.global_all_files.clone
+ new_branch.local_all_files = @current_branch.local_all_files.clone
@branches << new_branch
OperationResult.new("Created branch #{branch_name}.", true)
else
OperationResult.new("Branch #{branch_name} already exists.", false)
end
end
def checkout(branch_name)
existing_branch = @branches.select { |b| b.name == branch_name }
if existing_branch != []
@current_branch = existing_branch.first
OperationResult.new("Switched to branch #{branch_name}.", true)
else
OperationResult.new("Branch #{branch_name} does not exist.", false)
end
end
def remove(branch_name)
old_branch = @branches.select { |b| b.name == branch_name }
if @current_branch.name == branch_name
OperationResult.new("Cannot remove current branch.", false)
elsif old_branch != []
@branches -= old_branch
OperationResult.new("Removed branch #{branch_name}.", true)
else
OperationResult.new("Branch #{branch_name} does not exist.", false)
end
end
def list
message = []
@branches.sort_by { |b| b.name }.each do |branch|
if branch == @current_branch
message << "* #{branch.name}"
else
message << " #{branch.name}"
end
end
message = message.join("\n")
OperationResult.new(message, true)
end
end
class Commit
attr_reader :message, :hash, :date
attr_accessor :objects
def initialize(files, message, date)
@objects = files.clone
@message = message
@date = date
@hash = Digest::SHA1.hexdigest(
@date.strftime("%a %b %d %H:%M %Y %z") + @message)
end
end
class OperationResult
attr_reader :message, :result
def initialize(message, state, result = nil)
@message = message
@state = state
@result = result
end
def success?
@state ? true : false
end
def error?
@state ? false : true
end
end
class File < Struct.new(:name, :obj)
def to_s
"#{name.to_s} - #{obj.to_s}"
end
end
end