Class: Gitgo::Index::ShaFile

Inherits:
Object
  • Object
show all
Defined in:
lib/gitgo/index/sha_file.rb

Overview

ShaFile is a wrapper providing access to a file of H packed shas.

Constant Summary collapse

PACK =

The pack format, optimized for packing multiple shas

"H*"
UNPACK =

The unpacking format

"H40"
ENTRY_SIZE =

The size of an unpacked sha

40
PACKED_ENTRY_SIZE =

The size of a packed sha

20

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file) ⇒ ShaFile

Initializes a new ShaFile with the specified file. The file will be set to binary mode.



73
74
75
76
# File 'lib/gitgo/index/sha_file.rb', line 73

def initialize(file)
  file.binmode
  @file = file
end

Instance Attribute Details

#fileObject (readonly)

The file being wrapped



69
70
71
# File 'lib/gitgo/index/sha_file.rb', line 69

def file
  @file
end

Class Method Details

.append(path, sha) ⇒ Object

Opens the file and appends the sha. Multiple shas may be appended at once by providing a string of concatenated shas.



41
42
43
44
45
# File 'lib/gitgo/index/sha_file.rb', line 41

def append(path, sha)
  dir = File.dirname(path)
  FileUtils.mkdir_p(dir) unless File.exists?(dir)
  open(path, "a") {|sha_file| sha_file.write(sha) }
end

.open(path, mode = "r") ⇒ Object

Opens and returns an sha file in the specified mode. If a block is given the file is yielded to it and closed afterwards; in this case the return of open is the block result.



13
14
15
16
17
18
19
20
21
22
23
# File 'lib/gitgo/index/sha_file.rb', line 13

def open(path, mode="r")
  sha_file = new(File.open(path, mode))
  
  return sha_file unless block_given?

  begin
    yield(sha_file)
  ensure
    sha_file.close
  end
end

.read(path) ⇒ Object

Reads the file and returns an array of shas.



26
27
28
# File 'lib/gitgo/index/sha_file.rb', line 26

def read(path)
  open(path) {|sha_file| sha_file.read(nil) }
end

.rm(path, *shas) ⇒ Object

Opens the file and removes the shas.



48
49
50
51
52
53
# File 'lib/gitgo/index/sha_file.rb', line 48

def rm(path, *shas)
  return unless File.exists?(path)
  
  current = read(path)
  write(path, (current-shas).join)
end

.write(path, sha) ⇒ Object

Opens the file and writes the sha; previous contents are replaced. Multiple shas may be written at once by providing a string of concatenated shas.



33
34
35
36
37
# File 'lib/gitgo/index/sha_file.rb', line 33

def write(path, sha)
  dir = File.dirname(path)
  FileUtils.mkdir_p(dir) unless File.exists?(dir)
  open(path, "w") {|sha_file| sha_file.write(sha) }
end

Instance Method Details

#append(sha) ⇒ Object

Appends the sha to the file. Multiple shas may be appended at once by providing a string of concatenated shas.



128
129
130
131
132
# File 'lib/gitgo/index/sha_file.rb', line 128

def append(sha)
  file.pos = file.size
  write(sha)
  self
end

#closeObject

Closes file



79
80
81
# File 'lib/gitgo/index/sha_file.rb', line 79

def close
  file.close
end

#currentObject

The index of the current entry.



84
85
86
# File 'lib/gitgo/index/sha_file.rb', line 84

def current
  file.pos / PACKED_ENTRY_SIZE
end

#read(n = 10, start = 0) ⇒ Object

Reads n entries from the start index and returns them as an array. Nil n will read all remaining entries and nil start will read from the current index.



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'lib/gitgo/index/sha_file.rb', line 91

def read(n=10, start=0)
  if start
    start_pos = start * PACKED_ENTRY_SIZE 
    file.pos = start_pos
  end
  
  str = file.read(n.nil? ? nil : n * PACKED_ENTRY_SIZE).to_s
  unless str.length % PACKED_ENTRY_SIZE == 0
    raise "invalid packed sha length: #{str.length}"
  end
  entries = str.unpack(UNPACK * (str.length / PACKED_ENTRY_SIZE))

  # clear out all missing entries, which will be empty
  while last = entries.last
    if last.empty?
      entries.pop
    else
      break
    end
  end
  
  entries
end

#write(sha) ⇒ Object

Writes the sha to the file at the current index. Multiple shas may be written at once by providing a string of concatenated shas.



117
118
119
120
121
122
123
124
# File 'lib/gitgo/index/sha_file.rb', line 117

def write(sha)
  unless sha.length % ENTRY_SIZE == 0
    raise "invalid sha length: #{sha.length}"
  end
  
  file.write [sha].pack(PACK)
  self
end