vendorificator 0.5.git.v0.4.0.63.g8e9d54d → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +9 -9
- data/.travis.yml +2 -2
- data/CHANGELOG.md +10 -0
- data/Gemfile +5 -12
- data/README.md +27 -1
- data/Rakefile +2 -8
- data/features/chef_cookbook.feature +4 -4
- data/features/download.feature +1 -1
- data/features/edgecases.feature +15 -0
- data/features/environment.feature +3 -2
- data/features/fake_mode.feature +15 -0
- data/features/git.feature +4 -4
- data/features/overlay.feature +99 -0
- data/features/step_definitions/basic.rb +22 -0
- data/features/step_definitions/git.rb +16 -0
- data/features/step_definitions/vendorificator.rb +9 -4
- data/features/support/aruba_ext.rb +4 -0
- data/features/support/env.rb +3 -0
- data/features/tarball.feature +2 -2
- data/features/tarball_edit.feature +3 -3
- data/features/tool.feature +6 -4
- data/features/tool_shortcuts.feature +3 -3
- data/features/tool_specs.feature +62 -0
- data/features/vendor.feature +4 -3
- data/lib/vendorificator.rb +7 -1
- data/lib/vendorificator/cli.rb +12 -11
- data/lib/vendorificator/config.rb +32 -1
- data/lib/vendorificator/environment.rb +23 -27
- data/lib/vendorificator/hooks/chef_cookbook.rb +2 -2
- data/lib/vendorificator/overlay.rb +17 -0
- data/lib/vendorificator/segment.rb +376 -0
- data/lib/vendorificator/segment/overlay.rb +114 -0
- data/lib/vendorificator/segment/vendor.rb +115 -0
- data/lib/vendorificator/vendor.rb +25 -279
- data/lib/vendorificator/vendor/tool.rb +40 -23
- data/lib/vendorificator/version.rb +1 -1
- data/spec/vendorificator/config_spec.rb +66 -0
- data/spec/vendorificator/environment_spec.rb +7 -7
- data/spec/vendorificator/fixtures/vendorfiles/overlay.rb +4 -0
- data/spec/vendorificator/segment/vendor_spec.rb +19 -0
- data/spec/vendorificator/segment_spec.rb +106 -0
- data/spec/vendorificator/vendor_spec.rb +0 -89
- data/vendorificator.gemspec +5 -5
- metadata +45 -29
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'tmpdir'
|
2
|
+
|
3
|
+
module Vendorificator
|
4
|
+
class Segment::Vendor < Segment
|
5
|
+
attr_reader :overlay, :vendor
|
6
|
+
|
7
|
+
def initialize(options)
|
8
|
+
@vendor = options.delete(:vendor)
|
9
|
+
@overlay = options.delete(:overlay)
|
10
|
+
super
|
11
|
+
end
|
12
|
+
|
13
|
+
def name
|
14
|
+
@vendor.name
|
15
|
+
end
|
16
|
+
|
17
|
+
def group
|
18
|
+
@vendor.group
|
19
|
+
end
|
20
|
+
|
21
|
+
def version
|
22
|
+
@vendor.version
|
23
|
+
end
|
24
|
+
|
25
|
+
def branch_name
|
26
|
+
if overlay
|
27
|
+
_join overlay.branch_name, group, name
|
28
|
+
else
|
29
|
+
super
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def compute_dependencies!
|
34
|
+
@vendor.compute_dependencies!
|
35
|
+
end
|
36
|
+
|
37
|
+
# Public: Conjures the vendor module without merging back.
|
38
|
+
#
|
39
|
+
# options - available options: :metadata - Hash with metadata information
|
40
|
+
#
|
41
|
+
# Returns nothing.
|
42
|
+
def conjure(options = {})
|
43
|
+
shell.padding += 1
|
44
|
+
@vendor.before_conjure!
|
45
|
+
Dir.mktmpdir "vendorificator-#{name}" do |tmpdir|
|
46
|
+
in_branch(branch_name, clean: true) do |tmpgit|
|
47
|
+
begin
|
48
|
+
@git = tmpgit
|
49
|
+
@vendor.git = tmpgit
|
50
|
+
|
51
|
+
Dir.chdir tmpdir do
|
52
|
+
@vendor.conjure!
|
53
|
+
|
54
|
+
subdir = @vendor.args[:subdirectory]
|
55
|
+
make_subdir_root subdir if subdir && !subdir.empty?
|
56
|
+
end
|
57
|
+
|
58
|
+
FileUtils.mkdir_p work_dir
|
59
|
+
tmpdir_entries = (Dir.entries(tmpdir) - %w'. ..').
|
60
|
+
map { |e| File.join(tmpdir, e) }
|
61
|
+
FileUtils.mv tmpdir_entries, work_dir
|
62
|
+
commit_and_annotate(options[:metadata] || {})
|
63
|
+
ensure
|
64
|
+
@git = nil
|
65
|
+
@vendor.git = nil
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
ensure
|
70
|
+
shell.padding -= 1
|
71
|
+
end
|
72
|
+
|
73
|
+
# Public: Merges back to the original branch (usually master).
|
74
|
+
#
|
75
|
+
# commit - git ref/branch to merge, defaults to segment branch
|
76
|
+
#
|
77
|
+
# Returns nothing.
|
78
|
+
def merge_back(commit = branch_name)
|
79
|
+
git.capturing.merge({no_edit: true, no_ff: true}, commit) unless config.fake_mode?
|
80
|
+
@vendor.postprocess! if @vendor.respond_to? :postprocess!
|
81
|
+
@vendor.compute_dependencies!
|
82
|
+
end
|
83
|
+
|
84
|
+
private
|
85
|
+
|
86
|
+
def update(options = {})
|
87
|
+
shell.padding += 1
|
88
|
+
conjure options
|
89
|
+
merge_back
|
90
|
+
ensure
|
91
|
+
shell.padding -= 1
|
92
|
+
end
|
93
|
+
|
94
|
+
def environment
|
95
|
+
@vendor.environment
|
96
|
+
end
|
97
|
+
|
98
|
+
def path
|
99
|
+
if overlay
|
100
|
+
_join overlay.path, group, name
|
101
|
+
else
|
102
|
+
@vendor.args[:path] || _join(group, name)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def work_subdir
|
107
|
+
if overlay
|
108
|
+
_join overlay.path
|
109
|
+
else
|
110
|
+
_join config[:basedir], path
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
@@ -19,7 +19,8 @@ module Vendorificator
|
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
22
|
-
attr_reader :environment, :name, :args, :block
|
22
|
+
attr_reader :environment, :name, :args, :block, :segment
|
23
|
+
attr_accessor :git
|
23
24
|
arg_reader :version
|
24
25
|
|
25
26
|
def initialize(environment, name, args = {}, &block)
|
@@ -27,231 +28,35 @@ module Vendorificator
|
|
27
28
|
@name = name
|
28
29
|
@block = block
|
29
30
|
@metadata = {
|
30
|
-
:module_name => @name,
|
31
31
|
:unparsed_args => args.clone
|
32
32
|
}
|
33
33
|
@metadata[:parsed_args] = @args = parse_initialize_args(args)
|
34
34
|
@metadata[:module_annotations] = @args[:annotate] if @args[:annotate]
|
35
35
|
|
36
|
-
@
|
36
|
+
@segment = Segment::Vendor.new(vendor: self, overlay: config.overlay_instance)
|
37
|
+
if config.overlay_instance
|
38
|
+
config.overlay_instance.segments << @segment
|
39
|
+
else
|
40
|
+
@environment.segments << @segment
|
41
|
+
end
|
37
42
|
end
|
38
43
|
|
39
44
|
def ===(other)
|
40
|
-
other ===
|
41
|
-
end
|
42
|
-
|
43
|
-
def path
|
44
|
-
args[:path] || _join(group, name)
|
45
|
-
end
|
46
|
-
|
47
|
-
def shell
|
48
|
-
@environment.shell
|
49
|
-
end
|
50
|
-
|
51
|
-
def say(verb_level= :default, &block)
|
52
|
-
output = yield
|
53
|
-
@environment.say verb_level, output
|
54
|
-
end
|
55
|
-
|
56
|
-
def say_status(*args, &block)
|
57
|
-
@environment.say_status(*args, &block)
|
45
|
+
other === name || File.expand_path(other.to_s) == work_dir
|
58
46
|
end
|
59
47
|
|
60
48
|
def group
|
61
49
|
defined?(@group) ? @group : self.class.group
|
62
50
|
end
|
63
51
|
|
64
|
-
def branch_name
|
65
|
-
_join(config[:branch_prefix], group, name)
|
66
|
-
end
|
67
|
-
|
68
|
-
def to_s
|
69
|
-
_join(name, version)
|
70
|
-
end
|
71
|
-
|
72
52
|
def inspect
|
73
53
|
"#<#{self.class} #{self}>"
|
74
54
|
end
|
75
55
|
|
76
|
-
def work_subdir
|
77
|
-
_join(config[:basedir], path)
|
78
|
-
end
|
79
|
-
|
80
|
-
def work_dir
|
81
|
-
_join(git.git_work_tree, environment.relative_root_dir, work_subdir)
|
82
|
-
end
|
83
|
-
|
84
|
-
def head
|
85
|
-
git.capturing.rev_parse({:verify => true, :quiet => true}, "refs/heads/#{branch_name}").strip
|
86
|
-
rescue MiniGit::GitError
|
87
|
-
nil
|
88
|
-
end
|
89
|
-
|
90
|
-
def tag_name
|
91
|
-
_join(tag_name_base, version)
|
92
|
-
end
|
93
|
-
|
94
|
-
def merged
|
95
|
-
unless @_has_merged
|
96
|
-
if ( head = self.head )
|
97
|
-
merged = git.capturing.merge_base(head, 'HEAD').strip
|
98
|
-
@merged = merged unless merged.empty?
|
99
|
-
end
|
100
|
-
@_has_merged = true
|
101
|
-
end
|
102
|
-
@merged
|
103
|
-
rescue MiniGit::GitError
|
104
|
-
@_has_merged = true
|
105
|
-
@merged = nil
|
106
|
-
end
|
107
|
-
|
108
|
-
def merged_tag
|
109
|
-
unless @_has_merged_tag
|
110
|
-
if merged
|
111
|
-
tag = git.capturing.describe( {
|
112
|
-
:exact_match => true,
|
113
|
-
:match => _join(tag_name_base, '*') },
|
114
|
-
merged).strip
|
115
|
-
@merged_tag = tag unless tag.empty?
|
116
|
-
end
|
117
|
-
@_has_merged_tag = true
|
118
|
-
end
|
119
|
-
@merged_tag
|
120
|
-
end
|
121
|
-
|
122
|
-
def merged_version
|
123
|
-
merged_tag && merged_tag[(1+tag_name_base.length)..-1]
|
124
|
-
end
|
125
|
-
|
126
|
-
# Public: Get git vendor notes of the merged commit.
|
127
|
-
#
|
128
|
-
# Returns the Hash of git vendor notes.
|
129
|
-
def merged_notes
|
130
|
-
Commit.new(merged, git).notes?
|
131
|
-
end
|
132
|
-
|
133
56
|
def version
|
134
|
-
@args[:version] ||
|
135
|
-
|
136
|
-
|
137
|
-
def upstream_version
|
138
|
-
# To be overriden
|
139
|
-
end
|
140
|
-
|
141
|
-
def updatable?
|
142
|
-
return nil if self.status == :up_to_date
|
143
|
-
return false if !head
|
144
|
-
return false if head && merged == head
|
145
|
-
git.describe({:abbrev => 0, :always => true}, branch_name)
|
146
|
-
end
|
147
|
-
|
148
|
-
def status
|
149
|
-
# If there's no branch yet, it's a completely new module
|
150
|
-
return :new unless head
|
151
|
-
|
152
|
-
# If there's a branch but no tag, it's a known module that's not
|
153
|
-
# been updated for the new definition yet.
|
154
|
-
return :outdated unless tagged_sha1
|
155
|
-
|
156
|
-
# Well, this is awkward: branch is in config and exists, but is
|
157
|
-
# not merged into current branch at all.
|
158
|
-
return :unmerged unless merged
|
159
|
-
|
160
|
-
# Merge base is tagged with our tag. We're good.
|
161
|
-
return :up_to_date if tagged_sha1 == merged
|
162
|
-
|
163
|
-
return :unpulled if environment.fast_forwardable?(tagged_sha1, merged)
|
164
|
-
|
165
|
-
return :unknown
|
166
|
-
end
|
167
|
-
|
168
|
-
def needed?
|
169
|
-
return self.status != :up_to_date
|
170
|
-
end
|
171
|
-
|
172
|
-
def in_branch(options={}, &block)
|
173
|
-
branch_exists = !!self.head
|
174
|
-
notes_exist = begin
|
175
|
-
git.capturing.rev_parse({verify: true, quiet: true}, 'refs/notes/vendor')
|
176
|
-
rescue MiniGit::GitError
|
177
|
-
nil
|
178
|
-
end
|
179
|
-
Dir.mktmpdir("vendor-#{group}-#{name}") do |tmpdir|
|
180
|
-
clone_opts = {:shared => true, :no_checkout => true}
|
181
|
-
clone_opts[:branch] = branch_name if branch_exists
|
182
|
-
say { MiniGit::Capturing.git(:clone, clone_opts, git.git_dir, tmpdir) }
|
183
|
-
tmpgit = MiniGit.new(tmpdir)
|
184
|
-
#TODO: Silence/handle the stderr output from git-checkout
|
185
|
-
tmpgit.capturing.checkout({orphan: true}, branch_name) unless branch_exists
|
186
|
-
tmpgit.fetch(git.git_dir, "refs/notes/vendor:refs/notes/vendor") if notes_exist
|
187
|
-
if options[:clean] || !branch_exists
|
188
|
-
tmpgit.rm({ :r => true, :f => true, :q => true, :ignore_unmatch => true }, '.')
|
189
|
-
end
|
190
|
-
|
191
|
-
begin
|
192
|
-
@git = tmpgit
|
193
|
-
Dir.chdir(tmpdir) do
|
194
|
-
yield
|
195
|
-
end
|
196
|
-
ensure
|
197
|
-
@git = nil
|
198
|
-
end
|
199
|
-
|
200
|
-
#TODO: Silence/handle the stderr output from git-fetch
|
201
|
-
git.fetch(tmpdir)
|
202
|
-
git.fetch({tags: true}, tmpdir)
|
203
|
-
git.fetch(tmpdir,
|
204
|
-
"refs/heads/#{branch_name}:refs/heads/#{branch_name}",
|
205
|
-
"refs/notes/vendor:refs/notes/vendor")
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
def run!(options = {})
|
210
|
-
case status
|
211
|
-
|
212
|
-
when :up_to_date
|
213
|
-
say_status :default, 'up to date', self.to_s
|
214
|
-
|
215
|
-
when :unpulled, :unmerged
|
216
|
-
say_status :default, 'merging', self.to_s, :yellow
|
217
|
-
git.merge({:no_edit => true, :no_ff => true}, tagged_sha1)
|
218
|
-
postprocess! if self.respond_to? :postprocess!
|
219
|
-
compute_dependencies!
|
220
|
-
|
221
|
-
when :outdated, :new
|
222
|
-
say_status :default, 'fetching', self.to_s, :yellow
|
223
|
-
begin
|
224
|
-
shell.padding += 1
|
225
|
-
before_conjure!
|
226
|
-
in_branch(:clean => true) do
|
227
|
-
FileUtils::mkdir_p work_dir
|
228
|
-
|
229
|
-
# Actually fill the directory with the wanted content
|
230
|
-
Dir::chdir work_dir do
|
231
|
-
begin
|
232
|
-
shell.padding += 1
|
233
|
-
self.conjure!
|
234
|
-
ensure
|
235
|
-
shell.padding -= 1
|
236
|
-
end
|
237
|
-
|
238
|
-
subdir = args[:subdirectory]
|
239
|
-
make_subdir_root subdir if subdir && !subdir.empty?
|
240
|
-
end
|
241
|
-
|
242
|
-
commit_and_annotate(options[:metadata])
|
243
|
-
end
|
244
|
-
# Merge back to the original branch
|
245
|
-
git.capturing.merge( {:no_edit => true, :no_ff => true}, branch_name )
|
246
|
-
postprocess! if self.respond_to? :postprocess!
|
247
|
-
compute_dependencies!
|
248
|
-
ensure
|
249
|
-
shell.padding -= 1
|
250
|
-
end
|
251
|
-
|
252
|
-
else
|
253
|
-
say_status :quiet, self.status, "I'm unsure what to do.", :red
|
254
|
-
end
|
57
|
+
@args[:version] ||
|
58
|
+
(!config[:use_upstream_version] && segment.merged_version) ||
|
59
|
+
upstream_version
|
255
60
|
end
|
256
61
|
|
257
62
|
def conjure!
|
@@ -262,27 +67,19 @@ module Vendorificator
|
|
262
67
|
def git_add_extra_paths ; [] ; end
|
263
68
|
def before_conjure! ; end
|
264
69
|
def compute_dependencies! ; end
|
265
|
-
|
266
|
-
def pushable_refs
|
267
|
-
created_tags.unshift("refs/heads/#{branch_name}")
|
268
|
-
end
|
70
|
+
def upstream_version ; end
|
269
71
|
|
270
72
|
def metadata
|
271
73
|
default = {
|
74
|
+
:module_name => @name,
|
272
75
|
:module_version => version,
|
273
76
|
:module_group => @group,
|
274
77
|
}
|
275
78
|
default.merge @metadata
|
276
79
|
end
|
277
80
|
|
278
|
-
def
|
279
|
-
|
280
|
-
|
281
|
-
module_list.include?(name) ||
|
282
|
-
module_list.include?("#{group}/#{name}") ||
|
283
|
-
modpaths.include?(File.expand_path(work_dir)) ||
|
284
|
-
module_list.include?(merged) ||
|
285
|
-
module_list.include?(branch_name)
|
81
|
+
def conjure_commit_message
|
82
|
+
"Conjured vendor module #{name} version #{version}"
|
286
83
|
end
|
287
84
|
|
288
85
|
private
|
@@ -305,31 +102,6 @@ module Vendorificator
|
|
305
102
|
args
|
306
103
|
end
|
307
104
|
|
308
|
-
def tag_name_base
|
309
|
-
_join('vendor', group, name)
|
310
|
-
end
|
311
|
-
|
312
|
-
def conjure_commit_message
|
313
|
-
"Conjured vendor module #{name} version #{version}"
|
314
|
-
end
|
315
|
-
|
316
|
-
def tag_message
|
317
|
-
conjure_commit_message
|
318
|
-
end
|
319
|
-
|
320
|
-
def tagged_sha1
|
321
|
-
@tagged_sha1 ||= git.capturing.rev_parse(
|
322
|
-
{:verify => true, :quiet => true}, "refs/tags/#{tag_name}^{commit}"
|
323
|
-
).strip
|
324
|
-
rescue MiniGit::GitError
|
325
|
-
nil
|
326
|
-
end
|
327
|
-
|
328
|
-
def created_tags
|
329
|
-
git.capturing.show_ref.lines.map{ |line| line.split(' ')[1] }.
|
330
|
-
select{ |ref| ref =~ /\Arefs\/tags\/#{tag_name_base}\// }
|
331
|
-
end
|
332
|
-
|
333
105
|
def git
|
334
106
|
@git || environment.git
|
335
107
|
end
|
@@ -338,47 +110,21 @@ module Vendorificator
|
|
338
110
|
environment.config
|
339
111
|
end
|
340
112
|
|
341
|
-
def
|
342
|
-
|
113
|
+
def work_dir
|
114
|
+
segment.work_dir
|
343
115
|
end
|
344
116
|
|
345
|
-
def
|
346
|
-
|
347
|
-
tmpdir = Pathname.pwd.dirname.join("#{Pathname.pwd.basename}.tmp")
|
348
|
-
subdir = Pathname.pwd.join(subdir_path)
|
349
|
-
|
350
|
-
Dir.chdir('..')
|
351
|
-
|
352
|
-
subdir.rename(tmpdir.to_s)
|
353
|
-
curdir.rmtree
|
354
|
-
tmpdir.rename(curdir.to_s)
|
355
|
-
ensure
|
356
|
-
Dir.chdir(curdir.to_s) if curdir.exist?
|
117
|
+
def shell
|
118
|
+
environment.shell
|
357
119
|
end
|
358
120
|
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
#
|
363
|
-
# Returns nothing.
|
364
|
-
def commit_and_annotate(environment_metadata = {})
|
365
|
-
git.capturing.add work_dir, *git_add_extra_paths
|
366
|
-
git.capturing.commit :m => conjure_commit_message
|
367
|
-
git.capturing.notes({:ref => 'vendor'}, 'add', {:m => conjure_note(environment_metadata)}, 'HEAD')
|
368
|
-
git.capturing.tag( { :a => true, :m => tag_message }, tag_name )
|
369
|
-
say_status :default, :tag, tag_name
|
121
|
+
def say(verb_level= :default, &block)
|
122
|
+
output = yield
|
123
|
+
environment.say verb_level, output
|
370
124
|
end
|
371
125
|
|
372
|
-
|
373
|
-
|
374
|
-
# environment_metadata - Hash with environment metadata where vendor was run
|
375
|
-
#
|
376
|
-
# Returns: The note in the YAML format.
|
377
|
-
def conjure_note(environment_metadata = {})
|
378
|
-
config.metadata.
|
379
|
-
merge(environment_metadata).
|
380
|
-
merge(metadata).
|
381
|
-
to_yaml
|
126
|
+
def say_status(*args, &block)
|
127
|
+
environment.say_status(*args, &block)
|
382
128
|
end
|
383
129
|
end
|
384
130
|
|