appraisal 2.0.0 → 2.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 0f0ed208de18ec1152d5f8d9d77e86a42236f89f
4
- data.tar.gz: 5a0a145e1c89faeb6447aa5ca47b9662e69ed84c
2
+ SHA256:
3
+ metadata.gz: 0e5becde2c97891ac7e0d0cb0e8943653ec7b43ca3dcad2f60a8aa7becd9a977
4
+ data.tar.gz: bac9e06f7948cc07025d06572f373f444e8159422ac9c62aa5e29ae6e32f6fdb
5
5
  SHA512:
6
- metadata.gz: 5c182a653a7e693cfcf9f288aa25a0f9c5ec312b89c7ea3741927eea0a4d4c7890230ef760313a3753bfee4cb9ddf3a5829f255f5a14393fd6013724e0bcf97f
7
- data.tar.gz: 9bc7f08e8982c0234ddc3e098fe75ba530604eb2f79546032537db14faa74d2dc3aa71a17e5e15ced8059e39de17701bff90e6b66caa3c76422071d8b4a44f6b
6
+ metadata.gz: d9b23d137f23b270822cf4e49248cc2f2a3bd229668d96f44feaf3a7d804b7daddca6429ebe2dba8f5782ee5b4f9860da0e0976e9b25e5baf419180e463bb85e
7
+ data.tar.gz: de06629b275c669997f73c5e840458f6de44ca435a4e8a543ff49b8e4d7a6c98d44006dc780df173d37958a4b6e8286184571a135b19d9529465206f7f548d8d
@@ -1,22 +1,18 @@
1
- sudo: false
2
-
3
- before_install: gem install bundler
1
+ ---
2
+ before_install: gem install bundler:2.1.4
4
3
 
5
4
  rvm:
6
- - 1.8
7
- - 1.9
8
- - 2.0
9
- - 2.1
10
- - 2.2
11
- - rbx-2
12
- - jruby-19mode
5
+ - 2.3
6
+ - 2.4
7
+ - 2.5
8
+ - 2.6
9
+ - 2.7
10
+ - jruby-9.2.9.0
13
11
  - ruby-head
14
12
  - jruby-head
15
13
 
16
14
  matrix:
17
15
  fast_finish: true
18
16
  allow_failures:
19
- - rvm: rbx-2
20
- - rvm: jruby-19mode
21
17
  - rvm: ruby-head
22
18
  - rvm: jruby-head
data/Gemfile CHANGED
@@ -1,11 +1,6 @@
1
- source 'https://rubygems.org'
1
+ source "https://rubygems.org"
2
2
 
3
3
  gemspec
4
4
 
5
5
  # This here to make sure appraisal works with Rails 3.0.0.
6
- gem 'thor', '~> 0.14.0'
7
-
8
- if RUBY_VERSION < "1.9"
9
- gem "i18n", "~> 0.6.0"
10
- gem "activesupport", "~> 3.2.21"
11
- end
6
+ gem "thor", "~> 0.14.0"
data/README.md CHANGED
@@ -5,7 +5,7 @@ Appraisal
5
5
 
6
6
  Find out what your Ruby gems are worth.
7
7
 
8
- [Build Status Image]: https://secure.travis-ci.org/thoughtbot/appraisal.png?branch=master
8
+ [Build Status Image]: https://secure.travis-ci.org/thoughtbot/appraisal.svg?branch=master
9
9
  [Build Status]: http://travis-ci.org/thoughtbot/appraisal
10
10
 
11
11
  Synopsis
@@ -19,22 +19,23 @@ without interfering with day-to-day development using Bundler.
19
19
  Installation
20
20
  ------------
21
21
 
22
- In your Gemfile:
22
+ In your package's `.gemspec`:
23
23
 
24
- gem "appraisal"
24
+ s.add_development_dependency "appraisal"
25
25
 
26
- Note that gems must be bundled in the global namespace. Bundling gems to a local
27
- location or vendoring plugins is not supported. If you do not want to pollute the
28
- global namespace, one alternative is [RVM's Gemsets](http://rvm.io/gemsets).
26
+ Note that gems must be bundled in the global namespace. Bundling gems to a
27
+ local location or vendoring plugins is not supported. If you do not want to
28
+ pollute the global namespace, one alternative is
29
+ [RVM's Gemsets](http://rvm.io/gemsets).
29
30
 
30
31
  Setup
31
32
  -----
32
33
 
33
- Setting up appraisal requires an Appraisals file (similar to a Gemfile) in your
34
- project root, named "Appraisals" (note the case), and some slight changes to
35
- your project's Rakefile.
34
+ Setting up appraisal requires an `Appraisals` file (similar to a `Gemfile`) in
35
+ your project root, named "Appraisals" (note the case), and some slight changes
36
+ to your project's `Rakefile`.
36
37
 
37
- An Appraisals file consists of several appraisal definitions. An appraisal
38
+ An `Appraisals` file consists of several appraisal definitions. An appraisal
38
39
  definition is simply a list of gem dependencies. For example, to test with a
39
40
  few versions of Rails:
40
41
 
@@ -46,35 +47,29 @@ few versions of Rails:
46
47
  gem "rails", "4.0.0"
47
48
  end
48
49
 
49
- The dependencies in your Appraisals file are combined with dependencies in your
50
- Gemfile, so you don't need to repeat anything that's the same for each
50
+ The dependencies in your `Appraisals` file are combined with dependencies in
51
+ your `Gemfile`, so you don't need to repeat anything that's the same for each
51
52
  appraisal. If something is specified in both the Gemfile and an appraisal, the
52
53
  version from the appraisal takes precedence.
53
54
 
54
- It's also recommended that you setup bundler at the very top of your Rakefile,
55
- so that you don't need to constantly run bundle exec:
56
-
57
- require "rubygems"
58
- require "bundler/setup"
59
-
60
55
  Usage
61
56
  -----
62
57
 
63
58
  Once you've configured the appraisals you want to use, you need to install the
64
59
  dependencies for each appraisal:
65
60
 
66
- appraisal install
61
+ $ bundle exec appraisal install
67
62
 
68
63
  This will resolve, install, and lock the dependencies for that appraisal using
69
64
  bundler. Once you have your dependencies set up, you can run any command in a
70
65
  single appraisal:
71
66
 
72
- appraisal rails-3 rake test
67
+ $ bundle exec appraisal rails-3 rake test
73
68
 
74
69
  This will run `rake test` using the dependencies configured for Rails 3. You can
75
70
  also run each appraisal in turn:
76
71
 
77
- appraisal rake test
72
+ $ bundle exec appraisal rake test
78
73
 
79
74
  If you want to use only the dependencies from your Gemfile, just run `rake
80
75
  test` as normal. This allows you to keep running with the latest versions of
@@ -96,6 +91,18 @@ Note that this may conflict with your CI setup if you decide to split the test
96
91
  into multiple processes by Appraisal and you are using `rake` to run tests by
97
92
  default. Please see **Travis CI Integration** for more detail.
98
93
 
94
+ ### Commands
95
+
96
+ ```bash
97
+ appraisal clean # Remove all generated gemfiles and lockfiles from gemfiles folder
98
+ appraisal generate # Generate a gemfile for each appraisal
99
+ appraisal help [COMMAND] # Describe available commands or one specific command
100
+ appraisal install # Resolve and install dependencies for each appraisal
101
+ appraisal list # List the names of the defined appraisals
102
+ appraisal update [LIST_OF_GEMS] # Remove all generated gemfiles and lockfiles, resolve, and install dependencies again
103
+ appraisal version # Display the version and exit
104
+ ```
105
+
99
106
  Under the hood
100
107
  --------------
101
108
 
@@ -139,15 +146,38 @@ all versions of its dependency, you might have to set a `script` setting:
139
146
  That will make sure that each of the test sub-job are not getting run more than
140
147
  one time.
141
148
 
142
- You can also running your test against multiple versions of Ruby locally, just
149
+ You can also run your tests against multiple versions of Ruby locally, just
143
150
  like running on Travis CI, by using [WWTD].
144
151
 
145
152
  [WWTD]: https://github.com/grosser/wwtd
146
153
 
154
+ Circle CI Integration
155
+ ---------------------
156
+
157
+ In Circle CI you can override the default testing behaviour to customize your
158
+ testing. Using this feature you can configure appraisal to execute your tests.
159
+
160
+ In order to this you can put the following configuration in your circle.yml file:
161
+
162
+ ```yml
163
+ dependencies:
164
+ post:
165
+ - bundle exec appraisal install
166
+ test:
167
+ pre:
168
+ - bundle exec appraisal rake db:create
169
+ - bundle exec appraisal rake db:migrate
170
+ override:
171
+ - bundle exec appraisal rspec
172
+ ```
173
+
174
+ Notice that we are running an rspec suite. You can customize your testing
175
+ command in the `override` section and use your favourite one.
176
+
147
177
  Credits
148
178
  -------
149
179
 
150
- ![thoughtbot](http://thoughtbot.com/images/tm/logo.png)
180
+ ![thoughtbot](http://presskit.thoughtbot.com/images/thoughtbot-logo-for-readmes.svg)
151
181
 
152
182
  Appraisal is maintained and funded by [thoughtbot, inc][thoughtbot]
153
183
 
@@ -18,10 +18,12 @@ Gem::Specification.new do |s|
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
20
 
21
+ s.required_ruby_version = ">= 2.3.0"
22
+
21
23
  s.add_runtime_dependency('rake')
22
24
  s.add_runtime_dependency('bundler')
23
25
  s.add_runtime_dependency('thor', '>= 0.14.0')
24
- s.add_runtime_dependency("activesupport", ">= 3.2.21")
25
26
 
27
+ s.add_development_dependency("activesupport", ">= 3.2.21")
26
28
  s.add_development_dependency('rspec', '~> 3.0')
27
29
  end
@@ -7,6 +7,8 @@ require 'pathname'
7
7
  module Appraisal
8
8
  # Represents one appraisal and its dependencies
9
9
  class Appraisal
10
+ DEFAULT_INSTALL_OPTIONS = { "jobs" => 1 }.freeze
11
+
10
12
  attr_reader :name, :gemfile
11
13
 
12
14
  def initialize(name, source_gemfile)
@@ -18,8 +20,8 @@ module Appraisal
18
20
  gemfile.gem(*args)
19
21
  end
20
22
 
21
- def source(*args)
22
- gemfile.source(*args)
23
+ def source(*args, &block)
24
+ gemfile.source(*args, &block)
23
25
  end
24
26
 
25
27
  def ruby(*args)
@@ -46,26 +48,36 @@ module Appraisal
46
48
  gemfile.gemspec(options)
47
49
  end
48
50
 
51
+ def git_source(*args, &block)
52
+ gemfile.git_source(*args, &block)
53
+ end
54
+
49
55
  def write_gemfile
50
- ::File.open(gemfile_path, "w") do |file|
56
+ File.open(gemfile_path, "w") do |file|
51
57
  signature = "# This file was generated by Appraisal"
52
58
  file.puts([signature, gemfile.to_s].join("\n\n"))
53
59
  end
54
60
  end
55
61
 
56
- def install(job_size = 1)
57
- command = [
58
- check_command,
59
- "||",
60
- install_command(job_size)
61
- ].flatten.join(" ")
62
+ def install(options = {})
63
+ commands = [install_command(options).join(" ")]
62
64
 
63
- Command.new(command).run
65
+ if options["without"].nil? || options["without"].empty?
66
+ commands.unshift(check_command.join(" "))
67
+ end
68
+
69
+ command = commands.join(" || ")
70
+
71
+ if Bundler.settings[:path]
72
+ env = { 'BUNDLE_DISABLE_SHARED_GEMS' => '1' }
73
+ Command.new(command, :env => env).run
74
+ else
75
+ Command.new(command).run
76
+ end
64
77
  end
65
78
 
66
79
  def update(gems = [])
67
- command, env = update_command(gems)
68
- Command.new(command, :env => env).run
80
+ Command.new(update_command(gems), :gemfile => gemfile_path).run
69
81
  end
70
82
 
71
83
  def gemfile_path
@@ -77,15 +89,15 @@ module Appraisal
77
89
  end
78
90
 
79
91
  def relative_gemfile_path
80
- ::File.join("gemfiles", gemfile_name)
92
+ File.join("gemfiles", gemfile_name)
81
93
  end
82
94
 
83
95
  def relativize
84
96
  current_directory = Pathname.new(Dir.pwd)
85
97
  relative_path = current_directory.relative_path_from(gemfile_root).cleanpath
86
- lockfile_content = ::File.read(lockfile_path)
98
+ lockfile_content = File.read(lockfile_path)
87
99
 
88
- ::File.open(lockfile_path, 'w') do |file|
100
+ File.open(lockfile_path, 'w') do |file|
89
101
  file.write lockfile_content.gsub(/#{current_directory}/, relative_path.to_s)
90
102
  end
91
103
  end
@@ -97,19 +109,21 @@ module Appraisal
97
109
  ['bundle', 'check', gemfile_option]
98
110
  end
99
111
 
100
- def install_command(job_size)
112
+ def install_command(options = {})
101
113
  gemfile_option = "--gemfile='#{gemfile_path}'"
102
- ['bundle', 'install', gemfile_option, bundle_parallel_option(job_size)].compact
114
+ ['bundle', 'install', gemfile_option, bundle_options(options)].compact
103
115
  end
104
116
 
105
117
  def update_command(gems)
106
- env = { "BUNDLE_GEMFILE" => gemfile_path }
107
- command = ['bundle', 'update', *gems].compact
108
- [command, env]
118
+ ['bundle', 'update', *gems].compact
109
119
  end
110
120
 
111
121
  def gemfile_root
112
- Pathname.new(::File.join(Dir.pwd, "gemfiles"))
122
+ project_root + "gemfiles"
123
+ end
124
+
125
+ def project_root
126
+ Pathname.new(Dir.pwd)
113
127
  end
114
128
 
115
129
  def gemfile_name
@@ -124,15 +138,30 @@ module Appraisal
124
138
  name.gsub(/[^\w\.]/, '_')
125
139
  end
126
140
 
127
- def bundle_parallel_option(job_size)
128
- if job_size > 1
141
+ def bundle_options(options)
142
+ full_options = DEFAULT_INSTALL_OPTIONS.dup.merge(options)
143
+ options_strings = []
144
+ jobs = full_options.delete("jobs")
145
+ if jobs > 1
129
146
  if Utils.support_parallel_installation?
130
- "--jobs=#{job_size}"
147
+ options_strings << "--jobs=#{jobs}"
131
148
  else
132
149
  warn 'Your current version of Bundler does not support parallel installation. Please ' +
133
150
  'upgrade Bundler to version >= 1.4.0, or invoke `appraisal` without `--jobs` option.'
134
151
  end
135
152
  end
153
+
154
+ path = full_options.delete("path")
155
+ if path
156
+ relative_path = project_root.join(options["path"])
157
+ options_strings << "--path #{relative_path}"
158
+ end
159
+
160
+ full_options.each do |flag, val|
161
+ options_strings << "--#{flag} #{val}"
162
+ end
163
+
164
+ options_strings.join(" ") if options_strings != []
136
165
  end
137
166
  end
138
167
  end
@@ -4,7 +4,7 @@ require 'appraisal/gemfile'
4
4
 
5
5
  module Appraisal
6
6
  # Loads and parses Appraisals file
7
- class File
7
+ class AppraisalFile
8
8
  attr_reader :appraisals, :gemfile
9
9
 
10
10
  def self.each(&block)
@@ -16,7 +16,7 @@ module Appraisal
16
16
  @gemfile = Gemfile.new
17
17
  @gemfile.load(ENV['BUNDLE_GEMFILE'] || 'Gemfile')
18
18
 
19
- if ::File.exist? path
19
+ if File.exist? path
20
20
  run IO.read(path)
21
21
  else
22
22
  raise AppraisalsNotFound
@@ -1,22 +1,23 @@
1
1
  require "appraisal/dependency_list"
2
- require "active_support/ordered_hash"
3
2
 
4
3
  module Appraisal
5
4
  class BundlerDSL
6
5
  attr_reader :dependencies
7
6
 
8
- PARTS = %w(source ruby_version git_sources path_sources dependencies groups
9
- platforms gemspec)
7
+ PARTS = %w(source ruby_version gits paths dependencies groups
8
+ platforms source_blocks gemspec)
10
9
 
11
10
  def initialize
12
11
  @sources = []
13
12
  @ruby_version = nil
14
13
  @dependencies = DependencyList.new
15
- @gemspec = nil
16
- @groups = ActiveSupport::OrderedHash.new
17
- @platforms = ActiveSupport::OrderedHash.new
18
- @git_sources = ActiveSupport::OrderedHash.new
19
- @path_sources = ActiveSupport::OrderedHash.new
14
+ @gemspecs = []
15
+ @groups = Hash.new
16
+ @platforms = Hash.new
17
+ @gits = Hash.new
18
+ @paths = Hash.new
19
+ @source_blocks = Hash.new
20
+ @git_sources = {}
20
21
  end
21
22
 
22
23
  def run(&block)
@@ -24,23 +25,31 @@ module Appraisal
24
25
  end
25
26
 
26
27
  def gem(name, *requirements)
27
- @dependencies.add(name, requirements)
28
+ @dependencies.add(name, substitute_git_source(requirements))
28
29
  end
29
30
 
30
31
  def group(*names, &block)
31
- @groups[names] ||= Group.new(names)
32
+ @groups[names] ||=
33
+ Group.new(names).tap { |g| g.git_sources = @git_sources.dup }
32
34
  @groups[names].run(&block)
33
35
  end
34
36
 
35
37
  def platforms(*names, &block)
36
- @platforms[names] ||= Platform.new(names)
38
+ @platforms[names] ||=
39
+ Platform.new(names).tap { |g| g.git_sources = @git_sources.dup }
37
40
  @platforms[names].run(&block)
38
41
  end
39
42
 
40
43
  alias_method :platform, :platforms
41
44
 
42
- def source(source)
43
- @sources << source
45
+ def source(source, &block)
46
+ if block_given?
47
+ @source_blocks[source] ||=
48
+ Source.new(source).tap { |g| g.git_sources = @git_sources.dup }
49
+ @source_blocks[source].run(&block)
50
+ else
51
+ @sources << source
52
+ end
44
53
  end
45
54
 
46
55
  def ruby(ruby_version)
@@ -48,13 +57,15 @@ module Appraisal
48
57
  end
49
58
 
50
59
  def git(source, options = {}, &block)
51
- @git_sources[source] ||= GitSource.new(source, options)
52
- @git_sources[source].run(&block)
60
+ @gits[source] ||=
61
+ Git.new(source, options).tap { |g| g.git_sources = @git_sources.dup }
62
+ @gits[source].run(&block)
53
63
  end
54
64
 
55
65
  def path(source, options = {}, &block)
56
- @path_sources[source] ||= PathSource.new(source, options)
57
- @path_sources[source].run(&block)
66
+ @paths[source] ||=
67
+ Path.new(source, options).tap { |g| g.git_sources = @git_sources.dup }
68
+ @paths[source].run(&block)
58
69
  end
59
70
 
60
71
  def to_s
@@ -66,9 +77,17 @@ module Appraisal
66
77
  end
67
78
 
68
79
  def gemspec(options = {})
69
- @gemspec = Gemspec.new(options)
80
+ @gemspecs << Gemspec.new(options)
81
+ end
82
+
83
+ def git_source(source, &block)
84
+ @git_sources[source] = block
70
85
  end
71
86
 
87
+ protected
88
+
89
+ attr_writer :git_sources
90
+
72
91
  private
73
92
 
74
93
  def source_entry
@@ -85,25 +104,24 @@ module Appraisal
85
104
 
86
105
  alias_method :ruby_version_entry_for_dup, :ruby_version_entry
87
106
 
88
- [:dependencies, :gemspec].each do |method_name|
89
- class_eval <<-METHODS, __FILE__, __LINE__
90
- private
107
+ def gemspec_entry
108
+ @gemspecs.map(&:to_s).join("\n")
109
+ end
91
110
 
92
- def #{method_name}_entry
93
- if @#{method_name}
94
- @#{method_name}.to_s
95
- end
96
- end
111
+ def gemspec_entry_for_dup
112
+ @gemspecs.map(&:for_dup).join("\n")
113
+ end
97
114
 
98
- def #{method_name}_entry_for_dup
99
- if @#{method_name}
100
- @#{method_name}.for_dup
101
- end
102
- end
103
- METHODS
115
+ def dependencies_entry
116
+ @dependencies.to_s
117
+ end
118
+
119
+ def dependencies_entry_for_dup
120
+ @dependencies.for_dup
104
121
  end
105
122
 
106
- [:git_sources, :path_sources, :platforms, :groups].each do |method_name|
123
+ [:gits, :paths, :platforms, :groups, :source_blocks].
124
+ each do |method_name|
107
125
  class_eval <<-METHODS, __FILE__, __LINE__
108
126
  private
109
127
 
@@ -120,5 +138,16 @@ module Appraisal
120
138
  def indent(string)
121
139
  string.strip.gsub(/^(.+)$/, ' \1')
122
140
  end
141
+
142
+ def substitute_git_source(requirements)
143
+ requirements.each do |requirement|
144
+ if requirement.is_a?(Hash)
145
+ (requirement.keys & @git_sources.keys).each do |matching_source|
146
+ value = requirement.delete(matching_source)
147
+ requirement[:git] = @git_sources[matching_source].call(value)
148
+ end
149
+ end
150
+ end
151
+ end
123
152
  end
124
153
  end