Class: Metaverse::Repo

Inherits:
Object
  • Object
show all
Defined in:
lib/metaverse/repo.rb

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ Repo

Initialize a git repository path - An absolute path to the repo root folder



10
11
12
13
# File 'lib/metaverse/repo.rb', line 10

def initialize path
  load path
  @previous_branches = []
end

Instance Method Details

#add_option_to_remote(remote, value, key) ⇒ Object



195
196
197
198
199
200
201
202
# File 'lib/metaverse/repo.rb', line 195

def add_option_to_remote remote, value, key
  config_path = "#{@repo.path}config"
  cfg = IniParse.parse(File.read(config_path))
  if not [*cfg["remote \"#{remote}\""][key]].include? value
    cfg["remote \"#{remote}\""][key] = [*cfg["remote \"#{remote}\""][key], value]
    cfg.save config_path
  end
end

#add_remote(name, url) ⇒ Object



223
224
225
226
# File 'lib/metaverse/repo.rb', line 223

def add_remote name, url
  return Errors::remote_exists name if not @repo.remotes[name].nil?
  @repo.remotes.create name, url
end

#ahead_of_develop?(branch) ⇒ Boolean

Returns:

  • (Boolean)


210
211
212
# File 'lib/metaverse/repo.rb', line 210

def ahead_of_develop? branch
  has_changes? branch, @repo.branches['develop']
end

#branchesObject



85
86
87
# File 'lib/metaverse/repo.rb', line 85

def branches
  @repo.branches
end

#checkout(ref) ⇒ Object



35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'lib/metaverse/repo.rb', line 35

def checkout ref
  if @repo.branches[ref].nil?
    is_reference = false 
    if Rugged::Reference.valid_name?(ref) and @repo.references[ref].nil?
      raise Errors::ref_not_found ref
    end
  end

  @previous_branches.push current_branch
  Dir.chdir(@repo.workdir) do
    `git checkout #{ref}`#TODO: find out what's going on, check out a branch
  end
end

#clean_branch(branch) ⇒ Object



159
160
161
162
163
164
165
166
167
# File 'lib/metaverse/repo.rb', line 159

def clean_branch branch

  changed = ahead_of_develop? branch
  if not changed
    checkout 'develop'
    @repo.branches.delete branch
  end
  changed
end

#create_ref(ref_name, ref_target) ⇒ Object



90
91
92
# File 'lib/metaverse/repo.rb', line 90

def create_ref ref_name, ref_target
  @repo.references.create ref_name, ref_target.target_id
end

#create_state(prefix, state) ⇒ Object



100
101
102
103
104
105
106
107
108
# File 'lib/metaverse/repo.rb', line 100

def create_state prefix, state
  ref_target = @repo.head
  if not prefix == 'snapshot'
    branch_name = "#{prefix}/#{state}"
    ref_target = @repo.create_branch branch_name
  end
  ref_name = "refs/meta/local/#{prefix}/#{state}"
  create_ref ref_name, ref_target
end

#current_branchObject



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/metaverse/repo.rb', line 50

def current_branch
  branch_name = ''

  Dir.chdir(@repo.workdir) do
    branch_name = `git branch | sed -n '/\* /s///p'`
    #TODO Look into why the command returns an empty string in a new repo
    if branch_name == ''
      branch_name = 'master'
    end
  end

  if branch_name.include? "detached"
    match = /[A-Za-z0-9._-]+(?:\/[A-Za-z0-9._-]+)+/.match(branch_name) 
    if not match.nil?
      return match[0]
    end
    return 'HEAD'
  end

  branch_name.strip
end

#delete_branch(branch) ⇒ Object



169
170
171
172
173
# File 'lib/metaverse/repo.rb', line 169

def delete_branch branch
  if not @repo.branches[branch].nil?
    @repo.branches.delete branch
  end
end

#dirty?Boolean

Returns:

  • (Boolean)


175
176
177
178
179
180
181
182
# File 'lib/metaverse/repo.rb', line 175

def dirty?
  is_dirty = false
  @repo.status { |file, data|
    next if data == [:ignored]
    is_dirty = true
  }
  is_dirty
end

#exec(env, command) ⇒ Object



228
229
230
231
232
# File 'lib/metaverse/repo.rb', line 228

def exec env, command
  Dir.chdir(@repo.workdir) do
    system env, command
  end
end

#has_changes?(ref1, ref2) ⇒ Boolean

Returns:

  • (Boolean)


205
206
207
# File 'lib/metaverse/repo.rb', line 205

def has_changes? ref1, ref2
  not ref1.target_id == ref2.target_id
end

#headObject



80
81
82
# File 'lib/metaverse/repo.rb', line 80

def head
  @repo.head
end

#load(path) ⇒ Object



16
17
18
19
20
21
22
23
24
# File 'lib/metaverse/repo.rb', line 16

def load path
  @repo = Rugged::Repository.new(path)
  @repo.remotes.each_name do |remote|
    fetch_refspec = "+refs/meta/local/*:refs/meta/remotes/#{remote}/*"
    push_refspec = "+refs/meta/local/*:refs/meta/local/*"
    add_option_to_remote remote, fetch_refspec, 'fetch'
    add_option_to_remote remote, push_refspec, 'push'
  end
end

#load_state(prefix, state, remote = nil, should_create_branch = false) ⇒ Object



111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'lib/metaverse/repo.rb', line 111

def load_state prefix, state, remote = nil, should_create_branch = false
  ref_name = "refs/meta"
  ref_name += remote.nil? ? "/local" : "/remotes/#{remote}"
  ref_name += "/#{prefix}/#{state}"
  if should_create_branch
    branch_name = "#{prefix}/#{state}"
    # TODO: Decide what to do when a branch exists previous. Should we :
    # - Replace it's ref by the saved state ? ( We lose the previous branch reference)
    # - Load it as it is ( We may get an inconsistent state since the branch could point to a different commit than the state reference )
    if @repo.branches[branch_name].nil?
      puts "Creating branch #{branch_name} based on #{ref_name}"
      @repo.create_branch branch_name, ref_name
    end
    return checkout branch_name
  end
  checkout ref_name
end

#nameObject



27
28
29
# File 'lib/metaverse/repo.rb', line 27

def name
  File.basename @repo.workdir
end

#peek_previous_branchObject



72
73
74
# File 'lib/metaverse/repo.rb', line 72

def peek_previous_branch
  @previous_branches.last
end

#pop_previous_branchObject



76
77
78
# File 'lib/metaverse/repo.rb', line 76

def pop_previous_branch
  @previous_branches.pop
end

#pull(remote) ⇒ Object



214
215
216
217
218
219
220
221
# File 'lib/metaverse/repo.rb', line 214

def pull remote
  if @repo.remotes[remote].nil?
    return Errors::remote_not_found remote
  end
  Dir.chdir(@repo.workdir) do
    `git pull #{remote} #{current_branch}`
  end
end

#send_state(prefix, state, remote, should_clean = false) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# File 'lib/metaverse/repo.rb', line 130

def send_state prefix, state, remote, should_clean = false
  refs = ["refs/meta/local/#{prefix}/#{state}"]
  branch_name = "#{prefix}/#{state}"
  branch = @repo.branches[branch_name]
  develop = @repo.branches['develop']

  if branch.nil?
    Errors::ref_not_found branch_name
    return false
  end

  if develop.nil?
    Errors::ref_not_found 'develop'
    return false
  end

  if (not prefix == 'snapshot') and ahead_of_develop? branch
      refs << branch_name
      update_ref refs[0], @repo.branches[branch_name]
  end

  clean_branch branch if should_clean

  Dir.chdir(@repo.workdir) do
    `git push #{remote} #{refs.join(' ')}`
  end
end

#update(remote = nil) ⇒ Object



185
186
187
188
189
190
191
192
# File 'lib/metaverse/repo.rb', line 185

def update remote = nil
  if not remote.nil? and @repo.remotes[remote].nil?
    return Errors::remote_not_found remote
  end
  Dir.chdir(@repo.workdir) do
    `git remote update #{remote}`
  end
end

#update_ref(ref_name, ref_target) ⇒ Object



95
96
97
# File 'lib/metaverse/repo.rb', line 95

def update_ref ref_name, ref_target
  @repo.references.update ref_name, ref_target.target_id
end

#workdirObject



31
32
33
# File 'lib/metaverse/repo.rb', line 31

def workdir
  @repo.workdir
end