appraisal 2.0.1 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/appraisal/cli.rb CHANGED
@@ -19,11 +19,11 @@ module Appraisal
19
19
  appraisal, otherwise it runs the EXTERNAL_COMMAND against all appraisals.
20
20
  help
21
21
 
22
- if ::File.exist?('Appraisals')
22
+ if File.exist?('Appraisals')
23
23
  shell.say
24
24
  shell.say 'Available Appraisal(s):'
25
25
 
26
- File.each do |appraisal|
26
+ AppraisalFile.each do |appraisal|
27
27
  shell.say " - #{appraisal.name}"
28
28
  end
29
29
  end
@@ -41,11 +41,23 @@ module Appraisal
41
41
  method_option 'jobs', :aliases => 'j', :type => :numeric, :default => 1,
42
42
  :banner => 'SIZE',
43
43
  :desc => 'Install gems in parallel using the given number of workers.'
44
+ method_option 'retry', :type => :numeric, :default => 1,
45
+ :desc => 'Retry network and git requests that have failed'
46
+ method_option "without", :banner => "GROUP_NAMES",
47
+ :desc => "A space-separated list of groups referencing gems to skip " +
48
+ "during installation. Bundler will remember this option."
49
+ method_option "full-index", :type => :boolean,
50
+ :desc => "Run bundle install with the " \
51
+ "full-index argument."
52
+ method_option "path", type: :string,
53
+ desc: "Install gems in the specified directory. " \
54
+ "Bundler will remember this option."
55
+
44
56
  def install
45
57
  invoke :generate, [], {}
46
58
 
47
- File.each do |appraisal|
48
- appraisal.install(options[:jobs])
59
+ AppraisalFile.each do |appraisal|
60
+ appraisal.install(options)
49
61
  appraisal.relativize
50
62
  end
51
63
  end
@@ -53,7 +65,7 @@ module Appraisal
53
65
  desc 'generate', 'Generate a gemfile for each appraisal'
54
66
  method_option "travis", :type => :boolean, :default => false
55
67
  def generate
56
- File.each do |appraisal|
68
+ AppraisalFile.each do |appraisal|
57
69
  appraisal.write_gemfile
58
70
  end
59
71
 
@@ -73,14 +85,14 @@ module Appraisal
73
85
  def update(*gems)
74
86
  invoke :generate, []
75
87
 
76
- File.each do |appraisal|
88
+ AppraisalFile.each do |appraisal|
77
89
  appraisal.update(gems)
78
90
  end
79
91
  end
80
92
 
81
93
  desc 'list', 'List the names of the defined appraisals'
82
94
  def list
83
- File.new.appraisals.each { |appraisal| puts appraisal.name }
95
+ AppraisalFile.new.appraisals.each { |appraisal| puts appraisal.name }
84
96
  end
85
97
 
86
98
  desc "version", "Display the version and exit"
@@ -91,12 +103,14 @@ module Appraisal
91
103
  private
92
104
 
93
105
  def method_missing(name, *args, &block)
94
- matching_appraisal = File.new.appraisals.detect { |appraisal| appraisal.name == name.to_s }
106
+ matching_appraisal = AppraisalFile.new.appraisals.detect do |appraisal|
107
+ appraisal.name == name.to_s
108
+ end
95
109
 
96
110
  if matching_appraisal
97
111
  Command.new(args, :gemfile => matching_appraisal.gemfile_path).run
98
112
  else
99
- File.each do |appraisal|
113
+ AppraisalFile.each do |appraisal|
100
114
  Command.new(ARGV, :gemfile => appraisal.gemfile_path).run
101
115
  end
102
116
  end
@@ -41,14 +41,17 @@ module Appraisal
41
41
  end
42
42
 
43
43
  def ensure_bundler_is_available
44
- unless system %(gem list -q "^bundler$" | grep -q bundler)
44
+ version = Utils.bundler_version
45
+ unless system %(gem list -i bundler -v #{version})
45
46
  puts ">> Reinstall Bundler into #{ENV["GEM_HOME"]}"
46
47
 
47
- unless system "gem install bundler"
48
+ unless system "gem install bundler --version #{version}"
48
49
  puts
49
50
  puts <<-ERROR.strip.gsub(/\s+/, " ")
50
- Bundler installation failed. Please try running
51
- `GEM_HOME="#{ENV["GEM_HOME"]}" gem install bundler` manually.
51
+ Bundler installation failed.
52
+ Please try running:
53
+ `GEM_HOME="#{ENV["GEM_HOME"]}" gem install bundler --version #{version}`
54
+ manually.
52
55
  ERROR
53
56
  exit(1)
54
57
  end
@@ -1,14 +1,22 @@
1
1
  require 'appraisal/dependency'
2
- require "active_support/ordered_hash"
3
2
 
4
3
  module Appraisal
5
4
  class DependencyList
6
5
  def initialize
7
- @dependencies = ActiveSupport::OrderedHash.new
6
+ @dependencies = Hash.new
7
+ @removed_dependencies = Set.new
8
8
  end
9
9
 
10
10
  def add(name, requirements)
11
- @dependencies[name] = Dependency.new(name, requirements)
11
+ unless @removed_dependencies.include?(name)
12
+ @dependencies[name] = Dependency.new(name, requirements)
13
+ end
14
+ end
15
+
16
+ def remove(name)
17
+ if @removed_dependencies.add?(name)
18
+ @dependencies.delete(name)
19
+ end
12
20
  end
13
21
 
14
22
  def to_s
@@ -2,15 +2,18 @@ require "appraisal/bundler_dsl"
2
2
 
3
3
  module Appraisal
4
4
  autoload :Gemspec, "appraisal/gemspec"
5
- autoload :GitSource, "appraisal/git_source"
6
- autoload :PathSource, "appraisal/path_source"
5
+ autoload :Git, "appraisal/git"
7
6
  autoload :Group, "appraisal/group"
7
+ autoload :Path, "appraisal/path"
8
8
  autoload :Platform, "appraisal/platform"
9
+ autoload :Source, "appraisal/source"
9
10
 
10
11
  # Load bundler Gemfiles and merge dependencies
11
12
  class Gemfile < BundlerDSL
12
13
  def load(path)
13
- run(IO.read(path))
14
+ if File.exist?(path)
15
+ run(IO.read(path))
16
+ end
14
17
  end
15
18
 
16
19
  def run(definitions)
@@ -19,6 +22,7 @@ module Appraisal
19
22
 
20
23
  def dup
21
24
  Gemfile.new.tap do |gemfile|
25
+ gemfile.git_sources = @git_sources
22
26
  gemfile.run(for_dup)
23
27
  end
24
28
  end
@@ -2,7 +2,7 @@ require "appraisal/bundler_dsl"
2
2
  require 'appraisal/utils'
3
3
 
4
4
  module Appraisal
5
- class GitSource < BundlerDSL
5
+ class Git < BundlerDSL
6
6
  def initialize(source, options = {})
7
7
  super()
8
8
  @source = source
@@ -2,7 +2,7 @@ require "appraisal/bundler_dsl"
2
2
  require 'appraisal/utils'
3
3
 
4
4
  module Appraisal
5
- class PathSource < BundlerDSL
5
+ class Path < BundlerDSL
6
6
  def initialize(source, options = {})
7
7
  super()
8
8
  @source = source
@@ -0,0 +1,30 @@
1
+ require "appraisal/bundler_dsl"
2
+ require "appraisal/utils"
3
+
4
+ module Appraisal
5
+ class Source < BundlerDSL
6
+ def initialize(source)
7
+ super()
8
+ @source = source
9
+ end
10
+
11
+ def to_s
12
+ formatted_output indent(super)
13
+ end
14
+
15
+ # :nodoc:
16
+ def for_dup
17
+ formatted_output indent(super)
18
+ end
19
+
20
+ private
21
+
22
+ def formatted_output(output_dependencies)
23
+ <<-OUTPUT.strip
24
+ source #{@source.inspect} do
25
+ #{output_dependencies}
26
+ end
27
+ OUTPUT
28
+ end
29
+ end
30
+ end
@@ -1,4 +1,4 @@
1
- require 'appraisal/file'
1
+ require 'appraisal/appraisal_file'
2
2
  require 'rake/tasklib'
3
3
 
4
4
  module Appraisal
@@ -29,7 +29,7 @@ module Appraisal
29
29
  end
30
30
 
31
31
  begin
32
- File.each do |appraisal|
32
+ AppraisalFile.each do |appraisal|
33
33
  desc "DEPRECATED: Run the given task for appraisal #{appraisal.name}"
34
34
  task appraisal.name do
35
35
  ARGV.shift
@@ -1,10 +1,11 @@
1
- require "appraisal/file"
1
+ require "appraisal/appraisal_file"
2
2
  require "yaml"
3
3
 
4
4
  module Appraisal
5
5
  class TravisCIHelper
6
- NO_CONFIGURATION_WARNING = <<-WARNING.strip
7
- Note: Run with --travis to generate Travis CI configuration.
6
+ NO_CONFIGURATION_WARNING = <<-WARNING.strip.gsub(/\s+/, " ")
7
+ Note: Run `appraisal generate --travis` to generate Travis CI
8
+ configuration.
8
9
  WARNING
9
10
 
10
11
  INVALID_CONFIGURATION_WARNING = <<-WARNING.strip.gsub(/\s+/, " ")
@@ -19,7 +20,7 @@ module Appraisal
19
20
  puts "# Put this in your .travis.yml"
20
21
  puts "#{GEMFILES_CONFIGURATION_KEY}:"
21
22
 
22
- File.each do |appraisal|
23
+ AppraisalFile.each do |appraisal|
23
24
  puts " - #{appraisal.relative_gemfile_path}"
24
25
  end
25
26
  end
@@ -44,7 +45,7 @@ module Appraisal
44
45
  private
45
46
 
46
47
  def has_configuration_file?
47
- ::File.exist?(CONFIGURATION_FILE)
48
+ File.exist?(CONFIGURATION_FILE)
48
49
  end
49
50
 
50
51
  def has_no_gemfiles_configuration?
@@ -54,7 +55,7 @@ module Appraisal
54
55
  def has_invalid_gemfiles_configuration?
55
56
  if configuration && configuration[GEMFILES_CONFIGURATION_KEY]
56
57
  appraisal_paths =
57
- File.new.appraisals.map(&:relative_gemfile_path).sort
58
+ AppraisalFile.new.appraisals.map(&:relative_gemfile_path).sort
58
59
  travis_gemfile_paths = configuration[GEMFILES_CONFIGURATION_KEY].sort
59
60
  appraisal_paths != travis_gemfile_paths
60
61
  end
@@ -9,7 +9,7 @@ module Appraisal
9
9
  case object
10
10
  when Hash
11
11
  items = object.map do |key, value|
12
- "#{format_string(key, true)} => #{format_string(value, true)}"
12
+ format_hash_value(key, value)
13
13
  end
14
14
 
15
15
  if enclosing_object
@@ -22,6 +22,17 @@ module Appraisal
22
22
  end
23
23
  end
24
24
 
25
+ def self.format_hash_value(key, value)
26
+ key = format_string(key, true)
27
+ value = format_string(value, true)
28
+
29
+ if key.start_with?(":")
30
+ "#{key.sub(/^:/, "")}: #{value}"
31
+ else
32
+ "#{key} => #{value}"
33
+ end
34
+ end
35
+
25
36
  def self.format_arguments(arguments)
26
37
  unless arguments.empty?
27
38
  arguments.map { |object| format_string(object, false) }.join(', ')
@@ -35,10 +46,17 @@ module Appraisal
35
46
  def self.prefix_path(path)
36
47
  if path !~ /^(?:\/|\S:)/ && path !~ /^\S+:\/\// && path !~ /^\S+@\S+:/
37
48
  cleaned_path = path.gsub(/(^|\/)\.(?:\/|$)/, "\\1")
38
- ::File.join("..", cleaned_path)
49
+ File.join("..", cleaned_path)
39
50
  else
40
51
  path
41
52
  end
42
53
  end
54
+
55
+ def self.bundler_version
56
+ Gem::Specification.
57
+ detect { |spec| spec.name == "bundler" }.
58
+ version.
59
+ to_s
60
+ end
43
61
  end
44
62
  end
@@ -1,3 +1,3 @@
1
1
  module Appraisal
2
- VERSION = '2.0.1'.freeze
2
+ VERSION = "2.4.0".freeze
3
3
  end
@@ -2,14 +2,17 @@ require 'spec_helper'
2
2
 
3
3
  describe 'Appraisals file Bundler DSL compatibility' do
4
4
  it 'supports all Bundler DSL in Appraisals file' do
5
- build_gems %w(bagel orange_juice milk waffle coffee ham)
6
- build_git_gem 'egg'
5
+ build_gems %w(bagel orange_juice milk waffle coffee ham
6
+ sausage pancake rotten_egg)
7
+ build_git_gems %w(egg croissant pain_au_chocolat omelette)
7
8
 
8
9
  build_gemfile <<-Gemfile
9
10
  source 'https://rubygems.org'
11
+ git_source(:custom_git_source) { |repo| "../gems/\#{repo}" }
10
12
  ruby RUBY_VERSION
11
13
 
12
14
  gem 'bagel'
15
+ gem "croissant", :custom_git_source => "croissant"
13
16
 
14
17
  git '../gems/egg' do
15
18
  gem 'egg'
@@ -21,6 +24,8 @@ describe 'Appraisals file Bundler DSL compatibility' do
21
24
 
22
25
  group :breakfast do
23
26
  gem 'orange_juice'
27
+ gem "omelette", :custom_git_source => "omelette"
28
+ gem 'rotten_egg'
24
29
  end
25
30
 
26
31
  platforms :ruby, :jruby do
@@ -31,15 +36,20 @@ describe 'Appraisals file Bundler DSL compatibility' do
31
36
  end
32
37
  end
33
38
 
39
+ source "https://other-rubygems.org" do
40
+ gem "sausage"
41
+ end
42
+
34
43
  gem 'appraisal', :path => #{PROJECT_ROOT.inspect}
35
44
  Gemfile
36
45
 
37
46
  build_appraisal_file <<-Appraisals
38
47
  appraise 'breakfast' do
39
48
  source 'http://some-other-source.com'
40
- ruby "1.8.7"
49
+ ruby "2.3.0"
41
50
 
42
51
  gem 'bread'
52
+ gem "pain_au_chocolat", :custom_git_source => "pain_au_chocolat"
43
53
 
44
54
  git '../gems/egg' do
45
55
  gem 'porched_egg'
@@ -50,6 +60,7 @@ describe 'Appraisals file Bundler DSL compatibility' do
50
60
  end
51
61
 
52
62
  group :breakfast do
63
+ remove_gem 'rotten_egg'
53
64
  gem 'bacon'
54
65
 
55
66
  platforms :rbx do
@@ -61,7 +72,12 @@ describe 'Appraisals file Bundler DSL compatibility' do
61
72
  gem 'yoghurt'
62
73
  end
63
74
 
75
+ source "https://other-rubygems.org" do
76
+ gem "pancake"
77
+ end
78
+
64
79
  gemspec
80
+ gemspec :path => "sitepress"
65
81
  end
66
82
  Appraisals
67
83
 
@@ -74,7 +90,7 @@ describe 'Appraisals file Bundler DSL compatibility' do
74
90
  source "https://rubygems.org"
75
91
  source "http://some-other-source.com"
76
92
 
77
- ruby "1.8.7"
93
+ ruby "2.3.0"
78
94
 
79
95
  git "../../gems/egg" do
80
96
  gem "egg"
@@ -87,11 +103,14 @@ describe 'Appraisals file Bundler DSL compatibility' do
87
103
  end
88
104
 
89
105
  gem "bagel"
106
+ gem "croissant", :git => "../../gems/croissant"
90
107
  gem "appraisal", :path => #{PROJECT_ROOT.inspect}
91
108
  gem "bread"
109
+ gem "pain_au_chocolat", :git => "../../gems/pain_au_chocolat"
92
110
 
93
111
  group :breakfast do
94
112
  gem "orange_juice"
113
+ gem "omelette", :git => "../../gems/omelette"
95
114
  gem "bacon"
96
115
 
97
116
  platforms :rbx do
@@ -108,7 +127,13 @@ describe 'Appraisals file Bundler DSL compatibility' do
108
127
  end
109
128
  end
110
129
 
130
+ source "https://other-rubygems.org" do
131
+ gem "sausage"
132
+ gem "pancake"
133
+ end
134
+
111
135
  gemspec :path => "../"
136
+ gemspec :path => "../sitepress"
112
137
  Gemfile
113
138
  end
114
139
  end
@@ -1,22 +1,53 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe "Bundle with custom path" do
4
- it "supports --path option" do
5
- build_gemfile <<-Gemfile
6
- source "https://rubygems.org"
4
+ let(:gem_name) { 'rack' }
5
+ let(:path) { 'vendor/bundle' }
7
6
 
8
- gem 'appraisal', :path => #{PROJECT_ROOT.inspect}
9
- Gemfile
7
+ shared_examples :gemfile_dependencies_are_satisfied do
10
8
 
11
- build_appraisal_file <<-Appraisals
12
- appraise "breakfast" do
13
- end
14
- Appraisals
9
+ it 'installs gems in the --path directory' do
10
+ build_gemfile <<-Gemfile
11
+ source "https://rubygems.org"
15
12
 
16
- run %(bundle install --path="vendor/bundle")
17
- output = run "appraisal install"
13
+ gem 'appraisal', :path => #{PROJECT_ROOT.inspect}
14
+ Gemfile
18
15
 
19
- expect(file "gemfiles/breakfast.gemfile").to be_exists
20
- expect(output).to include("Successfully installed bundler")
16
+ build_appraisal_file <<-Appraisals
17
+ appraise "#{gem_name}" do
18
+ gem '#{gem_name}'
19
+ end
20
+ Appraisals
21
+
22
+ run %(bundle install --path="#{path}")
23
+ run 'bundle exec appraisal install'
24
+
25
+ installed_gem = Dir.glob("tmp/stage/#{path}/#{Gem.ruby_engine}/*/gems/*").
26
+ map { |path| path.split('/').last }.
27
+ select { |gem| gem.include?(gem_name) }
28
+ expect(installed_gem).not_to be_empty
29
+
30
+ bundle_output = run 'bundle check'
31
+ expect(bundle_output).to include("The Gemfile's dependencies are satisfied")
32
+
33
+ appraisal_output = run 'bundle exec appraisal install'
34
+ expect(appraisal_output).to include("The Gemfile's dependencies are satisfied")
35
+ end
36
+ end
37
+
38
+ include_examples :gemfile_dependencies_are_satisfied
39
+
40
+ context 'when already installed in vendor/another' do
41
+ before do
42
+ build_gemfile <<-Gemfile
43
+ source "https://rubygems.org"
44
+
45
+ gem '#{gem_name}'
46
+ Gemfile
47
+
48
+ run 'bundle install --path vendor/another'
49
+ end
50
+
51
+ include_examples :gemfile_dependencies_are_satisfied
21
52
  end
22
53
  end