Class: WikiMD::Repository

Inherits:
Object
  • Object
show all
Defined in:
lib/wikimd/repository.rb

Overview

Handles reading and writing of files in the repo. Also interacts with GIT.

Defined Under Namespace

Classes: FileNotFound, GitError

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ Repository

Returns a new instance of Repository.



16
17
18
19
# File 'lib/wikimd/repository.rb', line 16

def initialize(path)
  @path = Pathname(path).realpath
  @path.mkpath
end

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



14
15
16
# File 'lib/wikimd/repository.rb', line 14

def path
  @path
end

Instance Method Details

#build_hash(files, root) ⇒ Object (private)

convert an array of absolute path names into a hash.



108
109
110
111
112
113
114
# File 'lib/wikimd/repository.rb', line 108

def build_hash(files, root)
  tree = {}
  files.each do |path|
    build_tree(tree, path.split(File::SEPARATOR), root)
  end
  tree
end

#build_tree(tree, parts, path) ⇒ Object (private)

add an array of path parts to the tree



117
118
119
120
121
122
123
124
125
126
# File 'lib/wikimd/repository.rb', line 117

def build_tree(tree, parts, path)
  path += '/' unless path.empty? || path.end_with?('/')
  parts[0...-1].each do |p|
    path += "#{p}/"
    tree[p] ||= { type: :directory, path: path, sub: {} }
    tree = tree[p][:sub]
  end
  fname = parts[-1]
  tree[fname] = { type: :text, path: path + fname }
end

#files(root = '') ⇒ Object

return an array of all files



82
83
84
85
86
87
88
# File 'lib/wikimd/repository.rb', line 82

def files(root = '')
  files = []
  dir = @path.join(root)
  Dir.chdir(dir) do
    files = Dir.glob('**/*').select { |p| dir.join(p).file? }
  end
end

#git(cmd, arg) ⇒ Object (private)



97
98
99
100
101
102
103
104
105
# File 'lib/wikimd/repository.rb', line 97

def git(cmd, arg)
  command = "git #{cmd.to_s} #{arg}"
  out, err, stat = nil
  Dir.chdir(@path) do
    out, err, stat = Open3.capture3(command)
  end
  fail GitError, "Error running `#{command}` - #{err}" unless stat.success?
  out
end

#history(path) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/wikimd/repository.rb', line 38

def history(path)
  params = %(--pretty='format:%h;%cr;%s' --no-decorate --no-color -z)
  out = git :log, "#{params} -- #{path.shellescape}"
  out.split("\x0").map do |e|
    h, d, m = e.split(';', 3)
    {
      hash: h,
      date: d,
      message: m
    }
  end
end

#list_dirs(path) ⇒ Array

List all directories in path.

Parameters:

  • path (String, Pathname)

    path to the directory within the repo

Returns:

  • (Array)

    an array of directory names



55
56
57
58
59
60
61
62
63
64
# File 'lib/wikimd/repository.rb', line 55

def list_dirs(path)
  dir = pathname(path)

  Dir.chdir(dir) do
    Dir['*/']
  end

rescue
  raise FileNotFound, "no such file in repo - #{path}"
end

#list_files(path) ⇒ Array

List all files in path.

Parameters:

  • path (String, Pathname)

    path to the directory within the repo

Returns:

  • (Array)

    an array of file names



70
71
72
73
74
75
76
77
78
79
# File 'lib/wikimd/repository.rb', line 70

def list_files(path)
  dir = pathname(path)

  Dir.chdir(dir) do
    Dir['*'].select { |n| File.file?(n) }
  end

rescue
  raise FileNotFound, "no such file in repo - #{path}"
end

#pathname(path) ⇒ Object (private)



128
129
130
131
132
133
134
135
136
137
138
# File 'lib/wikimd/repository.rb', line 128

def pathname(path)
  # calling `realpath` does several things for us:
  # - returns an absolute pathname
  # - ... which does not contain any useless dots (., ..)
  # - and checks that the file actually exists.
  file = @path.join(path.sub(%r{\A/+}, '')).realpath
  fail unless file.to_s.start_with?(@path.to_s)
  file
rescue
  raise FileNotFound, "no such file or directory in repo - #{path}"
end

#read(path, rev = nil) ⇒ String

Reads a file from the repository. path will have its leading slashes removed and must be within the repository path.

Parameters:

  • path (String, Pathname)

    path to the file to be read

Returns:

  • (String)

    the content of file

Raises:

  • (FileNotFound)

    if file doesn’t exist within the repo or is a dir



27
28
29
30
31
32
33
34
35
36
# File 'lib/wikimd/repository.rb', line 27

def read(path, rev=nil)
  if rev.nil?
    file = pathname(path)
    return file.read
  else
    git :show, %(#{rev}:"./#{path.shellescape}")
  end
rescue
  raise FileNotFound, "no such file in repo - #{path}"
end

#tree(root = '') ⇒ Object

return a hash containing all dirs and files



91
92
93
# File 'lib/wikimd/repository.rb', line 91

def tree(root = '')
  build_hash(files(root), root)
end