Class: Coral::Repository

Inherits:
Core show all
Defined in:
lib/coral_core/repository.rb

Constant Summary collapse

@@repositories =
{}

Instance Attribute Summary collapse

Attributes inherited from Core

#ui

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Core

#logger, logger, logger=, ui

Methods inherited from Config

#[], #[]=, array, #array, #clear, #defaults, #delete, ensure, #export, #filter, filter, #get, #get_array, #get_hash, hash, #hash, #import, #init, init_flat, #set, string, #string, string_map, #string_map, #symbol, symbol, #symbol_map, symbol_map, test, #test

Methods included from Mixin::ConfigOptions

#clear_options, #contexts, #get_options, #set_options

Methods included from Mixin::ConfigCollection

#all_properties, #clear_properties, #delete_property, #get_property, #save_properties, #set_property

Methods included from Mixin::Lookup

#hiera, #hiera_config, #initialized?, #lookup, #lookup_array, #lookup_hash, #normalize

Methods included from Mixin::ConfigOps

#parse

Constructor Details

#initialize(options = {}) ⇒ Repository




42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/coral_core/repository.rb', line 42

def initialize(options = {})
  config = Config.ensure(options)
  
  super(config)
  
  set_location(config.get(:directory, Dir.pwd))
  
  @cloud       = config.get(:object_container, nil)
  @remote_path = config.get(:remote_path, nil)
  
  @origin   = config.get(:origin, nil)
  @revision = config.get(:revision, nil)
  
  set_origin(@origin) unless @origin.nil?
  checkout(@revision) unless @revision.nil?
  
  pull if config.get(:pull, false)
end

Instance Attribute Details

#directoryObject (readonly)


Property accessors / modifiers



178
179
180
# File 'lib/coral_core/repository.rb', line 178

def directory
  @directory
end

#editObject (readonly)


Remote operations



401
402
403
# File 'lib/coral_core/repository.rb', line 401

def edit
  @edit
end

#originObject (readonly)


Remote operations



401
402
403
# File 'lib/coral_core/repository.rb', line 401

def origin
  @origin
end

#parentObject (readonly)


Basic Git operations



245
246
247
# File 'lib/coral_core/repository.rb', line 245

def parent
  @parent
end

#revisionObject (readonly)


Basic Git operations



245
246
247
# File 'lib/coral_core/repository.rb', line 245

def revision
  @revision
end

#submodulesObject (readonly)


Submodule operations



330
331
332
# File 'lib/coral_core/repository.rb', line 330

def submodules
  @submodules
end

Class Method Details

.collectionObject




8
9
10
# File 'lib/coral_core/repository.rb', line 8

def self.collection
  return @@repositories
end

.edit_url(url, options = {}) ⇒ Object




103
104
105
106
107
108
109
110
111
# File 'lib/coral_core/repository.rb', line 103

def self.edit_url(url, options = {})
  config = Config.ensure(options)
  
  if matches = url.strip.match(/^(https?|git)\:\/\/([^\/]+)\/(.+)/)
    host, path = matches.captures
    return url(host, path, config.import({ :auth => true }))
  end
  return url
end

.git_dir(path, require_top_level = false) ⇒ Object


Location information



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/coral_core/repository.rb', line 70

def self.git_dir(path, require_top_level = false)
  path = File.expand_path(path)
  git_dir = File.join(path, '.git')

  if File.exist?(git_dir)
    if File.directory?(git_dir)
      return git_dir
    elsif ! require_top_level
      git_dir = Util::Disk.read(git_dir)
      unless git_dir.nil?
        git_dir = git_dir.gsub(/^gitdir\:\s*/, '').strip
        return git_dir if File.directory?(git_dir)
      end
    end
  elsif File.exist?(path) && (path =~ /\.git$/ && File.exist?(File.join(path, 'HEAD')))
    return path
  end
  return nil
end

.init(directory, url, revision, options = {}) ⇒ Object


Constructor / Destructor



15
16
17
18
19
20
21
22
23
# File 'lib/coral_core/repository.rb', line 15

def self.init(directory, url, revision, options = {})
  config = Config.ensure(options)
  
  return new(config.import({
    :directory => directory,
    :origin => url,
    :revision => revision
  }))
end

.open(directory, options = {}) ⇒ Object




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

def self.open(directory, options = {})
  config = Config.ensure(options)
  
  directory = Util::Disk.filename(directory)
  
  if ! @@repositories.has_key?(directory) || config.get(:reset, false)
    return new(config.import({
      :directory => directory
    }))
  end
  return @@repositories[directory]
end

.submodule?(path) ⇒ Boolean


Returns:

  • (Boolean)


155
156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/coral_core/repository.rb', line 155

def self.submodule?(path)
  git_dir = File.join(path, '.git')
  if File.exist?(git_dir)
    unless File.directory?(git_dir)
      git_dir = Util::Disk.read(git_dir)
      unless git_dir.nil?
        git_dir = git_dir.gsub(/^gitdir\:\s*/, '').strip
        return true if File.directory?(git_dir)
      end
    end
  end
  return false
end

.top?(path) ⇒ Boolean


Returns:

  • (Boolean)


137
138
139
140
141
142
143
144
145
# File 'lib/coral_core/repository.rb', line 137

def self.top?(path)
  git_dir = File.join(path, '.git')
  if File.exist?(git_dir)
    return true if File.directory?(git_dir)
  elsif File.exist?(path) && (path =~ /\.git$/ && File.exist?(File.join(path, 'HEAD')))
    return true
  end
  return false
end

.url(host, repo, options = {}) ⇒ Object


URLs



93
94
95
96
97
98
99
# File 'lib/coral_core/repository.rb', line 93

def self.url(host, repo, options = {})
  config = Config.ensure(options)
  
  user = config.get(:user, 'git')
  auth = config.get(:auth, true)
  return user + (auth ? '@' : '://') + host + (auth ? ':' : '/') + repo
end

Instance Method Details

#add_remote_url(name, url, options = {}) ⇒ Object




438
439
440
441
442
443
444
445
446
447
448
449
# File 'lib/coral_core/repository.rb', line 438

def add_remote_url(name, url, options = {})
  config = Config.ensure(options)
  
  if can_persist?
    git.remote({
      :add => true,
      :delete => config.get(:delete, false),
      :push => config.get(:push, false)
    }, 'set-url', name.to_s, url)
  end
  return self
end

#add_submodule(path, url, revision, options = {}) ⇒ Object




353
354
355
356
357
358
359
# File 'lib/coral_core/repository.rb', line 353

def add_submodule(path, url, revision, options = {})
  if can_persist?
    git.submodule({ :branch => revision }, 'add', url, path)
    commit([ '.gitmodules', path ], { :message => "Adding submodule #{url} to #{path}" })
    load_submodules
  end
end

#can_persist?Boolean


Returns:

  • (Boolean)


129
130
131
132
133
# File 'lib/coral_core/repository.rb', line 129

def can_persist?
  ensure_git
  return true if @git_lib
  return false
end

#checkout(revision) ⇒ Object




283
284
285
286
287
288
289
290
291
292
# File 'lib/coral_core/repository.rb', line 283

def checkout(revision)
  if can_persist?
    revision = revision.strip
    
    git.checkout({}, revision) unless @git_lib.bare
    @revision = revision
    load_submodules
  end
  return self
end

#commit(files = '.', options = {}) ⇒ Object




296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'lib/coral_core/repository.rb', line 296

def commit(files = '.', options = {})
  config = Config.ensure(options)
  
  if can_persist?
    time = Time.new.strftime("%Y-%m-%d %H:%M:%S")
    user = ENV['USER']
    message = config.get(:message, 'Saving state')
    
    user = 'UNKNOWN' unless user && ! user.empty?
          
    git.reset({}, 'HEAD') # Clear the index so we get a clean commit
    
    files = array(files)
    git.add(files) # Get all added and updated files
    git.add({ :update => true }, files) # Get all deleted files
  
    git.commit({
      :m => "#{time} by <#{user}> - #{message}",
      :author => config.get(:author, false),
      :allow_empty => config.get(:allow_empty, false)
    })
    
    if ! parent.nil? && config.get(:propogate, true)
      parent.commit(directory, config.import({
        :message => "Updating submodule #{path} with: #{message}"
      }))
    end
  end
  return self
end

#config(name, options = {}) ⇒ Object




199
200
201
202
203
# File 'lib/coral_core/repository.rb', line 199

def config(name, options = {})
  config = Config.ensure(options) # Just in case we throw a configuration in
  return git.config(config.export, name) if can_persist?
  return nil
end

#delete_config(name, options = {}) ⇒ Object




215
216
217
218
219
# File 'lib/coral_core/repository.rb', line 215

def delete_config(name, options = {})
  config = Config.ensure(options)
  git.config(config.import({ :remove_section => true }).options, name) if can_persist?
  return self
end

#delete_remote(name) ⇒ Object




474
475
476
477
478
479
# File 'lib/coral_core/repository.rb', line 474

def delete_remote(name)
  if can_persist? && git.list_remotes.include?(name)
    git.remote({}, 'rm', name.to_s)
  end
  return self
end

#delete_submodule(path) ⇒ Object




363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
# File 'lib/coral_core/repository.rb', line 363

def delete_submodule(path)
  if can_persist?
    submodule_key = "submodule.#{path}"
    
    delete_config(submodule_key)
    delete_config(submodule_key, { :file => '.gitmodules' })
    
    git.rm({ :cached => true }, path)
    FileUtils.rm_rf(File.join(directory, path))
    FileUtils.rm_rf(File.join(git.git_dir, 'modules', path))
    
    commit([ '.gitmodules', path ], { :message => "Removing submodule #{url} from #{path}" })
    load_submodules
  end
end

#foreach!Object




389
390
391
392
393
394
395
396
# File 'lib/coral_core/repository.rb', line 389

def foreach!
  if can_persist?
    submodules.each do |path, repo|
      yield(path, repo)
    end
  end
  return self
end

#inspectObject




63
64
65
# File 'lib/coral_core/repository.rb', line 63

def inspect
  "#<#{self.class}: #{directory} : #{@origin} : #{@revision}>"
end

#pathObject




182
183
184
185
186
187
# File 'lib/coral_core/repository.rb', line 182

def path
  if parent.nil?
    return directory
  end
  return directory.gsub(parent.directory + File::SEPARATOR, '')
end

#pull(remote = :origin, options = {}) ⇒ Object




515
516
517
# File 'lib/coral_core/repository.rb', line 515

def pull(remote = :origin, options = {})
  return pull!(remote, options)
end

#pull!(remote = :origin, options = {}) ⇒ Object


SSH operations



484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
# File 'lib/coral_core/repository.rb', line 484

def pull!(remote = :origin, options = {})
  config = Config.ensure(options)
  success = false
  
  if can_persist?
    success = Command.new({
      :command => :git,
      :data => { 'git-dir=' => git.git_dir },
      :subcommand => {
        :command => :pull,
        :flags => ( config.get(:tags, true) ? :tags : '' ),
        :args => [ remote, config.get(:branch, '') ]
      }
    }).exec!(config) do |line|
      block_given? ? yield(line) : true
    end
    
    update_submodules
    
    if success && ! parent.nil? && config.get(:propogate, true)
      parent.commit(directory, config.import({
        :message => "Pulling updates for submodule #{path}",
        :allow_empty => true
      }))
    end
  end
  return success
end

#push(remote = :edit, options = {}) ⇒ Object




549
550
551
# File 'lib/coral_core/repository.rb', line 549

def push(remote = :edit, options = {})
  return push!(remote, options)
end

#push!(remote = :edit, options = {}) ⇒ Object




521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
# File 'lib/coral_core/repository.rb', line 521

def push!(remote = :edit, options = {})
  config = Config.ensure(options)
  success = false
  
  if can_persist?
    success = Command.new({
      :command => :git,
      :data => { 'git-dir=' => git.git_dir },
      :subcommand => {
        :command => :push,
        :flags => ( config.get(:tags, true) ? :tags : '' ),
        :args => [ remote, config.get(:branch, '') ]
      }
    }).exec!(config) do |line|
      block_given? ? yield(line) : true
    end
    
    if success && config.get(:propogate, true)
      foreach! do |path, repo|
        repo.push(remote, config)
      end
    end
  end
  return success
end

#set_config(name, value, options = {}) ⇒ Object




207
208
209
210
211
# File 'lib/coral_core/repository.rb', line 207

def set_config(name, value, options = {})
  config = Config.ensure(options) # Just in case we throw a configuration in
  git.config(config.export, name, string(value)) if can_persist?
  return self
end

#set_edit(url) ⇒ Object




422
423
424
425
426
# File 'lib/coral_core/repository.rb', line 422

def set_edit(url)
  set_remote('edit', url)
  @edit = url
  return self
end

#set_host_remote(name, hosts, path, options = {}) ⇒ Object




453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
# File 'lib/coral_core/repository.rb', line 453

def set_host_remote(name, hosts, path, options = {})
  config = Config.ensure(options)
  
  if can_persist?
    hosts = array(hosts)
    
    return self if hosts.empty?
    
    set_remote(name.to_s, url(hosts.shift, path, config.options))
    
    unless hosts.empty?
      hosts.each do |host|
        add_remote_url(name.to_s, url(host, path, config.options), config)
      end
    end
  end
  return self
end

#set_location(directory) ⇒ Object




223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
# File 'lib/coral_core/repository.rb', line 223

def set_location(directory)
  @@repositories.delete(@directory) if @directory
  
  if Util::Data.empty?(directory)
    @directory = Dir.pwd
  else
    @directory = Util::Disk.filename(directory)
  end
  
  @@repositories[@directory] = self
  
  ensure_git(true)
  
  init_parent
  init_remotes
  load_revision
  return self
end

#set_origin(url) ⇒ Object




414
415
416
417
418
# File 'lib/coral_core/repository.rb', line 414

def set_origin(url)
  set_remote('origin', url)
  @origin = url
  return self
end

#set_remote(name, url) ⇒ Object




430
431
432
433
434
# File 'lib/coral_core/repository.rb', line 430

def set_remote(name, url)
  delete_remote(name)
  git.remote({}, 'add', name.to_s, url) if can_persist?
  return self
end

#submodule?Boolean


Returns:

  • (Boolean)


171
172
173
# File 'lib/coral_core/repository.rb', line 171

def submodule?
  return self.class.submodule?(directory)
end

#top?Boolean


Returns:

  • (Boolean)


149
150
151
# File 'lib/coral_core/repository.rb', line 149

def top?
  return self.class.top?(directory)
end