Class: OMF::Web::GitContentRepository

Inherits:
ContentRepository show all
Defined in:
lib/omf-web/content/git_repository.rb

Overview

This class provides an interface to a GIT repository It retrieves, archives and versions content.

Constant Summary

Constants inherited from ContentRepository

ContentRepository::MIME_TYPE, ContentRepository::REPO_PLUGINS

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods inherited from ContentRepository

#absolute_path, absolute_path_for, create_content_proxy_for, create_url, find_files, find_repo_for, #mime_type_for_file, #path, #read, read_content, register_repo

Constructor Details

#initialize(name, opts) ⇒ GitContentRepository

Returns a new instance of GitContentRepository.



60
61
62
63
64
# File 'lib/omf-web/content/git_repository.rb', line 60

def initialize(name, opts)
  super
  @repo = Grit::Repo.new(@top_dir)
  @url_prefix = "git:#{@name}:"
end

Instance Attribute Details

#nameObject (readonly)

end



58
59
60
# File 'lib/omf-web/content/git_repository.rb', line 58

def name
  @name
end

#top_dirObject (readonly)

end



58
59
60
# File 'lib/omf-web/content/git_repository.rb', line 58

def top_dir
  @top_dir
end

Instance Method Details

#_find_files(search_pattern, tree, dir_path, res) ⇒ Object



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/omf-web/content/git_repository.rb', line 146

def _find_files(search_pattern, tree, dir_path, res)
  tree.contents.each do |e|
    d = e.name
    long_name = dir_path ? "#{dir_path}/#{d}" : d

    if e.is_a? Grit::Tree
      _find_files(search_pattern, e, long_name, res)
    else
      if long_name.match(search_pattern)
        mt = mime_type_for_file(e.name)
        #path = @url_prefix + long_name
        path = long_name
        res << {path: path, url: get_url_for_path(path), name: e.name,
                mime_type: mt,
                #:id => Base64.encode64(long_name).gsub("\n", ''),
                size: e.size, blob: e.id}
      end
      # name = e.name
      # if File.fnmatch(search_pattern, long_name)
        # res << long_name
      # end
    end
  end
  res
end

#_get_path(content_descr) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/omf-web/content/git_repository.rb', line 172

def _get_path(content_descr)
  if content_descr.is_a? String
    path = content_descr.to_s
    if path.start_with? 'git:'
      path = path.split(':')[2]
    end
  elsif content_descr.is_a? Hash
    descr = content_descr
    if (url = descr[:url])
      path = url.split(':')[2] # git:repo_name:path
    else
      path = descr[:path]
    end
    unless path
      raise "Missing 'path' or 'url' in content description (#{descr.inspect})"
    end
    path = path.to_s
  else
    raise "Unsupported type '#{content_descr.class}'"
  end
  unless path
    raise "Can't find path information in '#{content_descr.inspect}'"
  end
  if path.start_with? '/'
    # Remove leading '/' .. need to stay within git directory tree
    path = path[1 .. -1]
  end
  return path
end

#create_content_proxy_for(content_descr) ⇒ Object

Load content described by either a hash or a straightforward path and return a ‘ContentProxy’ holding it.

If descr is true, return nil if file for which proxy is requested already exists.

@return: Content proxy



85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/omf-web/content/git_repository.rb', line 85

def create_content_proxy_for(content_descr)
  path = _get_path(content_descr)
  # TODO: Make sure that key is really unique across multiple repositories
  url = @url_prefix + path
  key = Digest::MD5.hexdigest(url)
  descr = {}
  descr[:url] = url
  descr[:url_key] = key
  descr[:path] = path
  descr[:name] = url # Should be something human digestable
  if (descr[:strictly_new])
    Dir.chdir(@top_dir) do
      return nil if File.exist?(path)
    end
  end
  proxy = ContentProxy.create(descr, self)
  return proxy
end

#find_files(search_pattern, opts = {}) ⇒ Object

Return an array of file names which are in the repository and match ‘search_pattern’



134
135
136
137
138
139
140
141
142
143
144
# File 'lib/omf-web/content/git_repository.rb', line 134

def find_files(search_pattern, opts = {})
  search_pattern = Regexp.new(search_pattern)
  tree = @repo.tree
  res = []
  fs = _find_files(search_pattern, tree, nil, res)

  # if (mt = opts[:mime_type])
    # fs = fs.select { |f| File.fnmatch(mt, f[:mime_type]) }
  # end
  fs
end

#get_url_for_path(path) ⇒ Object

Return a URL for a path in this repo



124
125
126
# File 'lib/omf-web/content/git_repository.rb', line 124

def get_url_for_path(path)
  @url_prefix + path
end

#write(content_descr, content, message) ⇒ Object



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/omf-web/content/git_repository.rb', line 104

def write(content_descr, content, message)
  path = _get_path(content_descr)
  Dir.chdir(@top_dir) do
    d_name = File.dirname(path)
    FileUtils.mkpath(d_name) unless File.exist?(d_name)
    unless File.writable?(path) || File.writable?(d_name)
      raise "Cannot write to file '#{path}'"
    end
    f = File.open(path, 'w')
    f.write(content)
    f.close

    @repo.add(path)
    # TODO: Should set info about committing user which should be in thread context
    @repo.commit_index(message || 'no message')
  end
end