Class: Sunshine::Repo

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

Overview

An abstract class to wrap simple basic scm features. The primary function of repo objects is to get information about the scm branch that is being deployed and to check it out on remote deploy servers:

svn = SvnRepo.new "svn://path/to/repo", :flags => "--ignore-externals"

The :flags option can be a String or an Array and supports any scm checkout (or clone for git) options.

Direct Known Subclasses

GitRepo, RsyncRepo, SvnRepo

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(url, options = {}) ⇒ Repo

Returns a new instance of Repo.



88
89
90
91
92
93
# File 'lib/sunshine/repo.rb', line 88

def initialize url, options={}
  @scm = self.class.name.split("::").last.sub('Repo', '').downcase

  @url   = url.to_s
  @flags = [*options[:flags]].compact
end

Instance Attribute Details

#flagsObject

Returns the value of attribute flags.



86
87
88
# File 'lib/sunshine/repo.rb', line 86

def flags
  @flags
end

#scmObject

Returns the value of attribute scm.



86
87
88
# File 'lib/sunshine/repo.rb', line 86

def scm
  @scm
end

#urlObject

Returns the value of attribute url.



86
87
88
# File 'lib/sunshine/repo.rb', line 86

def url
  @url
end

Class Method Details

.detect(path = ".", shell = nil) ⇒ Object

Looks for .git and .svn directories and determines if the passed path is a recognized repo. Does not check for RsyncRepo since it’s a special case. Returns the appropriate repo object:

Repo.detect "path/to/svn/repo/dir"
  #=> <SvnRepo @url="svn://url/of/checked/out/repo">
Repo.detect "path/to/git/repo/dir"
  #=> <GitRepo, @url="git://url/of/git/repo", @branch="master">
Repo.detect "invalid/repo/path"
  #=> nil


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

def self.detect path=".", shell=nil
  @@repo_types.values.each do |repo|
    if repo.valid? path
      info = repo.get_info path, shell
      return repo.new(info[:url], info)
    end
  end

  nil
end

.get_info(path = ".", shell = nil) ⇒ Object

Gets repo information for the specified dir - Implemented by subclass

Raises:



70
71
72
73
# File 'lib/sunshine/repo.rb', line 70

def self.get_info path=".", shell=nil
  raise RepoError,
    "The 'get_info' method must be implemented by child classes"
end

.inherited(subclass) ⇒ Object

Adds subclasses to a repo_types hash for easy



17
18
19
20
21
22
23
24
25
26
27
# File 'lib/sunshine/repo.rb', line 17

def self.inherited subclass
  @@repo_types ||= {}

  # Turn Sunshine::ScmNameRepo into :scm_name
  class_key = subclass.to_s.split("::").last
  class_key = $1 if class_key =~ /(\w+)Repo$/
  class_key.gsub!(/([a-z0-9])([A-Z])/, '\1_\2')
  class_key = class_key.downcase

  @@repo_types[class_key] = subclass
end

.new_of_type(repo_type, url, options = {}) ⇒ Object

Creates a new repo subclass object:

Repo.new_of_type :svn, "https://path/to/repo/tags/releasetag"
Repo.new_of_type :git, "[email protected]:repo/path"

Raises:



35
36
37
38
39
40
41
# File 'lib/sunshine/repo.rb', line 35

def self.new_of_type repo_type, url, options={}
  repo_class = @@repo_types[repo_type.to_s]

  raise RepoError, "Invalid type #{repo_type.inspect}" unless repo_class

  repo_class.new(url, options)
end

.valid?(*args) ⇒ Boolean

Checks if current working directory is a valid repo. Defaults to false. Subclasses must override this method to enable auto detecting of a given scm implementation.

Returns:

  • (Boolean)


81
82
83
# File 'lib/sunshine/repo.rb', line 81

def self.valid? *args
  false
end

Instance Method Details

#checkout_to(path, shell = nil) ⇒ Object

Checkout code to a shell and return an info log hash:

repo.chekout_to "some/path", remote_shell
#=> {:revision => 123, :committer => 'someone', :date => time_obj ...}


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

def checkout_to path, shell=nil
  shell ||= Sunshine.shell

  shell.call "test -d #{path} && rm -rf #{path} || echo false"
  shell.call "mkdir -p #{path}"

  do_checkout     path, shell
  get_repo_info   path, shell
end

#do_checkout(path, shell) ⇒ Object

Checkout the repo - implemented by subclass

Raises:



116
117
118
119
# File 'lib/sunshine/repo.rb', line 116

def do_checkout path, shell
  raise RepoError,
    "The 'do_checkout' method must be implemented by child classes"
end

#get_repo_info(path = ".", shell = nil) ⇒ Object

Returns the repo information as a hash.



142
143
144
145
146
# File 'lib/sunshine/repo.rb', line 142

def get_repo_info path=".", shell=nil
  defaults = {:type => @scm, :url => @url, :path => path}

  defaults.merge self.class.get_info(path, shell)
end

#nameObject

Get the project name of the specified repo - implemented by subclass

Raises:



125
126
127
128
# File 'lib/sunshine/repo.rb', line 125

def name
  raise RepoError,
    "The 'name' method must be implemented by child classes"
end

#scm_flagsObject

Returns the set scm flags as a string



134
135
136
# File 'lib/sunshine/repo.rb', line 134

def scm_flags
  @flags.join(" ")
end