appraisal2 3.0.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.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +28 -0
- data/CODE_OF_CONDUCT.md +135 -0
- data/CONTRIBUTING.md +136 -0
- data/LICENSE.txt +22 -0
- data/README.md +700 -0
- data/SECURITY.md +21 -0
- data/exe/appraisal +14 -0
- data/lib/appraisal/appraisal.rb +201 -0
- data/lib/appraisal/appraisal_file.rb +52 -0
- data/lib/appraisal/bundler_dsl.rb +209 -0
- data/lib/appraisal/cli.rb +130 -0
- data/lib/appraisal/command.rb +94 -0
- data/lib/appraisal/conditional.rb +32 -0
- data/lib/appraisal/customize.rb +40 -0
- data/lib/appraisal/dependency.rb +51 -0
- data/lib/appraisal/dependency_list.rb +38 -0
- data/lib/appraisal/errors.rb +10 -0
- data/lib/appraisal/gemfile.rb +31 -0
- data/lib/appraisal/gemspec.rb +31 -0
- data/lib/appraisal/git.rb +47 -0
- data/lib/appraisal/group.rb +32 -0
- data/lib/appraisal/ordered_hash.rb +22 -0
- data/lib/appraisal/path.rb +47 -0
- data/lib/appraisal/platform.rb +32 -0
- data/lib/appraisal/source.rb +32 -0
- data/lib/appraisal/task.rb +56 -0
- data/lib/appraisal/utils.rb +71 -0
- data/lib/appraisal/version.rb +5 -0
- data/lib/appraisal.rb +5 -0
- data/lib/appraisal2.rb +6 -0
- data.tar.gz.sig +0 -0
- metadata +268 -0
- metadata.gz.sig +0 -0
@@ -0,0 +1,94 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "shellwords"
|
4
|
+
|
5
|
+
module Appraisal
|
6
|
+
# Executes commands with a clean environment
|
7
|
+
class Command
|
8
|
+
attr_reader :command, :env, :gemfile
|
9
|
+
|
10
|
+
def initialize(command, options = {})
|
11
|
+
@gemfile = options[:gemfile]
|
12
|
+
@env = options.fetch(:env, {})
|
13
|
+
@command = command_starting_with_bundle(command)
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
run_env = test_environment.merge(env)
|
18
|
+
|
19
|
+
Bundler.with_original_env do
|
20
|
+
ensure_bundler_is_available
|
21
|
+
announce
|
22
|
+
|
23
|
+
ENV["BUNDLE_GEMFILE"] = gemfile
|
24
|
+
ENV["APPRAISAL_INITIALIZED"] = "1"
|
25
|
+
run_env.each_pair do |key, value|
|
26
|
+
ENV[key] = value
|
27
|
+
end
|
28
|
+
|
29
|
+
exit(1) unless Kernel.system(command_as_string)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def ensure_bundler_is_available
|
36
|
+
version = Utils.bundler_version
|
37
|
+
return if system(%(gem list --silent -i bundler -v #{version}))
|
38
|
+
|
39
|
+
puts ">> Reinstall Bundler into #{ENV["GEM_HOME"]}"
|
40
|
+
|
41
|
+
return if system("gem install bundler --version #{version}")
|
42
|
+
|
43
|
+
puts
|
44
|
+
puts <<-ERROR.rstrip
|
45
|
+
Bundler installation failed.
|
46
|
+
Please try running:
|
47
|
+
`GEM_HOME="#{ENV["GEM_HOME"]}" gem install bundler --version #{version}`
|
48
|
+
manually.
|
49
|
+
ERROR
|
50
|
+
exit(1)
|
51
|
+
end
|
52
|
+
|
53
|
+
def announce
|
54
|
+
if gemfile
|
55
|
+
puts ">> BUNDLE_GEMFILE=#{gemfile} #{command_as_string}"
|
56
|
+
else
|
57
|
+
puts ">> #{command_as_string}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def command_starts_with_bundle?(original_command)
|
62
|
+
if original_command.is_a?(Array)
|
63
|
+
original_command.first =~ /^bundle/
|
64
|
+
else
|
65
|
+
original_command =~ /^bundle/
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def command_starting_with_bundle(original_command)
|
70
|
+
if command_starts_with_bundle?(original_command)
|
71
|
+
original_command
|
72
|
+
else
|
73
|
+
%w[bundle exec] + original_command
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def command_as_string
|
78
|
+
if command.is_a?(Array)
|
79
|
+
Shellwords.join(command)
|
80
|
+
else
|
81
|
+
command
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_environment
|
86
|
+
return {} unless ENV["APPRAISAL_UNDER_TEST"] == "1"
|
87
|
+
|
88
|
+
{
|
89
|
+
"GEM_HOME" => ENV["GEM_HOME"],
|
90
|
+
"GEM_PATH" => "",
|
91
|
+
}
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "appraisal/bundler_dsl"
|
4
|
+
require "appraisal/utils"
|
5
|
+
|
6
|
+
module Appraisal
|
7
|
+
class Conditional < BundlerDSL
|
8
|
+
def initialize(condition)
|
9
|
+
super()
|
10
|
+
@condition = condition
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
<<-OUTPUT.rstrip
|
15
|
+
install_if #{@condition} do
|
16
|
+
#{indent(super)}
|
17
|
+
end
|
18
|
+
OUTPUT
|
19
|
+
end
|
20
|
+
|
21
|
+
# :nodoc:
|
22
|
+
def for_dup
|
23
|
+
return unless @condition.is_a?(String)
|
24
|
+
|
25
|
+
<<-OUTPUT.rstrip
|
26
|
+
install_if #{@condition} do
|
27
|
+
#{indent(super)}
|
28
|
+
end
|
29
|
+
OUTPUT
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Appraisal
|
4
|
+
class Customize
|
5
|
+
def initialize(options = {})
|
6
|
+
heading = options.fetch(:heading, nil)
|
7
|
+
single_quotes = options.fetch(:single_quotes, false)
|
8
|
+
@@heading = !heading.nil? && heading.chomp
|
9
|
+
@@single_quotes = single_quotes
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.heading(gemfile = nil)
|
13
|
+
@@heading ||= nil
|
14
|
+
return @@heading unless gemfile
|
15
|
+
|
16
|
+
customize(@@heading, gemfile)
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.single_quotes
|
20
|
+
@@single_quotes ||= false
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.customize(topper, gemfile)
|
24
|
+
return unless topper
|
25
|
+
|
26
|
+
format(
|
27
|
+
topper.to_s,
|
28
|
+
:appraisal => gemfile.send(:clean_name),
|
29
|
+
:gemfile => gemfile.send(:gemfile_name),
|
30
|
+
:gemfile_path => gemfile.gemfile_path,
|
31
|
+
:lockfile => "#{gemfile.send(:gemfile_name)}.lock",
|
32
|
+
:lockfile_path => gemfile.send(:lockfile_path),
|
33
|
+
:relative_gemfile_path => gemfile.relative_gemfile_path,
|
34
|
+
:relative_lockfile_path => "#{gemfile.relative_gemfile_path}.lock",
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
private_class_method :customize
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "appraisal/utils"
|
4
|
+
|
5
|
+
module Appraisal
|
6
|
+
# Dependency on a gem and optional version requirements
|
7
|
+
class Dependency
|
8
|
+
attr_accessor :requirements
|
9
|
+
attr_reader :name
|
10
|
+
|
11
|
+
def initialize(name, requirements)
|
12
|
+
@name = name
|
13
|
+
@requirements = requirements
|
14
|
+
end
|
15
|
+
|
16
|
+
def to_s
|
17
|
+
formatted_output(Utils.format_arguments(path_prefixed_requirements))
|
18
|
+
end
|
19
|
+
|
20
|
+
# :nodoc:
|
21
|
+
def for_dup
|
22
|
+
formatted_output(Utils.format_arguments(requirements))
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def path_prefixed_requirements
|
28
|
+
requirements.map do |requirement|
|
29
|
+
if requirement.is_a?(Hash)
|
30
|
+
requirement[:path] = Utils.prefix_path(requirement[:path]) if requirement[:path]
|
31
|
+
|
32
|
+
requirement[:git] = Utils.prefix_path(requirement[:git]) if requirement[:git]
|
33
|
+
end
|
34
|
+
|
35
|
+
requirement
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def formatted_output(output_requirements)
|
40
|
+
[gem_name, output_requirements].compact.join(", ")
|
41
|
+
end
|
42
|
+
|
43
|
+
def gem_name
|
44
|
+
%(gem "#{name}")
|
45
|
+
end
|
46
|
+
|
47
|
+
def no_requirements?
|
48
|
+
requirements.nil? || requirements.empty?
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Std libs
|
4
|
+
require "set"
|
5
|
+
|
6
|
+
# This gem
|
7
|
+
require "appraisal/dependency"
|
8
|
+
require "appraisal/ordered_hash"
|
9
|
+
|
10
|
+
module Appraisal
|
11
|
+
class DependencyList
|
12
|
+
def initialize
|
13
|
+
@dependencies = OrderedHash.new
|
14
|
+
@removed_dependencies = Set.new
|
15
|
+
end
|
16
|
+
|
17
|
+
def add(name, requirements)
|
18
|
+
return if @removed_dependencies.include?(name)
|
19
|
+
|
20
|
+
@dependencies[name] = Dependency.new(name, requirements)
|
21
|
+
end
|
22
|
+
|
23
|
+
def remove(name)
|
24
|
+
return unless @removed_dependencies.add?(name)
|
25
|
+
|
26
|
+
@dependencies.delete(name)
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
@dependencies.values.map(&:to_s).join("\n")
|
31
|
+
end
|
32
|
+
|
33
|
+
# :nodoc:
|
34
|
+
def for_dup
|
35
|
+
@dependencies.values.map(&:for_dup).join("\n")
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Appraisal
|
4
|
+
# Raises when Appraisal is unable to locate Appraisals file in the current directory.
|
5
|
+
class AppraisalsNotFound < StandardError
|
6
|
+
def message
|
7
|
+
"Unable to locate 'Appraisals' file in the current directory."
|
8
|
+
end
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "appraisal/bundler_dsl"
|
4
|
+
|
5
|
+
module Appraisal
|
6
|
+
autoload :Gemspec, "appraisal/gemspec"
|
7
|
+
autoload :Git, "appraisal/git"
|
8
|
+
autoload :Group, "appraisal/group"
|
9
|
+
autoload :Path, "appraisal/path"
|
10
|
+
autoload :Platform, "appraisal/platform"
|
11
|
+
autoload :Source, "appraisal/source"
|
12
|
+
autoload :Conditional, "appraisal/conditional"
|
13
|
+
|
14
|
+
# Load bundler Gemfiles and merge dependencies
|
15
|
+
class Gemfile < BundlerDSL
|
16
|
+
def load(path)
|
17
|
+
run(File.read(path), path) if File.exist?(path)
|
18
|
+
end
|
19
|
+
|
20
|
+
def run(definitions, path, line = 1)
|
21
|
+
instance_eval(definitions, path, line) if definitions
|
22
|
+
end
|
23
|
+
|
24
|
+
def dup
|
25
|
+
Gemfile.new.tap do |gemfile|
|
26
|
+
gemfile.git_sources = @git_sources
|
27
|
+
gemfile.run(for_dup, __FILE__, __LINE__)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "appraisal/utils"
|
4
|
+
|
5
|
+
module Appraisal
|
6
|
+
class Gemspec
|
7
|
+
attr_reader :options
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
@options = options
|
11
|
+
@options[:path] ||= "."
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
"gemspec #{Utils.format_string(exported_options)}"
|
16
|
+
end
|
17
|
+
|
18
|
+
# :nodoc:
|
19
|
+
def for_dup
|
20
|
+
"gemspec #{Utils.format_string(@options)}"
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def exported_options
|
26
|
+
@options.merge(
|
27
|
+
:path => Utils.prefix_path(@options[:path]),
|
28
|
+
)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "appraisal/bundler_dsl"
|
4
|
+
require "appraisal/utils"
|
5
|
+
|
6
|
+
module Appraisal
|
7
|
+
class Git < BundlerDSL
|
8
|
+
def initialize(source, options = {})
|
9
|
+
super()
|
10
|
+
@source = source
|
11
|
+
@options = options
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
if @options.empty?
|
16
|
+
<<-OUTPUT.rstrip
|
17
|
+
git #{Utils.prefix_path(@source).inspect} do
|
18
|
+
#{indent(super)}
|
19
|
+
end
|
20
|
+
OUTPUT
|
21
|
+
else
|
22
|
+
<<-OUTPUT.rstrip
|
23
|
+
git #{Utils.prefix_path(@source).inspect}, #{Utils.format_string(@options)} do
|
24
|
+
#{indent(super)}
|
25
|
+
end
|
26
|
+
OUTPUT
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# :nodoc:
|
31
|
+
def for_dup
|
32
|
+
if @options.empty?
|
33
|
+
<<-OUTPUT.rstrip
|
34
|
+
git #{@source.inspect} do
|
35
|
+
#{indent(super)}
|
36
|
+
end
|
37
|
+
OUTPUT
|
38
|
+
else
|
39
|
+
<<-OUTPUT.rstrip
|
40
|
+
git #{@source.inspect}, #{Utils.format_string(@options)} do
|
41
|
+
#{indent(super)}
|
42
|
+
end
|
43
|
+
OUTPUT
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "appraisal/bundler_dsl"
|
4
|
+
require "appraisal/utils"
|
5
|
+
|
6
|
+
module Appraisal
|
7
|
+
class Group < BundlerDSL
|
8
|
+
def initialize(group_names)
|
9
|
+
super()
|
10
|
+
@group_names = group_names
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
formatted_output(super)
|
15
|
+
end
|
16
|
+
|
17
|
+
# :nodoc:
|
18
|
+
def for_dup
|
19
|
+
formatted_output(super)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def formatted_output(output_dependencies)
|
25
|
+
<<-OUTPUT.rstrip
|
26
|
+
group #{Utils.format_arguments(@group_names)} do
|
27
|
+
#{indent(output_dependencies)}
|
28
|
+
end
|
29
|
+
OUTPUT
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module Appraisal
|
2
|
+
# An ordered hash implementation for Ruby 1.8.7 compatibility. This is not
|
3
|
+
# a complete implementation, but it covers Appraisal's specific needs.
|
4
|
+
class OrderedHash < ::Hash
|
5
|
+
# Hashes are ordered in Ruby 1.9.
|
6
|
+
if RUBY_VERSION < "1.9"
|
7
|
+
def initialize(*args, &block)
|
8
|
+
super
|
9
|
+
@keys = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def []=(key, value)
|
13
|
+
@keys << key unless has_key?(key)
|
14
|
+
super
|
15
|
+
end
|
16
|
+
|
17
|
+
def values
|
18
|
+
@keys.collect { |key| self[key] }
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "appraisal/bundler_dsl"
|
4
|
+
require "appraisal/utils"
|
5
|
+
|
6
|
+
module Appraisal
|
7
|
+
class Path < BundlerDSL
|
8
|
+
def initialize(source, options = {})
|
9
|
+
super()
|
10
|
+
@source = source
|
11
|
+
@options = options
|
12
|
+
end
|
13
|
+
|
14
|
+
def to_s
|
15
|
+
if @options.empty?
|
16
|
+
<<-OUTPUT.rstrip
|
17
|
+
path #{Utils.prefix_path(@source).inspect} do
|
18
|
+
#{indent(super)}
|
19
|
+
end
|
20
|
+
OUTPUT
|
21
|
+
else
|
22
|
+
<<-OUTPUT.rstrip
|
23
|
+
path #{Utils.prefix_path(@source).inspect}, #{Utils.format_string(@options)} do
|
24
|
+
#{indent(super)}
|
25
|
+
end"
|
26
|
+
OUTPUT
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
# :nodoc:
|
31
|
+
def for_dup
|
32
|
+
if @options.empty?
|
33
|
+
<<-OUTPUT.rstrip
|
34
|
+
path #{@source.inspect} do
|
35
|
+
#{indent(super)}
|
36
|
+
end
|
37
|
+
OUTPUT
|
38
|
+
else
|
39
|
+
<<-OUTPUT.rstrip
|
40
|
+
path #{@source.inspect}, #{Utils.format_string(@options)} do
|
41
|
+
#{indent(super)}
|
42
|
+
end
|
43
|
+
OUTPUT
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "appraisal/bundler_dsl"
|
4
|
+
require "appraisal/utils"
|
5
|
+
|
6
|
+
module Appraisal
|
7
|
+
class Platform < BundlerDSL
|
8
|
+
def initialize(platform_names)
|
9
|
+
super()
|
10
|
+
@platform_names = platform_names
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
formatted_output(super)
|
15
|
+
end
|
16
|
+
|
17
|
+
# :nodoc:
|
18
|
+
def for_dup
|
19
|
+
formatted_output(super)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def formatted_output(output_dependencies)
|
25
|
+
<<-OUTPUT.rstrip
|
26
|
+
platforms #{Utils.format_arguments(@platform_names)} do
|
27
|
+
#{indent(output_dependencies)}
|
28
|
+
end
|
29
|
+
OUTPUT
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "appraisal/bundler_dsl"
|
4
|
+
require "appraisal/utils"
|
5
|
+
|
6
|
+
module Appraisal
|
7
|
+
class Source < BundlerDSL
|
8
|
+
def initialize(source)
|
9
|
+
super()
|
10
|
+
@source = source
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
formatted_output(super)
|
15
|
+
end
|
16
|
+
|
17
|
+
# :nodoc:
|
18
|
+
def for_dup
|
19
|
+
formatted_output(super)
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def formatted_output(output_dependencies)
|
25
|
+
<<-OUTPUT.rstrip
|
26
|
+
source #{@source.inspect} do
|
27
|
+
#{indent(output_dependencies)}
|
28
|
+
end
|
29
|
+
OUTPUT
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "appraisal/appraisal_file"
|
4
|
+
require "rake/tasklib"
|
5
|
+
|
6
|
+
module Appraisal
|
7
|
+
# Defines tasks for installing appraisal dependencies and running other tasks
|
8
|
+
# for a given appraisal.
|
9
|
+
class Task < Rake::TaskLib
|
10
|
+
def initialize
|
11
|
+
namespace(:appraisal) do
|
12
|
+
desc("DEPRECATED: Generate a Gemfile for each appraisal")
|
13
|
+
task(:gemfiles) do
|
14
|
+
warn("`rake appraisal:gemfile` task is deprecated and will be removed soon. " \
|
15
|
+
"Please use `appraisal generate`.")
|
16
|
+
exec("bundle exec appraisal generate")
|
17
|
+
end
|
18
|
+
|
19
|
+
desc("DEPRECATED: Resolve and install dependencies for each appraisal")
|
20
|
+
task(:install) do
|
21
|
+
warn("`rake appraisal:install` task is deprecated and will be removed soon. " \
|
22
|
+
"Please use `appraisal install`.")
|
23
|
+
exec("bundle exec appraisal install")
|
24
|
+
end
|
25
|
+
|
26
|
+
desc("DEPRECATED: Remove all generated gemfiles from gemfiles/ folder")
|
27
|
+
task(:cleanup) do
|
28
|
+
warn("`rake appraisal:cleanup` task is deprecated and will be removed soon. " \
|
29
|
+
"Please use `appraisal clean`.")
|
30
|
+
exec("bundle exec appraisal clean")
|
31
|
+
end
|
32
|
+
|
33
|
+
begin
|
34
|
+
AppraisalFile.each do |appraisal|
|
35
|
+
desc("DEPRECATED: Run the given task for appraisal #{appraisal.name}")
|
36
|
+
task(appraisal.name) do
|
37
|
+
ARGV.shift
|
38
|
+
warn("`rake appraisal:#{appraisal.name}` task is deprecated and will be removed soon. " \
|
39
|
+
"Please use `appraisal #{appraisal.name} rake #{ARGV.join(" ")}`.")
|
40
|
+
exec("bundle exec appraisal #{appraisal.name} rake #{ARGV.join(" ")}")
|
41
|
+
end
|
42
|
+
end
|
43
|
+
rescue AppraisalsNotFound
|
44
|
+
end
|
45
|
+
|
46
|
+
task(:all) do
|
47
|
+
ARGV.shift
|
48
|
+
exec("bundle exec appraisal rake #{ARGV.join(" ")}")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
desc("Run the given task for all appraisals")
|
53
|
+
task(:appraisal => "appraisal:all")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Appraisal
|
4
|
+
# Contains methods for various operations
|
5
|
+
module Utils
|
6
|
+
class << self
|
7
|
+
def support_parallel_installation?
|
8
|
+
Gem::Version.create(Bundler::VERSION) >= Gem::Version.create("1.4.0.pre.1")
|
9
|
+
end
|
10
|
+
|
11
|
+
def support_git_local_installation?
|
12
|
+
Gem::Version.create(Bundler::VERSION) > Gem::Version.create("2.4.22")
|
13
|
+
end
|
14
|
+
|
15
|
+
# Appraisal needs to print Gemfiles in the oldest Ruby syntax that is supported by Appraisal.
|
16
|
+
# Otherwise, a project would not be able to use Appraisal to test compatibility
|
17
|
+
# with older versions of Ruby, which is a core use case for Appraisal.
|
18
|
+
def format_string(object, enclosing_object = false)
|
19
|
+
case object
|
20
|
+
when Hash
|
21
|
+
items = object.map do |key, value|
|
22
|
+
format_hash_value(key, value)
|
23
|
+
end
|
24
|
+
|
25
|
+
if enclosing_object
|
26
|
+
"{ #{items.join(", ")} }"
|
27
|
+
else
|
28
|
+
items.join(", ")
|
29
|
+
end
|
30
|
+
else
|
31
|
+
object.inspect
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
# Appraisal needs to print Gemfiles in the oldest Ruby syntax that is supported by Appraisal.
|
36
|
+
# This means formatting Hashes as Rockets, until support for Ruby 1.8 is dropped.
|
37
|
+
# Regardless of what Ruby is used to generate appraisals,
|
38
|
+
# generated appraisals may need to run on a different Ruby version.
|
39
|
+
# Generated appraisals should use a syntax compliant with the oldest supported Ruby version.
|
40
|
+
def format_hash_value(key, value)
|
41
|
+
key = format_string(key, true)
|
42
|
+
value = format_string(value, true)
|
43
|
+
|
44
|
+
"#{key} => #{value}"
|
45
|
+
end
|
46
|
+
|
47
|
+
def format_arguments(arguments)
|
48
|
+
return if arguments.empty?
|
49
|
+
|
50
|
+
arguments.map { |object| format_string(object, false) }.join(", ")
|
51
|
+
end
|
52
|
+
|
53
|
+
def join_parts(parts)
|
54
|
+
parts.reject(&:nil?).reject(&:empty?).join("\n\n").rstrip
|
55
|
+
end
|
56
|
+
|
57
|
+
def prefix_path(path)
|
58
|
+
if path !~ /^(?:\/|\S:)/ && path !~ /^\S+:\/\// && path !~ /^\S+@\S+:/
|
59
|
+
cleaned_path = path.gsub(/(^|\/)\.(?:\/|$)/, "\\1")
|
60
|
+
File.join("..", cleaned_path)
|
61
|
+
else
|
62
|
+
path
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def bundler_version
|
67
|
+
Gem::Specification.detect { |spec| spec.name == "bundler" }.version.to_s
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/appraisal.rb
ADDED