vendorificator 0.5.git.v0.4.0.63.g8e9d54d → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +9 -9
  2. data/.travis.yml +2 -2
  3. data/CHANGELOG.md +10 -0
  4. data/Gemfile +5 -12
  5. data/README.md +27 -1
  6. data/Rakefile +2 -8
  7. data/features/chef_cookbook.feature +4 -4
  8. data/features/download.feature +1 -1
  9. data/features/edgecases.feature +15 -0
  10. data/features/environment.feature +3 -2
  11. data/features/fake_mode.feature +15 -0
  12. data/features/git.feature +4 -4
  13. data/features/overlay.feature +99 -0
  14. data/features/step_definitions/basic.rb +22 -0
  15. data/features/step_definitions/git.rb +16 -0
  16. data/features/step_definitions/vendorificator.rb +9 -4
  17. data/features/support/aruba_ext.rb +4 -0
  18. data/features/support/env.rb +3 -0
  19. data/features/tarball.feature +2 -2
  20. data/features/tarball_edit.feature +3 -3
  21. data/features/tool.feature +6 -4
  22. data/features/tool_shortcuts.feature +3 -3
  23. data/features/tool_specs.feature +62 -0
  24. data/features/vendor.feature +4 -3
  25. data/lib/vendorificator.rb +7 -1
  26. data/lib/vendorificator/cli.rb +12 -11
  27. data/lib/vendorificator/config.rb +32 -1
  28. data/lib/vendorificator/environment.rb +23 -27
  29. data/lib/vendorificator/hooks/chef_cookbook.rb +2 -2
  30. data/lib/vendorificator/overlay.rb +17 -0
  31. data/lib/vendorificator/segment.rb +376 -0
  32. data/lib/vendorificator/segment/overlay.rb +114 -0
  33. data/lib/vendorificator/segment/vendor.rb +115 -0
  34. data/lib/vendorificator/vendor.rb +25 -279
  35. data/lib/vendorificator/vendor/tool.rb +40 -23
  36. data/lib/vendorificator/version.rb +1 -1
  37. data/spec/vendorificator/config_spec.rb +66 -0
  38. data/spec/vendorificator/environment_spec.rb +7 -7
  39. data/spec/vendorificator/fixtures/vendorfiles/overlay.rb +4 -0
  40. data/spec/vendorificator/segment/vendor_spec.rb +19 -0
  41. data/spec/vendorificator/segment_spec.rb +106 -0
  42. data/spec/vendorificator/vendor_spec.rb +0 -89
  43. data/vendorificator.gemspec +5 -5
  44. metadata +45 -29
@@ -7,8 +7,11 @@ require 'wrong'
7
7
 
8
8
  require 'vendorificator/cli'
9
9
 
10
+ MiniGit.debug = true if ENV['CUCUMBER_DEBUG']
11
+
10
12
  ENV['GIT_AUTHOR_NAME'] = ENV['GIT_COMMITTER_NAME'] = 'Vendorificator Cucumber'
11
13
  ENV['GIT_AUTHOR_EMAIL'] = ENV['GIT_COMMITTER_EMAIL'] = 'nonexistent@example.com'
14
+ ENV['THOR_DEBUG'] = '1'
12
15
 
13
16
  World(Wrong)
14
17
 
@@ -62,5 +62,5 @@ Scenario: Tarball without a root directory
62
62
  """
63
63
  When I run vendor command "install"
64
64
  Then following has been conjured:
65
- | Name | testrepo |
66
- | With file | test/alias.c |
65
+ | Name | testrepo |
66
+ | With file | test/alias.c |
@@ -10,6 +10,6 @@ Scenario:
10
10
  """
11
11
  When I run vendor command "install"
12
12
  Then following has been conjured:
13
- | Name | testrepo |
14
- | With file | test/alias.c |
15
- | Without file | test/archive.c |
13
+ | Name | testrepo |
14
+ | With file | test/alias.c |
15
+ | Without file | test/archive.c |
@@ -23,7 +23,7 @@ Scenario: Use Gem bundler to download rubygems, and Vendorificator to vendor the
23
23
  When I run vendor command "install"
24
24
  Then following has been conjured:
25
25
  | Name | bundler |
26
- | Path | cache |
26
+ | Path | vendor/cache |
27
27
  | With file | hello-0.0.1.gem |
28
28
  | Without file | first-0.gem |
29
29
 
@@ -36,7 +36,7 @@ Scenario: Bundler correctly downloads and caches dependencies
36
36
  When I run vendor command "install"
37
37
  Then following has been conjured:
38
38
  | Name | bundler |
39
- | Path | cache |
39
+ | Path | vendor/cache |
40
40
  | Without file | hello-0.0.1.gem |
41
41
  | With file | first-0.gem |
42
42
  | With file | second-0.gem |
@@ -50,7 +50,7 @@ Scenario: directory contents are completely replaced on re-vendoring
50
50
  When I run vendor command "install"
51
51
  Then following has been conjured:
52
52
  | Name | bundler |
53
- | Path | cache |
53
+ | Path | vendor/cache |
54
54
  | With file | hello-0.0.1.gem |
55
55
  | Without file | first-0.gem |
56
56
  When I change Gemfile to:
@@ -58,10 +58,12 @@ Scenario: directory contents are completely replaced on re-vendoring
58
58
  source "file://#{ENV['FIXTURES_DIR']}/rubygems"
59
59
  gem "first"
60
60
  """
61
+ And I run `git commit -a -m bump`
61
62
  And I run vendor command "install"
62
63
  Then following has been conjured:
63
64
  | Name | bundler |
64
- | Path | cache |
65
+ | Path | vendor/cache |
65
66
  | Without file | hello-0.0.1.gem |
66
67
  | With file | first-0.gem |
67
68
  | With file | second-0.gem |
69
+
@@ -17,7 +17,7 @@ Scenario: rubygems_bundler
17
17
  When I run vendor command "install"
18
18
  Then following has been conjured:
19
19
  | Name | rubygems |
20
- | Path | cache |
20
+ | Path | vendor/cache |
21
21
  | With file | hello-0.0.1.gem |
22
22
  | Without file | first-0.gem |
23
23
 
@@ -38,14 +38,14 @@ Scenario: chef_berkshelf
38
38
  When I run vendor command "install"
39
39
  Then following has been conjured:
40
40
  | Name | cookbooks |
41
- | With file | build-essential/metadata.rb |
41
+ | With file | build-essential/metadata.rb |
42
42
 
43
43
  @berkshelf
44
44
  Scenario: postprocessing tool
45
45
  Given a repository with following Vendorfile:
46
46
  """ruby
47
47
  chef_berkshelf do
48
- FileUtils::rm_rf 'runit'
48
+ FileUtils::rm_rf 'vendor/cookbooks/runit'
49
49
  end
50
50
  """
51
51
  And a file named "Berksfile" with:
@@ -0,0 +1,62 @@
1
+ Feature: tool's specs can be specified in a flexible way
2
+
3
+ Scenario Outline:
4
+ Given a repository with following Vendorfile:
5
+ """ruby
6
+ tool 'find', :specs => <specs>,
7
+ :command => "mkdir -p vendor/find ; find . -type f -not -name found -a -not -path './.git/*' > vendor/find/found"
8
+ """
9
+ Given an empty file named "<file1>"
10
+ Given an empty file named "<file2>"
11
+ Given an empty file named "<file3>"
12
+ Given I run `git add .`
13
+ Given I run `git commit -m add`
14
+ Given an empty file named "untracked.txt"
15
+ When I run vendor command "install"
16
+ Then following has been conjured:
17
+ | Name | find |
18
+ | Path | vendor/find |
19
+ | With file | found |
20
+ And the file "vendor/find/found" should match <matches>
21
+ And the file "vendor/find/found" should not match <doesnt_match>
22
+
23
+ Examples:
24
+ | specs | file1 | file2 | file3 | matches | doesnt_match |
25
+ | '*.txt' | foo.txt | bar.txt | baz.py | /foo\.txt/ | /baz\.py/ |
26
+ | '*.txt' | foo.txt | bar.txt | baz.py | /bar\.txt/ | /baz\.py/ |
27
+ | '*.txt' | foo.txt | bar.txt | baz.py | /bar\.txt/ | /untracked\.txt/ |
28
+ | ['*.txt', '*.py' ] | foo.txt | bar.py | baz.rb | /foo\.txt/ | /baz\.rb/ |
29
+ | ['*.txt', '*.py' ] | foo.txt | bar.py | baz.rb | /bar\.py/ | /baz\.rb/ |
30
+ | '**/*.txt' | foo.txt | foo/bar.txt | foo/bar/baz.txt | /foo\.txt/ | /xxx/ |
31
+ | '**/*.txt' | foo.txt | foo/bar.txt | foo/bar/baz.txt | /bar\.txt/ | /xxx/ |
32
+ | '**/*.txt' | foo.txt | foo/bar.txt | foo/bar/baz.txt | /baz\.txt/ | /xxx/ |
33
+
34
+ Scenario: tool can be provided with extras that are not committed to segment
35
+ Given a repository with following Vendorfile:
36
+ """ruby
37
+ tool 'find',
38
+ :specs => '*.spec',
39
+ :extras => '*.txt',
40
+ :command => "mkdir -p vendor/find ; find . -type f -not -name found -a -not -path './.git/*' > vendor/find/found"
41
+ """
42
+ Given an empty file named "foo.spec"
43
+ And an empty file named "bar.txt"
44
+ And an empty file named "baz.py"
45
+ Given I run `git add .`
46
+ And I run `git commit -m add`
47
+ Given an empty file named "untracked.txt"
48
+ And an empty file named "untracked.spec"
49
+ When I run vendor command "install"
50
+ Then following has been conjured:
51
+ | Name | find |
52
+ | Path | vendor/find |
53
+ | With file | found |
54
+ And the file "vendor/find/found" should contain "foo.spec"
55
+ And the file "vendor/find/found" should contain "bar.txt"
56
+ And the file "vendor/find/found" should not contain "baz.py"
57
+ And the file "vendor/find/found" should not contain "untracked.txt"
58
+ And the file "vendor/find/found" should not contain "untracked.spec"
59
+ And the branch "vendor/find" should contain file "foo.spec"
60
+ And the branch "vendor/find" should not contain file "bar.txt"
61
+ And the branch "vendor/find" should not contain file "untracked.txt"
62
+ And the branch "vendor/find" should not contain file "untracked.spec"
@@ -11,9 +11,10 @@ Scenario:
11
11
  """
12
12
  When I run vendor command "install -v 1"
13
13
  Then the following has been conjured:
14
- | Name | generated |
15
- | Version | 0.23 |
16
- | With file | README |
14
+ | Name | generated |
15
+ | Version | 0.23 |
16
+ | With file | README |
17
17
  And the file "vendor/generated/VERSION" should contain "0.23"
18
18
  And there's a git commit note including "bar" in "foo"
19
19
  And there's a git commit note including "by Przemo" in "module_annotations"
20
+ And tag "vendor/generated/0.23" exists
@@ -1,5 +1,6 @@
1
- # Require everything except the CLI.
1
+ require 'minigit'
2
2
 
3
+ # Require everything except the CLI.
3
4
  require "vendorificator/version"
4
5
 
5
6
  require 'vendorificator/config'
@@ -7,6 +8,7 @@ require 'vendorificator/environment'
7
8
  require 'vendorificator/errors'
8
9
  require 'vendorificator/commit'
9
10
  require 'vendorificator/io_proxy'
11
+ require 'vendorificator/overlay'
10
12
 
11
13
  require 'vendorificator/vendor'
12
14
  require 'vendorificator/vendor/download'
@@ -14,3 +16,7 @@ require 'vendorificator/vendor/archive'
14
16
  require 'vendorificator/vendor/git'
15
17
  require 'vendorificator/vendor/chef_cookbook'
16
18
  require 'vendorificator/vendor/tool'
19
+
20
+ require 'vendorificator/segment'
21
+ require 'vendorificator/segment/vendor'
22
+ require 'vendorificator/segment/overlay'
@@ -15,7 +15,7 @@ require 'vendorificator'
15
15
  module Vendorificator
16
16
  class CLI < Thor
17
17
  VERBOSITY_LEVELS = {1 => :quiet, 2 => :default, 3 => :chatty, 9 => :debug}
18
- attr_reader :environment
18
+ attr_reader :environment, :verbosity
19
19
 
20
20
  check_unknown_options! :except => [:git, :diff, :log]
21
21
  stop_on_unknown_option! :git, :diff, :log
@@ -33,7 +33,7 @@ module Vendorificator
33
33
  super
34
34
  parse_options
35
35
 
36
- if self.options[:debug]
36
+ if verbosity >= 9
37
37
  MiniGit.debug = true
38
38
  end
39
39
 
@@ -44,7 +44,7 @@ module Vendorificator
44
44
 
45
45
  @environment = Vendorificator::Environment.new(
46
46
  shell,
47
- VERBOSITY_LEVELS[self.options[:verbose]] || :default,
47
+ VERBOSITY_LEVELS[verbosity] || :default,
48
48
  self.options[:file]
49
49
  )
50
50
 
@@ -60,7 +60,7 @@ module Vendorificator
60
60
  method_option :update, :type => :boolean, :default => false
61
61
  def sync
62
62
  say_status 'DEPRECATED', 'Using vendor sync is deprecated and will be removed in future versions. Use vendor install or vendor update instead.', :yellow
63
- environment.sync options.merge(:modules => modules)
63
+ environment.sync options.merge(:segments => modules)
64
64
  rescue DirtyRepoError
65
65
  fail! 'Repository is not clean.'
66
66
  rescue MissingVendorfileError
@@ -69,14 +69,14 @@ module Vendorificator
69
69
 
70
70
  desc :install, "Download and install new or updated vendor files"
71
71
  def install(*modules)
72
- environment.sync options.merge(:modules => modules)
72
+ environment.sync options.merge(:segments => modules)
73
73
  rescue DirtyRepoError
74
74
  fail! 'Repository is not clean.'
75
75
  end
76
76
 
77
77
  desc :update, "Update installed vendor files"
78
78
  def update(*modules)
79
- environment.sync options.merge(:modules => modules, :update => true)
79
+ environment.sync options.merge(:segments => modules, :update => true)
80
80
  rescue DirtyRepoError
81
81
  fail! 'Repository is not clean.'
82
82
  end
@@ -90,7 +90,7 @@ module Vendorificator
90
90
  say_status 'DEPRECATED', 'Using vendor status is deprecated and will be removed in future versions', :yellow
91
91
  say_status 'WARNING', 'Git repository is not clean', :red unless environment.clean?
92
92
 
93
- environment.each_vendor_instance(*modules) do |mod|
93
+ environment.each_segment(*modules) do |mod|
94
94
  status_line = mod.to_s
95
95
 
96
96
  updatable = mod.updatable?
@@ -163,7 +163,7 @@ module Vendorificator
163
163
  EOF
164
164
  def git(command, *args)
165
165
  modules, git_options = split_git_options(args)
166
- environment.each_vendor_instance(*modules) do |mod|
166
+ environment.each_segment(*modules) do |mod|
167
167
  unless mod.merged
168
168
  say_status 'unmerged', mod.to_s, :red
169
169
  next
@@ -232,9 +232,10 @@ EOF
232
232
  exit
233
233
  end
234
234
 
235
- if options[:verbose] && (!VERBOSITY_LEVELS.keys.include? options[:verbose])
236
- fail! "Unknown verbosity level: #{options[:verbose].inspect}"
237
- end
235
+ # figure out verbosity
236
+ @verbosity = self.options[:verbose].to_i
237
+ @verbosity = 2 if @verbosity.zero?
238
+ @verbosity = VERBOSITY_LEVELS.keys.select { |i| i < verbosity }.max unless VERBOSITY_LEVELS[@verbosity]
238
239
  end
239
240
 
240
241
  def split_git_options(args)
@@ -3,7 +3,7 @@ require 'pathname'
3
3
  module Vendorificator
4
4
  class Config
5
5
  attr_accessor :environment
6
- attr_reader :metadata
6
+ attr_reader :metadata, :overlay_instance
7
7
 
8
8
  @defaults = {}
9
9
  @modules = {}
@@ -34,6 +34,7 @@ module Vendorificator
34
34
  end
35
35
 
36
36
  def initialize(params = {})
37
+ @fake_mode = check_fake_mode
37
38
  @configuration = self.class.defaults.merge(params)
38
39
  @metadata = {}
39
40
  end
@@ -80,8 +81,38 @@ module Vendorificator
80
81
  end
81
82
  end
82
83
 
84
+ def overlay(name, options = {}, &block)
85
+ @overlay_instance = Segment::Overlay.new(
86
+ environment: environment, overlay_opts: options.merge(name: name)
87
+ )
88
+ environment.segments << @overlay_instance
89
+ yield
90
+ ensure
91
+ @overlay_instance = nil
92
+ end
93
+
94
+ # Public: Returns information whether we work in the fake mode.
95
+ #
96
+ # Returns true/false.
97
+ def fake_mode?
98
+ @fake_mode
99
+ end
100
+
83
101
  option :basedir, 'vendor'
84
102
  option :branch_prefix, 'vendor'
85
103
  option :remotes, %w(origin)
104
+
105
+ private
106
+
107
+ # Private: Check if we should work in the fake mode.
108
+ #
109
+ # Returns true/false.
110
+ def check_fake_mode
111
+ setting = MiniGit::Capturing.git(:config, 'vendorificator.stub').strip
112
+ ['', 'false', '0', 'no'].include?(setting) ? false : true
113
+ rescue MiniGit::GitError
114
+ false
115
+ end
116
+
86
117
  end
87
118
  end
@@ -1,15 +1,14 @@
1
1
  require 'pathname'
2
- require 'minigit'
3
2
  require 'awesome_print'
4
3
  require 'vendorificator/config'
5
4
 
6
5
  module Vendorificator
7
6
  class Environment
8
7
  attr_reader :config
9
- attr_accessor :vendor_instances, :io
8
+ attr_accessor :segments, :io
10
9
 
11
10
  def initialize(shell, verbosity = :default, vendorfile = nil, &block)
12
- @vendor_instances = []
11
+ @segments = []
13
12
  @io = IOProxy.new(shell, verbosity)
14
13
  @vendorfile = find_vendorfile(vendorfile)
15
14
  @vendor_block = block
@@ -87,7 +86,7 @@ module Vendorificator
87
86
  map { |sha, name| name =~ ref_rx ? [$', sha] : nil }.
88
87
  compact ]
89
88
 
90
- each_vendor_instance do |mod|
89
+ each_segment do |mod|
91
90
  ours = mod.head
92
91
  theirs = remote_branches[mod.branch_name]
93
92
  if theirs
@@ -98,7 +97,7 @@ module Vendorificator
98
97
  say_status :default, 'unchanged', mod.branch_name
99
98
  elsif fast_forwardable?(theirs, ours)
100
99
  say_status :default, 'updated', mod.name, :yellow
101
- mod.in_branch { git.merge({:ff_only => true}, theirs) } unless options[:dry_run]
100
+ mod.fast_forward theirs unless options[:dry_run]
102
101
  elsif fast_forwardable?(ours, theirs)
103
102
  say_status :default, 'older', mod.branch_name
104
103
  else
@@ -119,7 +118,7 @@ module Vendorificator
119
118
  def info(mod_name, options = {})
120
119
  load_vendorfile
121
120
 
122
- if vendor = find_vendor_instance_by_name(mod_name)
121
+ if vendor = find_module_by_name(mod_name)
123
122
  say :default, "Module name: #{vendor.name}\n"
124
123
  say :default, "Module group: #{vendor.group}\n"
125
124
  say :default, "Module merged version: #{vendor.merged_version}\n"
@@ -132,25 +131,25 @@ module Vendorificator
132
131
  end
133
132
  end
134
133
 
135
- # Public: Displays info about current modules.
134
+ # Public: Displays info about current segments.
136
135
  #
137
136
  # Returns nothing.
138
137
  def list
139
138
  load_vendorfile
140
139
 
141
- each_vendor_instance do |mod|
140
+ each_segment do |mod|
142
141
  shell.say "Module: #{mod.name}, version: #{mod.version}"
143
142
  end
144
143
  end
145
144
 
146
- # Public: Displays info about outdated modules.
145
+ # Public: Displays info about outdated segments.
147
146
  #
148
147
  # Returns nothing.
149
148
  def outdated
150
149
  load_vendorfile
151
150
 
152
151
  outdated = []
153
- each_vendor_instance do |mod|
152
+ each_segment do |mod|
154
153
  outdated << mod if [:unpulled, :unmerged, :outdated].include? mod.status
155
154
  end
156
155
 
@@ -168,7 +167,7 @@ module Vendorificator
168
167
  ensure_clean!
169
168
 
170
169
  pushable = []
171
- each_vendor_instance { |mod| pushable += mod.pushable_refs }
170
+ each_segment { |mod| pushable += mod.pushable_refs }
172
171
 
173
172
  pushable << 'refs/notes/vendor' if has_notes?
174
173
 
@@ -178,7 +177,7 @@ module Vendorificator
178
177
  end
179
178
  end
180
179
 
181
- # Public: Runs all the vendor modules.
180
+ # Public: Runs all the vendor segments.
182
181
  #
183
182
  # options - The Hash of options.
184
183
  #
@@ -190,28 +189,25 @@ module Vendorificator
190
189
  config[:use_upstream_version] = options[:update]
191
190
  metadata = metadata_snapshot
192
191
 
193
- each_vendor_instance(*options[:modules]) do |mod|
194
- say_status :default, :module, mod.name
195
- indent do
196
- mod.run!(:metadata => metadata)
197
- end
192
+ each_segment(*options[:segments]) do |mod|
193
+ mod.run!(:metadata => metadata)
198
194
  end
199
195
  end
200
196
 
201
197
  # Public: Goes through all the Vendor instances and runs the block
202
198
  #
203
- # modules - An Array of vendor modules to yield the block for.
199
+ # segments - An Array of vendor segments to yield the block for.
204
200
  #
205
201
  # Returns nothing.
206
- def each_vendor_instance(*modules)
207
- # We don't use @vendor_instances.each here, because Vendor#run! is
202
+ def each_segment(*segments)
203
+ # We don't use @segments.each here, because Vendor#run! is
208
204
  # explicitly allowed to append to instantiate new dependencies, and #each
209
205
  # fails to catch up on some Ruby implementations.
210
206
  i = 0
211
207
  while true
212
- break if i >= @vendor_instances.length
213
- mod = @vendor_instances[i]
214
- yield mod if modules.empty? || mod.included_in_list?(modules)
208
+ break if i >= @segments.length
209
+ mod = @segments[i]
210
+ yield mod if segments.empty? || mod.included_in_list?(segments)
215
211
  i += 1
216
212
  end
217
213
  end
@@ -247,7 +243,7 @@ module Vendorificator
247
243
 
248
244
  # Public: Returns module with given name
249
245
  def [](name)
250
- vendor_instances.find { |v| v.name == name }
246
+ segments.find { |v| v.name == name }
251
247
  end
252
248
 
253
249
  # Public: Loads the vendorfile.
@@ -263,7 +259,7 @@ module Vendorificator
263
259
  end
264
260
  @config.instance_eval(&@vendor_block) if @vendor_block
265
261
 
266
- each_vendor_instance{ |mod| mod.compute_dependencies! }
262
+ each_segment{ |mod| mod.compute_dependencies! }
267
263
 
268
264
  @vendorfile_loaded = true
269
265
  end
@@ -282,8 +278,8 @@ module Vendorificator
282
278
  # mod_name - The String containing the module id.
283
279
  #
284
280
  # Returns Vendor instance.
285
- def find_vendor_instance_by_name(mod_name)
286
- each_vendor_instance(mod_name) do |mod|
281
+ def find_module_by_name(mod_name)
282
+ each_segment(mod_name) do |mod|
287
283
  return mod
288
284
  end
289
285
  nil