vendorificator 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (58) hide show
  1. data/.travis.yml +2 -4
  2. data/CHANGELOG.md +12 -0
  3. data/Gemfile +5 -1
  4. data/README.md +33 -0
  5. data/Rakefile +7 -0
  6. data/cucumber.yml +1 -1
  7. data/features/download.feature +14 -0
  8. data/features/environment.feature +27 -2
  9. data/features/fixtures/rubygems/.gitignore +1 -0
  10. data/features/fixtures/rubygems/Marshal.4.8 +0 -0
  11. data/features/fixtures/rubygems/Marshal.4.8.Z +2 -0
  12. data/features/fixtures/rubygems/Rakefile +46 -0
  13. data/features/fixtures/rubygems/gems/first-0.gem +0 -0
  14. data/features/fixtures/rubygems/gems/hello-0.0.1.gem +0 -0
  15. data/features/fixtures/rubygems/gems/second-0.gem +0 -0
  16. data/features/fixtures/rubygems/latest_specs.4.8 +0 -0
  17. data/features/fixtures/rubygems/latest_specs.4.8.gz +0 -0
  18. data/features/fixtures/rubygems/prerelease_specs.4.8 +0 -0
  19. data/features/fixtures/rubygems/prerelease_specs.4.8.gz +0 -0
  20. data/features/fixtures/rubygems/quick/Marshal.4.8/first-0.gemspec.rz +0 -0
  21. data/features/fixtures/rubygems/quick/Marshal.4.8/hello-0.0.1.gemspec.rz +3 -0
  22. data/features/fixtures/rubygems/quick/Marshal.4.8/second-0.gemspec.rz +0 -0
  23. data/features/fixtures/rubygems/specs.4.8 +0 -0
  24. data/features/fixtures/rubygems/specs.4.8.gz +0 -0
  25. data/features/fixtures/rubygems/src/README.md +4 -0
  26. data/features/fixtures/rubygems/src/first.gemspec +16 -0
  27. data/features/fixtures/rubygems/src/second.gemspec +14 -0
  28. data/features/fixtures/vcr/vendorificator.yml +551 -56
  29. data/features/git.feature +5 -2
  30. data/features/step_definitions/aruba_ext.rb +1 -0
  31. data/features/step_definitions/basic.rb +7 -0
  32. data/features/step_definitions/git.rb +14 -1
  33. data/features/step_definitions/vendorificator.rb +6 -2
  34. data/features/support/aruba_ext.rb +8 -0
  35. data/features/support/env.rb +3 -0
  36. data/features/support/minigit.rb +6 -0
  37. data/features/tarball.feature +3 -0
  38. data/features/tool.feature +67 -0
  39. data/features/tool_shortcuts.feature +42 -0
  40. data/features/vendor.feature +4 -1
  41. data/lib/vendorificator/cli.rb +7 -2
  42. data/lib/vendorificator/commit.rb +56 -0
  43. data/lib/vendorificator/config.rb +6 -0
  44. data/lib/vendorificator/environment.rb +66 -9
  45. data/lib/vendorificator/vendor/archive.rb +62 -40
  46. data/lib/vendorificator/vendor/download.rb +20 -10
  47. data/lib/vendorificator/vendor/git.rb +20 -13
  48. data/lib/vendorificator/vendor/tool.rb +60 -0
  49. data/lib/vendorificator/vendor.rb +113 -74
  50. data/lib/vendorificator/version.rb +1 -1
  51. data/lib/vendorificator.rb +2 -0
  52. data/spec/spec_helper.rb +18 -8
  53. data/spec/vendorificator/config_spec.rb +7 -0
  54. data/spec/vendorificator/environment_spec.rb +21 -0
  55. data/spec/vendorificator/vendor/git_spec.rb +23 -0
  56. data/spec/vendorificator/vendor_spec.rb +68 -0
  57. data/vendorificator.gemspec +9 -3
  58. metadata +110 -9
@@ -10,12 +10,69 @@ require 'vendorificator/vendor'
10
10
  module Vendorificator
11
11
  class Vendor::Archive < Vendor
12
12
  arg_reader :url, :strip_root, :type, :checksum, :filename, :basename, :extname, :unpack
13
- attr_reader :conjured_checksum
13
+ attr_reader :conjured_checksum, :conjured_filesize
14
14
 
15
- def initialize(environment, name, args={}, &block)
15
+ def conjure!
16
+ shell.say_status :download, url
17
+ archive = download_file
18
+ shell.say_status :unpack, filename
19
+ unpack_file archive
20
+ add_archive_metadata
21
+ super
22
+ ensure
23
+ if archive
24
+ archive.close
25
+ archive.unlink
26
+ end
27
+ end
28
+
29
+ def upstream_version
30
+ filename
31
+ end
32
+
33
+ def conjure_commit_message
34
+ rv = "Conjured archive #{name} from #{filename}\nOrigin: #{url}\nChecksum: #{conjured_checksum}\n"
35
+ rv << "Version: #{version}\n" if version
36
+ rv
37
+ end
38
+
39
+ private
40
+
41
+ def download_file
42
+ archive = Tempfile.new([basename, extname])
43
+ archive.write( open(url).read )
44
+ @conjured_filesize = archive.size
45
+ archive.close
46
+ @conjured_checksum = Digest::SHA256.file(archive.path).hexdigest
47
+ raise RuntimeError, "Checksum error" if checksum && checksum != conjured_checksum
48
+
49
+ archive
50
+ end
51
+
52
+ def unpack_file(archive)
53
+ system "#{unpack} #{Escape.shell_single_word archive.path}"
54
+ if Dir.entries('.').length == 3 && !args[:no_strip_root]
55
+ root = (Dir.entries('.') - %w(.. .)).first
56
+ root_entries = Dir.entries(root) - %w(.. .)
57
+ while root_entries.include?(root)
58
+ FileUtils::mv root, root+"~"
59
+ root << "~"
60
+ end
61
+ FileUtils::mv root_entries.map { |e| File.join(root, e) }, '.'
62
+ FileUtils::rmdir root
63
+ end
64
+ end
65
+
66
+ def add_archive_metadata
67
+ @metadata[:archive_checksum] = conjured_checksum
68
+ @metadata[:archive_filesize] = conjured_filesize
69
+ @metadata[:archive_url] = url
70
+ end
71
+
72
+ def parse_initialize_args(args = {})
16
73
  no_url_given = !args[:url]
17
74
 
18
- args[:url] ||= name
75
+ args[:url] ||= @name
19
76
  args[:filename] ||= URI::parse(args[:url]).path.split('/').last
20
77
 
21
78
  case args[:filename]
@@ -47,44 +104,9 @@ module Vendorificator
47
104
  args[:basename] ||= $`
48
105
  args[:extname] ||= $&
49
106
 
50
- name = args[:basename] if no_url_given
51
-
52
- super(environment, name, args, &block)
53
- end
107
+ @name = args[:basename] if no_url_given
54
108
 
55
- def conjure!
56
- shell.say_status :download, url
57
- archive = Tempfile.new([basename, extname])
58
- archive.write( open(url).read )
59
- archive.close
60
- @conjured_checksum = Digest::SHA256.file(archive.path).hexdigest
61
- raise RuntimeError, "Checksum error" if checksum && checksum!=conjured_checksum
62
- shell.say_status :unpack, filename
63
- system "#{unpack} #{Escape.shell_single_word archive.path}"
64
- if Dir.entries('.').length == 3 && !args[:no_strip_root]
65
- root = (Dir.entries('.') - %w(.. .)).first
66
- root_entries = Dir.entries(root) - %w(.. .)
67
- while root_entries.include?(root)
68
- FileUtils::mv root, root+"~"
69
- root << "~"
70
- end
71
- FileUtils::mv root_entries.map { |e| File.join(root, e) }, '.'
72
- FileUtils::rmdir root
73
- end
74
- super
75
- ensure
76
- archive.close
77
- archive.unlink
78
- end
79
-
80
- def upstream_version
81
- filename
82
- end
83
-
84
- def conjure_commit_message
85
- rv = "Conjured archive #{name} from #{filename}\nOrigin: #{url}\nChecksum: #{conjured_checksum}\n"
86
- rv << "Version: #{version}\n" if version
87
- rv
109
+ super args
88
110
  end
89
111
  end
90
112
 
@@ -8,16 +8,7 @@ require 'vendorificator/vendor'
8
8
  module Vendorificator
9
9
  class Vendor::Download < Vendor
10
10
  arg_reader :url
11
- attr_reader :conjured_checksum
12
-
13
- def initialize(environment, name, args={}, &block)
14
- no_url_given = !args[:url]
15
-
16
- args[:url] ||= name
17
- name = URI::parse(args[:url]).path.split('/').last if no_url_given
18
-
19
- super(environment, name, args, &block)
20
- end
11
+ attr_reader :conjured_checksum, :conjured_filesize
21
12
 
22
13
  def path
23
14
  args[:path] || category
@@ -29,6 +20,8 @@ module Vendorificator
29
20
  outf.write( open(url).read )
30
21
  end
31
22
  @conjured_checksum = Digest::SHA256.file(name).hexdigest
23
+ @conjured_filesize = File.size(name)
24
+ add_download_metadata
32
25
  end
33
26
 
34
27
  def upstream_version
@@ -40,6 +33,23 @@ module Vendorificator
40
33
  rv << "Version: #{args[:version]}" if args[:version]
41
34
  rv
42
35
  end
36
+
37
+ private
38
+
39
+ def parse_initialize_args(args = {})
40
+ unless args[:url]
41
+ args[:url] ||= @name
42
+ @name = URI::parse(args[:url]).path.split('/').last
43
+ end
44
+
45
+ args
46
+ end
47
+
48
+ def add_download_metadata
49
+ @metadata[:download_checksum] = conjured_checksum
50
+ @metadata[:download_filesize] = conjured_filesize
51
+ @metadata[:download_url] = url
52
+ end
43
53
  end
44
54
 
45
55
  class Config
@@ -6,19 +6,6 @@ module Vendorificator
6
6
  arg_reader :repository, :revision, :tag, :branch
7
7
  attr_reader :conjured_revision
8
8
 
9
- def initialize(environment, name, args={}, &block)
10
- args[:version] ||= args[:tag] if args[:tag]
11
- if [:revision, :tag, :branch].select { |key| args.key?(key) }.count > 1
12
- raise ArgumentError, "You can provide only one of: :revision, :tag, :branch"
13
- end
14
-
15
- unless args.include?(:repository)
16
- args[:repository] = name
17
- name = name.split('/').last.sub(/\.git$/, '')
18
- end
19
- super(environment, name, args, &block)
20
- end
21
-
22
9
  def conjure!
23
10
  shell.say_status :clone, repository
24
11
  MiniGit.git :clone, repository, '.'
@@ -33,6 +20,7 @@ module Vendorificator
33
20
  super
34
21
 
35
22
  @conjured_revision = local_git.capturing.rev_parse('HEAD').strip
23
+ add_git_metadata
36
24
  FileUtils::rm_rf '.git'
37
25
  end
38
26
 
@@ -48,6 +36,25 @@ module Vendorificator
48
36
  rv << "at revision #{conjured_revision}"
49
37
  rv
50
38
  end
39
+
40
+ private
41
+
42
+ def add_git_metadata
43
+ @metadata[:git_revision] = conjured_revision
44
+ end
45
+
46
+ def parse_initialize_args(args = {})
47
+ args[:version] ||= args[:tag] if args[:tag]
48
+ if [:revision, :tag, :branch].select { |key| args.key?(key) }.count > 1
49
+ raise ArgumentError, "You can provide only one of: :revision, :tag, :branch"
50
+ end
51
+
52
+ unless args.include?(:repository)
53
+ args[:repository] = @name
54
+ @name = @name.split('/').last.sub(/\.git$/, '')
55
+ end
56
+ super args
57
+ end
51
58
  end
52
59
 
53
60
  class Config
@@ -0,0 +1,60 @@
1
+ require 'fileutils'
2
+ require 'tempfile'
3
+
4
+ require 'vendorificator/vendor'
5
+
6
+ module Vendorificator
7
+ class Vendor::Tool < Vendor
8
+ arg_reader :specs, :command
9
+
10
+ def before_conjure!
11
+ upstream_version # to cache the version in instance attribute,
12
+ # it will be needed when we don't have the
13
+ # specs
14
+ end
15
+
16
+ def conjure!
17
+ specs.each do |spec|
18
+ src = File.join(environment.git.git_work_tree, spec)
19
+ if File.exist?(src)
20
+ FileUtils.install File.join(environment.git.git_work_tree, spec),
21
+ File.join(git.git_work_tree, spec),
22
+ verbose: true
23
+ end
24
+ Dir.chdir(git.git_work_tree) do
25
+ system self.command or raise RuntimeError, "Command failed"
26
+ end
27
+ end
28
+ end
29
+
30
+ def git_add_extra_paths
31
+ specs.inject(super) do |rv, path|
32
+ rv << path
33
+ end
34
+ end
35
+
36
+ def upstream_version
37
+ @upstream_version ||= git.capturing.
38
+ log({:n => 1, :pretty => 'format:%ad-%h', :date => 'short'}, *specs).
39
+ strip
40
+ end
41
+ end
42
+
43
+ class Config
44
+ register_module :tool, Vendor::Tool
45
+
46
+ def rubygems_bundler
47
+ tool 'rubygems',
48
+ :path => 'cache', # Hardcoded, meh
49
+ :specs => [ 'Gemfile', 'Gemfile.lock' ],
50
+ :command => 'bundle package --all'
51
+ end
52
+
53
+ def chef_berkshelf
54
+ tool 'cookbooks',
55
+ :path => 'cookbooks',
56
+ :specs => [ 'Berksfile', 'Berksfile.lock' ],
57
+ :command => 'berks install --path vendor/cookbooks'
58
+ end
59
+ end
60
+ end
@@ -1,7 +1,7 @@
1
1
  require 'fileutils'
2
-
2
+ require 'tmpdir'
3
3
  require 'thor/shell/basic'
4
-
4
+ require 'yaml'
5
5
  require 'vendorificator/config'
6
6
 
7
7
  module Vendorificator
@@ -22,20 +22,16 @@ module Vendorificator
22
22
  attr_reader :environment, :name, :args, :block
23
23
  arg_reader :version
24
24
 
25
- def initialize(environment, name, args={}, &block)
25
+ def initialize(environment, name, args = {}, &block)
26
26
  @environment = environment
27
- @category = args.delete(:category) if args.key?(:category)
28
-
29
- unless (hooks = Array(args.delete(:hooks))).empty?
30
- hooks.each do |hook|
31
- hook_module = hook.is_a?(Module) ? hook : ::Vendorificator::Hooks.const_get(hook)
32
- klass = class << self; self; end;
33
- klass.send :include, hook_module
34
- end
35
- end
36
27
  @name = name
37
- @args = args
38
28
  @block = block
29
+ @metadata = {
30
+ :module_name => @name,
31
+ :unparsed_args => args.clone
32
+ }
33
+ @metadata[:parsed_args] = @args = parse_initialize_args(args)
34
+ @metadata[:module_annotations] = @args[:annotate] if @args[:annotate]
39
35
 
40
36
  @environment.vendor_instances << self
41
37
  end
@@ -73,7 +69,7 @@ module Vendorificator
73
69
  end
74
70
 
75
71
  def work_dir
76
- _join(config[:root_dir], work_subdir)
72
+ _join(git.git_work_tree, environment.relative_root_dir, work_subdir)
77
73
  end
78
74
 
79
75
  def head
@@ -82,6 +78,10 @@ module Vendorificator
82
78
  nil
83
79
  end
84
80
 
81
+ def tag_name
82
+ _join(tag_name_base, version)
83
+ end
84
+
85
85
  def merged
86
86
  unless @_has_merged
87
87
  if ( head = self.head )
@@ -91,6 +91,9 @@ module Vendorificator
91
91
  @_has_merged = true
92
92
  end
93
93
  @merged
94
+ rescue MiniGit::GitError
95
+ @_has_merged = true
96
+ @merged = nil
94
97
  end
95
98
 
96
99
  def merged_tag
@@ -111,6 +114,13 @@ module Vendorificator
111
114
  merged_tag && merged_tag[(1+tag_name_base.length)..-1]
112
115
  end
113
116
 
117
+ # Public: Get git vendor notes of the merged commit.
118
+ #
119
+ # Returns the Hash of git vendor notes.
120
+ def merged_notes
121
+ Commit.new(merged, git).notes?
122
+ end
123
+
114
124
  def version
115
125
  @args[:version] || (!config[:use_upstream_version] && merged_version) || upstream_version
116
126
  end
@@ -151,48 +161,33 @@ module Vendorificator
151
161
  end
152
162
 
153
163
  def in_branch(options={}, &block)
154
- orig_branch = environment.current_branch
155
- stash_message = "vendorificator-#{git.capturing.rev_parse('HEAD').strip}-#{branch_name}-#{Time.now.to_i}"
164
+ branch_exists = !!self.head
165
+ Dir.mktmpdir("vendor-#{category}-#{name}") do |tmpdir|
166
+ clone_opts = {:shared => true, :no_checkout => true}
167
+ clone_opts[:branch] = branch_name if branch_exists
168
+ MiniGit.git(:clone, clone_opts, git.git_dir, tmpdir)
169
+ tmpgit = MiniGit::new(tmpdir)
170
+ tmpgit.checkout({orphan: true}, branch_name) unless branch_exists
171
+ tmpgit.rm( { :r => true, :f => true, :q => true, :ignore_unmatch => true }, '.') if options[:clean] || !branch_exists
156
172
 
157
- # We want to be in repository's root now, as we may need to
158
- # remove stuff and don't want to have removed directory as cwd.
159
- Dir::chdir git.git_work_tree do
160
173
  begin
161
- # Stash all local changes
162
- git.stash :save, {:all => true, :quiet => true}, stash_message
163
-
164
- # If our branch exists, check it out; otherwise, create a new
165
- # orphaned branch.
166
- if self.head
167
- git.checkout branch_name
168
- git.rm( { :r => true, :f => true, :q => true, :ignore_unmatch => true }, '.') if options[:clean]
169
- else
170
- git.checkout( { :orphan => true }, branch_name )
171
- git.rm( { :r => true, :f => true, :q => true, :ignore_unmatch => true }, '.')
174
+ @git = tmpgit
175
+ Dir.chdir(tmpdir) do
176
+ yield
172
177
  end
173
-
174
- yield
175
178
  ensure
176
- # We should try to ensure we're back on original branch and
177
- # local changes have been applied
178
- begin
179
- git.checkout orig_branch
180
- stash = git.capturing.
181
- stash(:list, {:grep => stash_message, :fixed_strings => true}).lines.map(&:strip)
182
- if stash.length > 1
183
- shell.say_status 'WARNING', "more than one stash matches #{stash_message}, it's weird", :yellow
184
- stash.each { |ln| shell.say_status '-', ln, :yellow }
185
- end
186
- git.stash :pop, {:quiet => true}, stash.first.sub(/:.*/, '') unless stash.empty?
187
- rescue => e
188
- shell.say_status 'ERROR', "Cannot revert branch from #{self.head} back to #{orig_branch}: #{e}", :red
189
- raise
190
- end
179
+ @git = nil
191
180
  end
181
+
182
+ git.fetch(tmpdir)
183
+ git.fetch({tags: true}, tmpdir)
184
+ git.fetch(tmpdir,
185
+ "+refs/heads/#{branch_name}:refs/heads/#{branch_name}",
186
+ "+refs/notes/vendor:refs/notes/vendor")
192
187
  end
193
188
  end
194
189
 
195
- def run!
190
+ def run!(options = {})
196
191
  case status
197
192
 
198
193
  when :up_to_date
@@ -201,12 +196,14 @@ module Vendorificator
201
196
  when :unpulled, :unmerged
202
197
  shell.say_status 'merging', self.to_s, :yellow
203
198
  git.merge({:no_edit => true, :no_ff => true}, tagged_sha1)
199
+ postprocess! if self.respond_to? :postprocess!
204
200
  compute_dependencies!
205
201
 
206
202
  when :outdated, :new
207
203
  shell.say_status 'fetching', self.to_s, :yellow
208
204
  begin
209
205
  shell.padding += 1
206
+ before_conjure!
210
207
  in_branch(:clean => true) do
211
208
  FileUtils::mkdir_p work_dir
212
209
 
@@ -223,15 +220,11 @@ module Vendorificator
223
220
  make_subdir_root subdir if subdir && !subdir.empty?
224
221
  end
225
222
 
226
-
227
- # Commit and tag the conjured module
228
- git.add work_dir
229
- git.commit :m => conjure_commit_message
230
- git.tag( { :a => true, :m => tag_message }, tag_name )
231
- shell.say_status :tag, tag_name
223
+ commit_and_annotate(options[:metadata])
232
224
  end
233
225
  # Merge back to the original branch
234
226
  git.merge( {:no_edit => true, :no_ff => true}, branch_name )
227
+ postprocess! if self.respond_to? :postprocess!
235
228
  compute_dependencies!
236
229
  ensure
237
230
  shell.padding -= 1
@@ -242,35 +235,57 @@ module Vendorificator
242
235
  end
243
236
  end
244
237
 
245
- def tag_name_base
246
- _join('vendor', category, name)
238
+ def conjure!
239
+ block.call(self) if block
247
240
  end
248
241
 
249
- def tag_name
250
- _join(tag_name_base, version)
251
- end
242
+ #
243
+ # Hook points
244
+ def git_add_extra_paths ; [] ; end
245
+ def before_conjure! ; end
246
+ def compute_dependencies! ; end
252
247
 
253
- def conjure_commit_message
254
- "Conjured vendor module #{name} version #{version}"
248
+ def pushable_refs
249
+ created_tags.
250
+ map { |tag| '+' << tag }.
251
+ unshift("+refs/heads/#{branch_name}")
255
252
  end
256
253
 
257
- def tag_message
258
- conjure_commit_message
254
+ def metadata
255
+ default = {
256
+ :module_version => version,
257
+ :module_category => @category,
258
+ }
259
+ default.merge @metadata
259
260
  end
260
261
 
261
- def conjure!
262
- block.call(self) if block
262
+ private
263
+
264
+ def parse_initialize_args(args = {})
265
+ @category = args.delete(:category) if args.key?(:category)
266
+
267
+ unless (hooks = Array(args.delete(:hooks))).empty?
268
+ hooks.each do |hook|
269
+ hook_module = hook.is_a?(Module) ? hook : ::Vendorificator::Hooks.const_get(hook)
270
+ klass = class << self; self; end;
271
+ klass.send :include, hook_module
272
+ end
273
+ end
274
+
275
+ args
263
276
  end
264
277
 
265
- def compute_dependencies! ; end
278
+ def tag_name_base
279
+ _join('vendor', category, name)
280
+ end
266
281
 
267
- def pushable_refs
268
- branch = "+refs/heads/#{branch_name}"
269
- tags = created_tags.map{ |tag| '+' + tag }
270
- [branch, tags].flatten
282
+ def conjure_commit_message
283
+ "Conjured vendor module #{name} version #{version}"
271
284
  end
272
285
 
273
- private
286
+ def tag_message
287
+ conjure_commit_message
288
+ end
274
289
 
275
290
  def tagged_sha1
276
291
  @tagged_sha1 ||= git.capturing.rev_parse({:verify => true, :quiet => true}, "refs/tags/#{tag_name}^{commit}").strip
@@ -279,12 +294,12 @@ module Vendorificator
279
294
  end
280
295
 
281
296
  def created_tags
282
- git.capturing.show_ref.split("\n").map{ |line| line.split(' ')[1] }.
283
- select{ |ref| ref =~ /\Arefs\/tags\/#{tag_name_base}/ }
297
+ git.capturing.show_ref.lines.map{ |line| line.split(' ')[1] }.
298
+ select{ |ref| ref =~ /\Arefs\/tags\/#{tag_name_base}\// }
284
299
  end
285
300
 
286
301
  def git
287
- environment.git
302
+ @git || environment.git
288
303
  end
289
304
 
290
305
  def config
@@ -309,6 +324,30 @@ module Vendorificator
309
324
  Dir.chdir(curdir.to_s) if curdir.exist?
310
325
  end
311
326
 
327
+ # Private: Commits and annotates the conjured module.
328
+ #
329
+ # environment_metadata - Hash with environment metadata where vendor was run
330
+ #
331
+ # Returns nothing.
332
+ def commit_and_annotate(environment_metadata = {})
333
+ git.add work_dir, *git_add_extra_paths
334
+ git.commit :m => conjure_commit_message
335
+ git.notes({:ref => 'vendor'}, 'add', {:m => conjure_note(environment_metadata)}, 'HEAD')
336
+ git.tag( { :a => true, :m => tag_message }, tag_name )
337
+ shell.say_status :tag, tag_name
338
+ end
339
+
340
+ # Private: Merges all the data we use for the commit note.
341
+ #
342
+ # environment_metadata - Hash with environment metadata where vendor was run
343
+ #
344
+ # Returns: The note in the YAML format.
345
+ def conjure_note(environment_metadata = {})
346
+ config.metadata.
347
+ merge(environment_metadata).
348
+ merge(metadata).
349
+ to_yaml
350
+ end
312
351
  end
313
352
 
314
353
  Config.register_module :vendor, Vendor