Class: Babushka::Source

Inherits:
Object show all
Extended by:
LogHelpers, PathHelpers, ShellHelpers
Includes:
LogHelpers, PathHelpers
Defined in:
lib/babushka/source.rb

Direct Known Subclasses

ImplicitSource

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from PathHelpers

cd, in_build_dir, in_download_dir

Methods included from ShellHelpers

cmd_dir, current_username, log_shell, login_shell, raw_shell, shell, shell!, shell?, shell_cmd, sudo, which

Methods included from LogHelpers

debug, deprecated!, log, log_block, log_error, log_ok, log_stderr, log_warn, removed!

Constructor Details

#initialize(path, name = nil, uri = nil) ⇒ Source

Returns a new instance of Source

Raises:

  • (ArgumentError)


40
41
42
43
44
45
46
47
# File 'lib/babushka/source.rb', line 40

def initialize path, name = nil, uri = nil
  raise ArgumentError, "Sources with nil paths require a name (as the second argument)." if path.nil? && name.nil?
  raise ArgumentError, "The source URI can only be supplied if the source doesn't exist already." if !uri.nil? && !path.nil? && path.p.exists?
  init
  @path = path.p unless path.nil?
  @name = name
  @uri = uri
end

Instance Attribute Details

#depsObject (readonly)

Returns the value of attribute deps



13
14
15
# File 'lib/babushka/source.rb', line 13

def deps
  @deps
end

#nameObject (readonly)

Returns the value of attribute name



13
14
15
# File 'lib/babushka/source.rb', line 13

def name
  @name
end

#pathObject (readonly)

Returns the value of attribute path



13
14
15
# File 'lib/babushka/source.rb', line 13

def path
  @path
end

#templatesObject (readonly)

Returns the value of attribute templates



13
14
15
# File 'lib/babushka/source.rb', line 13

def templates
  @templates
end

#uriObject (readonly)

Returns the value of attribute uri



13
14
15
# File 'lib/babushka/source.rb', line 13

def uri
  @uri
end

Class Method Details

.default_remote_for(name) ⇒ Object



31
32
33
34
35
36
37
38
# File 'lib/babushka/source.rb', line 31

def self.default_remote_for name
  if name == 'common'
    # This is a special case.
    "https://github.com/benhoskings/common-babushka-deps.git"
  else
    "https://github.com/#{name}/babushka-deps.git"
  end
end

.for_path(path) ⇒ Object



21
22
23
24
25
# File 'lib/babushka/source.rb', line 21

def self.for_path path
  source = Source.new(path)
  @sources ||= {}
  @sources[source.name] ||= source
end

.for_remote(name) ⇒ Object



27
28
29
# File 'lib/babushka/source.rb', line 27

def self.for_remote name
  Source.new(nil, name, default_remote_for(name))
end

.presentObject



15
16
17
18
19
# File 'lib/babushka/source.rb', line 15

def self.present
  source_prefix.glob('*').map {|path|
    Source.for_path(path.p)
  }
end

Instance Method Details

#==(other) ⇒ Object



102
103
104
105
106
107
# File 'lib/babushka/source.rb', line 102

def == other
  [:name, :uri, :type].all? {|method_name| other.respond_to? method_name } &&
  name == other.name &&
  uri == other.uri &&
  type == other.type
end

#add!Object



119
120
121
122
123
124
125
126
# File 'lib/babushka/source.rb', line 119

def add!
  if !remote?
    log "Nothing to add for #{name}."
  else
    raise_unless_addable!
    update!
  end
end

#clear!Object



128
129
130
131
# File 'lib/babushka/source.rb', line 128

def clear!
  deps.clear!
  templates.clear!
end

#description_piecesObject



93
94
95
96
97
98
99
100
# File 'lib/babushka/source.rb', line 93

def description_pieces
  [
    name,
    uri.to_s,
    type,
    ("#{updated_at.round.xsecs} ago" if remote?)
  ]
end

#find(dep_spec) ⇒ Object



109
110
111
112
# File 'lib/babushka/source.rb', line 109

def find dep_spec
  load!
  deps.for(dep_spec)
end

#find_template(template_spec) ⇒ Object



114
115
116
117
# File 'lib/babushka/source.rb', line 114

def find_template template_spec
  load!
  templates.for(template_spec)
end

#implicit?Boolean

Returns:

  • (Boolean)


69
70
71
# File 'lib/babushka/source.rb', line 69

def implicit?
  type == :implicit
end

#inspectObject



207
208
209
# File 'lib/babushka/source.rb', line 207

def inspect
  "#<Source:#{object_id} '#{name}' (#{path} <- #{uri}) (#{deps.count} dep#{'s' unless deps.count == 1})>"
end

#load!(should_update = false) ⇒ Object



133
134
135
136
137
138
139
140
# File 'lib/babushka/source.rb', line 133

def load! should_update = false
  unless @currently_loading
    @currently_loading = true
    update! if remote? && (!repo? || should_update)
    load_deps! unless implicit? # implicit sources can't be loaded.
    @currently_loading = false
  end
end

#load_deps!Object



142
143
144
145
146
147
148
149
150
151
152
153
154
155
# File 'lib/babushka/source.rb', line 142

def load_deps!
  unless @loaded
    path.p.glob('**/*.rb').each {|f|
      Base.sources.load_context :source => self, :path => f do
        load f, true
      end
    }
    debug "Loaded #{deps.count} deps from #{path}."
    @loaded = true
  end
rescue StandardError, SyntaxError => e
  clear!
  raise SourceLoadError.new(e.message).tap {|raised| raised.set_backtrace(e.backtrace) }
end

#local?Boolean

Returns:

  • (Boolean)


73
74
75
# File 'lib/babushka/source.rb', line 73

def local?
  type == :local
end

#present?Boolean

Returns:

  • (Boolean)


61
62
63
# File 'lib/babushka/source.rb', line 61

def present?
  path.exists?
end

#remote?Boolean

Returns:

  • (Boolean)


77
78
79
# File 'lib/babushka/source.rb', line 77

def remote?
  type == :remote
end

#repoObject



81
82
83
# File 'lib/babushka/source.rb', line 81

def repo
  @repo ||= Babushka::GitRepo.new(path)
end

#repo?Boolean

Returns:

  • (Boolean)


85
86
87
# File 'lib/babushka/source.rb', line 85

def repo?
  repo.exists? && (repo.root == path)
end

#typeObject



65
66
67
# File 'lib/babushka/source.rb', line 65

def type
  uri.nil? ? :local : :remote
end

#update!Object



157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/babushka/source.rb', line 157

def update!
  if @updated
    debug "Already pulled #{name} (#{uri}) this session."
    true
  elsif Base.sources.local_only?
    debug "Not pulling #{name} (#{uri}) - in local-only mode."
    true
  elsif @updated == false
    debug "Not updating #{name} (#{uri}) - it's offline."
  elsif repo.exists? && repo.dirty?
    log "Not updating #{name} (#{path}) because there are local changes."
  elsif repo.exists? && repo.ahead?
    @updated = false # So the ahead? check doesn't run again, for when there's no network.
    log "Not updating #{name} (#{path}) because it's ahead of origin."
  else
    GitHelpers.git(uri, :to => path, :log => true).tap {|result|
      log "Marking #{uri} as offline for this run." unless result
      @updated = result || false
    }
  end
end

#updated_atObject



89
90
91
# File 'lib/babushka/source.rb', line 89

def updated_at
  Time.now - File.mtime(path)
end