Class: KnifeCookbookDependencies::Cookbook

Inherits:
Object
  • Object
show all
Defined in:
lib/kcd/cookbook.rb

Constant Summary collapse

DOWNLOAD_LOCATION =
::KCD::TMP_DIRECTORY || '/tmp'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(*args) ⇒ Cookbook

Returns a new instance of Cookbook.



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/kcd/cookbook.rb', line 12

def initialize(*args)
  @options = args.last.is_a?(Hash) ? args.pop : {}
  @groups = []

  if from_git? and from_path?
    raise "Invalid: path and git options provided to #{args[0]}. They are mutually exclusive."
  end

  @options[:path] = File.expand_path(@options[:path]) if from_path?
  @name, constraint_string = args

  add_version_constraint(if from_path?
                           "= #{.to_s}"
                         else
                           constraint_string
                         end)
  @locked_version = DepSelector::Version.new(@options[:locked_version]) if @options[:locked_version]
  add_group(KnifeCookbookDependencies.shelf.active_group) if KnifeCookbookDependencies.shelf.active_group
  add_group(@options[:group]) if @options[:group]
  add_group(:default) if @groups.empty?
end

Instance Attribute Details

#groupsObject (readonly)

Returns the value of attribute groups.



7
8
9
# File 'lib/kcd/cookbook.rb', line 7

def groups
  @groups
end

#locked_versionObject

Returns the value of attribute locked_version.



8
9
10
# File 'lib/kcd/cookbook.rb', line 8

def locked_version
  @locked_version
end

#nameObject (readonly)

Returns the value of attribute name.



7
8
9
# File 'lib/kcd/cookbook.rb', line 7

def name
  @name
end

#version_constraintsObject (readonly)

Returns the value of attribute version_constraints.



7
8
9
# File 'lib/kcd/cookbook.rb', line 7

def version_constraints
  @version_constraints
end

Instance Method Details

#==(other) ⇒ Object



214
215
216
# File 'lib/kcd/cookbook.rb', line 214

def == other
  other.name == @name and other.version_constraints == @version_constraints
end

#add_group(*groups) ⇒ Object



193
194
195
196
197
198
199
# File 'lib/kcd/cookbook.rb', line 193

def add_group(*groups)
  groups = groups.first if groups.first.is_a?(Array)
  groups.each do |group|
    group = group.to_sym
    @groups << group unless @groups.include?(group)
  end
end

#add_version_constraint(constraint_string) ⇒ Object



34
35
36
37
# File 'lib/kcd/cookbook.rb', line 34

def add_version_constraint(constraint_string)
  @version_constraints ||= []
  @version_constraints << DepSelector::VersionConstraint.new(constraint_string) unless @version_constraints.collect(&:to_s).include? constraint_string
end

#clean(location = unpacked_cookbook_path) ⇒ Object



205
206
207
208
209
210
211
212
# File 'lib/kcd/cookbook.rb', line 205

def clean(location = unpacked_cookbook_path)
  if @git
    @git.clean
  else
    FileUtils.rm_rf location
    FileUtils.rm_f download_filename
  end
end

#cookbook_dataObject



136
137
138
139
140
141
# File 'lib/kcd/cookbook.rb', line 136

def cookbook_data
  css = Chef::Knife::CookbookSiteShow.new([@name])
  rescue_404 do
    @cookbook_data ||= JSON.parse(KCD::KnifeUtils.capture_knife_output(css))
  end
end

#copy_to_cookbooks_directoryObject



66
67
68
69
70
71
72
73
74
# File 'lib/kcd/cookbook.rb', line 66

def copy_to_cookbooks_directory
  FileUtils.mkdir_p KCD::COOKBOOKS_DIRECTORY

  target = File.join(KCD::COOKBOOKS_DIRECTORY, @name)
  FileUtils.rm_rf target
  FileUtils.cp_r full_path, target
  KCD.ui.info "#{@name} (#{identifier})"
  FileUtils.rm_rf File.join(target, '.git') if from_git?
end

#dependenciesObject



99
100
101
102
103
104
105
106
107
108
109
# File 'lib/kcd/cookbook.rb', line 99

def dependencies
  download
  unpack

  unless @dependencies
    @dependencies = []
    .dependencies.each { |name, constraint| depends(name, constraint) }
  end

  @dependencies
end

#download(show_output = false) ⇒ Object



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# File 'lib/kcd/cookbook.rb', line 39

def download(show_output = false)
  return if @downloaded
  return if !from_git? and downloaded_archive_exists?
  return if from_path? and !from_git?

  if from_git? 
    @git ||= KCD::Git.new(@options[:git])
    @git.clone
    @git.checkout(@options[:ref]) if @options[:ref]
    @options[:path] ||= @git.directory
  else
    FileUtils.mkdir_p KCD::TMP_DIRECTORY
    csd = Chef::Knife::CookbookSiteDownload.new([name, latest_constrained_version.to_s, "--file", download_filename])

    output = ''
    rescue_404 do
      output = KCD::KnifeUtils.capture_knife_output(csd)
    end

    if show_output
      output.split(/\r?\n/).each { |x| KCD.ui.info(x) }
    end
  end

  @downloaded = true
end

#download_filenameObject



143
144
145
146
# File 'lib/kcd/cookbook.rb', line 143

def download_filename
  return nil if from_path?
  File.join(DOWNLOAD_LOCATION, "#{@name}-#{latest_constrained_version}.tar.gz")
end

#downloaded_archive_exists?Boolean

Returns:

  • (Boolean)


201
202
203
# File 'lib/kcd/cookbook.rb', line 201

def downloaded_archive_exists?
  download_filename && File.exists?(download_filename)
end

#from_git?Boolean

Returns:

  • (Boolean)


181
182
183
# File 'lib/kcd/cookbook.rb', line 181

def from_git?
  !!git_repo
end

#from_path?Boolean

Returns:

  • (Boolean)


177
178
179
# File 'lib/kcd/cookbook.rb', line 177

def from_path?
  !!local_path
end

#full_pathObject



152
153
154
155
156
157
158
# File 'lib/kcd/cookbook.rb', line 152

def full_path
  if @git
    unpacked_cookbook_path
  else
    File.join(unpacked_cookbook_path, @name)
  end
end

#git_refObject



189
190
191
# File 'lib/kcd/cookbook.rb', line 189

def git_ref
  (from_git? && @git) ? @git.ref : nil
end

#git_repoObject



185
186
187
# File 'lib/kcd/cookbook.rb', line 185

def git_repo
  @options[:git]
end

#identifierObject



76
77
78
# File 'lib/kcd/cookbook.rb', line 76

def identifier
  @git_repo || local_path || latest_constrained_version
end

#latest_constrained_versionObject



111
112
113
114
115
116
117
118
119
120
# File 'lib/kcd/cookbook.rb', line 111

def latest_constrained_version
  return @locked_version if @locked_version
  return  if from_path? or from_git?

  versions.reverse.each do |v|
    return v if version_constraints_include? v
  end
  KCD.ui.fatal "No version available to fit the following constraints for #{@name}: #{version_constraints.inspect}\nAvailable versions: #{versions.inspect}"
  exit 1
end

#local_pathObject



173
174
175
# File 'lib/kcd/cookbook.rb', line 173

def local_path
  @options[:path]
end

#metadataObject



164
165
166
167
168
169
170
171
# File 'lib/kcd/cookbook.rb', line 164

def 
  download
  unpack

   = Chef::Cookbook::Metadata.new
  .from_file()
  
end

#metadata_filenameObject



160
161
162
# File 'lib/kcd/cookbook.rb', line 160

def 
  File.join(full_path, "metadata.rb")
end

#rescue_404Object



218
219
220
221
222
223
224
225
# File 'lib/kcd/cookbook.rb', line 218

def rescue_404
  begin
    yield
  rescue Net::HTTPServerException => e
    KCD.ui.fatal ErrorMessages.missing_cookbook(@name) if e.message.match(/404/)
    exit 100
  end
end

#unpack(location = unpacked_cookbook_path, options = {}) ⇒ Object

TODO: Clean up download repetition functionality here, in #download and the associated test.



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
# File 'lib/kcd/cookbook.rb', line 81

def unpack(location = unpacked_cookbook_path, options={})
  return true if from_path?

  clean     if options[:clean]
  download  if options[:download]

  unless downloaded_archive_exists? or File.directory?(location)
    # TODO raise friendly error
    raise "Archive hasn't been downloaded yet"
  end

  if downloaded_archive_exists?
    Archive::Tar::Minitar.unpack(Zlib::GzipReader.new(File.open(download_filename)), location)
  end

  return true
end

#unpacked_cookbook_pathObject



148
149
150
# File 'lib/kcd/cookbook.rb', line 148

def unpacked_cookbook_path
  @options[:path] || File.join(File.dirname(download_filename), File.basename(download_filename, '.tar.gz'))
end

#version_constraints_include?(version) ⇒ Boolean

Returns:

  • (Boolean)


122
123
124
# File 'lib/kcd/cookbook.rb', line 122

def version_constraints_include?(version)
  @version_constraints.inject(true) { |check, constraint| check and constraint.include? version }
end

#version_from_metadataObject



132
133
134
# File 'lib/kcd/cookbook.rb', line 132

def 
  DepSelector::Version.new(.version)
end

#versionsObject



126
127
128
129
130
# File 'lib/kcd/cookbook.rb', line 126

def versions
  return [latest_constrained_version] if @locked_version
  return [] if from_path? or from_git?
  cookbook_data['versions'].collect { |v| DepSelector::Version.new(v.split(/\//).last.gsub(/_/, '.')) }.sort
end