class ChefCLI::Policyfile::UndoStack
def delete(id)
def delete(id) undo_file = undo_file_for(id) unless File.exist?(undo_file) raise UndoRecordNotFound, "No undo record for id '#{id}' exists at #{undo_file}" end record = load_undo_record(undo_file) yield record if block_given? File.unlink(undo_file) record end
def each_with_id
def each_with_id undo_record_files.each do |filename| yield File.basename(filename), load_undo_record(filename) end end
def empty?
def empty? size == 0 end
def ensure_undo_dir_exists
def ensure_undo_dir_exists return false if File.directory?(undo_dir) FileUtils.mkdir_p(undo_dir) end
def has_id?(id)
def has_id?(id) File.exist?(undo_file_for(id)) end
def load_undo_record(file)
def load_undo_record(file) data = FFI_Yajl::Parser.parse(IO.read(file)) UndoRecord.new.load(data) end
def pop
def pop file_to_pop = undo_record_files.last if file_to_pop.nil? raise CantUndo, "No undo records exist in #{undo_dir}" end record = load_undo_record(file_to_pop) # if this hits an exception, we skip unlink yield record if block_given? File.unlink(file_to_pop) record end
def push(undo_record)
def push(undo_record) ensure_undo_dir_exists record_id = Time.new.utc.strftime("%Y%m%d%H%M%S") path = File.join(undo_dir, record_id) with_file(path) do |f| f.print(FFI_Yajl::Encoder.encode(undo_record.for_serialization, pretty: true)) end records_to_delete = undo_record_files.size - MAX_SIZE if records_to_delete > 0 undo_record_files.take(records_to_delete).each do |file| File.unlink(file) end end self end
def size
def size undo_record_files.size end
def undo_dir
def undo_dir File.join(Helpers.package_home, "undo") end
def undo_file_for(id)
def undo_file_for(id) File.join(undo_dir, id) end
def undo_record_files
def undo_record_files Dir[File.join(undo_dir, "*")].sort end
def undo_records
def undo_records undo_record_files.map { |f| load_undo_record(f) } end