appraisal2 3.0.0 → 3.0.1
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 +4 -4
- checksums.yaml.gz.sig +0 -0
- data/CHANGELOG.md +75 -5
- data/README.md +294 -19
- data/lib/appraisal/appraisal.rb +8 -56
- data/lib/appraisal/appraisal_file.rb +4 -2
- data/lib/appraisal/cli.rb +18 -3
- data/lib/appraisal/customize.rb +31 -23
- data/lib/appraisal/errors.rb +21 -0
- data/lib/appraisal/gem_manager/base.rb +51 -0
- data/lib/appraisal/gem_manager/bundler_adapter.rb +86 -0
- data/lib/appraisal/gem_manager/factory.rb +54 -0
- data/lib/appraisal/gem_manager/ore_adapter.rb +104 -0
- data/lib/appraisal/gem_manager.rb +11 -0
- data/lib/appraisal/version.rb +4 -1
- data.tar.gz.sig +0 -0
- metadata +182 -9
- metadata.gz.sig +0 -0
data/lib/appraisal/appraisal.rb
CHANGED
|
@@ -9,12 +9,11 @@ require "appraisal/gemfile"
|
|
|
9
9
|
require "appraisal/command"
|
|
10
10
|
require "appraisal/customize"
|
|
11
11
|
require "appraisal/utils"
|
|
12
|
+
require "appraisal/gem_manager"
|
|
12
13
|
|
|
13
14
|
module Appraisal
|
|
14
15
|
# Represents one appraisal and its dependencies
|
|
15
16
|
class Appraisal
|
|
16
|
-
DEFAULT_INSTALL_OPTIONS = {"jobs" => 1}.freeze
|
|
17
|
-
|
|
18
17
|
attr_reader :name, :gemfile
|
|
19
18
|
|
|
20
19
|
def initialize(name, source_gemfile)
|
|
@@ -79,22 +78,15 @@ module Appraisal
|
|
|
79
78
|
end
|
|
80
79
|
|
|
81
80
|
def install(options = {})
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
command = commands.join(" || ")
|
|
87
|
-
|
|
88
|
-
if Bundler.settings[:path]
|
|
89
|
-
env = {"BUNDLE_DISABLE_SHARED_GEMS" => "1"}
|
|
90
|
-
Command.new(command, :env => env).run
|
|
91
|
-
else
|
|
92
|
-
Command.new(command).run
|
|
93
|
-
end
|
|
81
|
+
gem_manager = options.delete(:gem_manager) || options.delete("gem_manager") ||
|
|
82
|
+
options.delete(:"gem-manager") || options.delete("gem-manager")
|
|
83
|
+
manager = GemManager::Factory.create(gemfile_path, project_root, :manager => gem_manager)
|
|
84
|
+
manager.install(options)
|
|
94
85
|
end
|
|
95
86
|
|
|
96
|
-
def update(gems = [])
|
|
97
|
-
|
|
87
|
+
def update(gems = [], gem_manager: nil)
|
|
88
|
+
manager = GemManager::Factory.create(gemfile_path, project_root, :manager => gem_manager)
|
|
89
|
+
manager.update(gems)
|
|
98
90
|
end
|
|
99
91
|
|
|
100
92
|
def gemfile_path
|
|
@@ -122,20 +114,6 @@ module Appraisal
|
|
|
122
114
|
|
|
123
115
|
private
|
|
124
116
|
|
|
125
|
-
def check_command
|
|
126
|
-
gemfile_option = "--gemfile='#{gemfile_path}'"
|
|
127
|
-
["bundle", "check", gemfile_option]
|
|
128
|
-
end
|
|
129
|
-
|
|
130
|
-
def install_command(options = {})
|
|
131
|
-
gemfile_option = "--gemfile='#{gemfile_path}'"
|
|
132
|
-
["bundle", "install", gemfile_option, bundle_options(options)].compact
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
def update_command(gems)
|
|
136
|
-
["bundle", "update", *gems].compact
|
|
137
|
-
end
|
|
138
|
-
|
|
139
117
|
def gemfile_root
|
|
140
118
|
project_root + "gemfiles"
|
|
141
119
|
end
|
|
@@ -156,32 +134,6 @@ module Appraisal
|
|
|
156
134
|
name.gsub(/[^\w.]/, "_")
|
|
157
135
|
end
|
|
158
136
|
|
|
159
|
-
def bundle_options(options)
|
|
160
|
-
full_options = DEFAULT_INSTALL_OPTIONS.dup.merge(options)
|
|
161
|
-
options_strings = []
|
|
162
|
-
jobs = full_options.delete("jobs")
|
|
163
|
-
if jobs > 1
|
|
164
|
-
if Utils.support_parallel_installation?
|
|
165
|
-
options_strings << "--jobs=#{jobs}"
|
|
166
|
-
else
|
|
167
|
-
warn("Your current version of Bundler does not support parallel installation. Please " \
|
|
168
|
-
"upgrade Bundler to version >= 1.4.0, or invoke `appraisal` without `--jobs` option.")
|
|
169
|
-
end
|
|
170
|
-
end
|
|
171
|
-
|
|
172
|
-
path = full_options.delete("path")
|
|
173
|
-
if path
|
|
174
|
-
relative_path = project_root.join(options["path"])
|
|
175
|
-
options_strings << "--path #{relative_path}"
|
|
176
|
-
end
|
|
177
|
-
|
|
178
|
-
full_options.each do |flag, val|
|
|
179
|
-
options_strings << "--#{flag} #{val}"
|
|
180
|
-
end
|
|
181
|
-
|
|
182
|
-
options_strings.join(" ") if options_strings != []
|
|
183
|
-
end
|
|
184
|
-
|
|
185
137
|
def comment_lines(heading)
|
|
186
138
|
heading.lines.map do |line|
|
|
187
139
|
if line.lstrip.empty?
|
data/lib/appraisal/cli.rb
CHANGED
|
@@ -8,6 +8,12 @@ module Appraisal
|
|
|
8
8
|
default_task :install
|
|
9
9
|
map ["-v", "--version"] => "version"
|
|
10
10
|
|
|
11
|
+
class_option "gem-manager",
|
|
12
|
+
:aliases => "-g",
|
|
13
|
+
:type => :string,
|
|
14
|
+
:default => "bundler",
|
|
15
|
+
:desc => "Gem manager to use for install/update (bundler or ore)"
|
|
16
|
+
|
|
11
17
|
class << self
|
|
12
18
|
# Override help command to print out usage
|
|
13
19
|
def help(shell, subcommand = false)
|
|
@@ -74,8 +80,9 @@ module Appraisal
|
|
|
74
80
|
def install
|
|
75
81
|
invoke(:generate, [], {})
|
|
76
82
|
|
|
83
|
+
install_options = options.to_h
|
|
77
84
|
AppraisalFile.each do |appraisal|
|
|
78
|
-
appraisal.install(
|
|
85
|
+
appraisal.install(install_options)
|
|
79
86
|
appraisal.relativize
|
|
80
87
|
end
|
|
81
88
|
end
|
|
@@ -94,10 +101,11 @@ module Appraisal
|
|
|
94
101
|
|
|
95
102
|
desc "update [LIST_OF_GEMS]", "Remove all generated gemfiles and lockfiles, resolve, and install dependencies again"
|
|
96
103
|
def update(*gems)
|
|
97
|
-
invoke(:generate, [])
|
|
104
|
+
invoke(:generate, [], {})
|
|
98
105
|
|
|
106
|
+
gem_manager = options["gem-manager"] || options[:gem_manager]
|
|
99
107
|
AppraisalFile.each do |appraisal|
|
|
100
|
-
appraisal.update(gems)
|
|
108
|
+
appraisal.update(gems, :gem_manager => gem_manager)
|
|
101
109
|
end
|
|
102
110
|
end
|
|
103
111
|
|
|
@@ -126,5 +134,12 @@ module Appraisal
|
|
|
126
134
|
end
|
|
127
135
|
end
|
|
128
136
|
end
|
|
137
|
+
|
|
138
|
+
def respond_to_missing?(name, include_private = false)
|
|
139
|
+
appraisals = AppraisalFile.new.appraisals
|
|
140
|
+
appraisals.any? { |appraisal| appraisal.name == name.to_s } || super
|
|
141
|
+
rescue AppraisalsNotFound
|
|
142
|
+
super
|
|
143
|
+
end
|
|
129
144
|
end
|
|
130
145
|
end
|
data/lib/appraisal/customize.rb
CHANGED
|
@@ -9,32 +9,40 @@ module Appraisal
|
|
|
9
9
|
@@single_quotes = single_quotes
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
class << self
|
|
13
|
+
def heading(gemfile = nil)
|
|
14
|
+
@@heading ||= nil
|
|
15
|
+
return @@heading unless gemfile
|
|
15
16
|
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
customize(@@heading, gemfile)
|
|
18
|
+
end
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
def single_quotes
|
|
21
|
+
@@single_quotes ||= false
|
|
22
|
+
end
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
|
24
|
+
# Reset class state - useful for testing
|
|
25
|
+
def reset!
|
|
26
|
+
@@heading = nil
|
|
27
|
+
@@single_quotes = false
|
|
28
|
+
end
|
|
37
29
|
|
|
38
|
-
|
|
30
|
+
private
|
|
31
|
+
|
|
32
|
+
def customize(topper, gemfile)
|
|
33
|
+
return unless topper
|
|
34
|
+
|
|
35
|
+
format(
|
|
36
|
+
topper.to_s,
|
|
37
|
+
:appraisal => gemfile.send(:clean_name),
|
|
38
|
+
:gemfile => gemfile.send(:gemfile_name),
|
|
39
|
+
:gemfile_path => gemfile.gemfile_path,
|
|
40
|
+
:lockfile => "#{gemfile.send(:gemfile_name)}.lock",
|
|
41
|
+
:lockfile_path => gemfile.send(:lockfile_path),
|
|
42
|
+
:relative_gemfile_path => gemfile.relative_gemfile_path,
|
|
43
|
+
:relative_lockfile_path => "#{gemfile.relative_gemfile_path}.lock",
|
|
44
|
+
)
|
|
45
|
+
end
|
|
46
|
+
end
|
|
39
47
|
end
|
|
40
48
|
end
|
data/lib/appraisal/errors.rb
CHANGED
|
@@ -7,4 +7,25 @@ module Appraisal
|
|
|
7
7
|
"Unable to locate 'Appraisals' file in the current directory."
|
|
8
8
|
end
|
|
9
9
|
end
|
|
10
|
+
|
|
11
|
+
# Raises when ore-light gem manager is requested but not installed.
|
|
12
|
+
class OreNotAvailableError < ArgumentError
|
|
13
|
+
def message
|
|
14
|
+
"ore-light is not installed or not in PATH. " \
|
|
15
|
+
"Install from: https://github.com/contriboss/ore-light"
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Raises when an unknown gem manager is requested.
|
|
20
|
+
class UnknownGemManagerError < ArgumentError
|
|
21
|
+
def initialize(manager, available)
|
|
22
|
+
@manager = manager
|
|
23
|
+
@available = available
|
|
24
|
+
super()
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def message
|
|
28
|
+
"Unknown gem manager: '#{@manager}'. Available: #{@available.join(", ")}"
|
|
29
|
+
end
|
|
30
|
+
end
|
|
10
31
|
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Appraisal
|
|
4
|
+
module GemManager
|
|
5
|
+
# Abstract base class defining the interface for gem managers.
|
|
6
|
+
# Subclasses must implement all public methods.
|
|
7
|
+
class Base
|
|
8
|
+
attr_reader :gemfile_path, :project_root
|
|
9
|
+
|
|
10
|
+
# @param gemfile_path [String] path to the gemfile
|
|
11
|
+
# @param project_root [Pathname] root directory of the project
|
|
12
|
+
def initialize(gemfile_path, project_root)
|
|
13
|
+
@gemfile_path = gemfile_path
|
|
14
|
+
@project_root = project_root
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# Install gems for the given gemfile
|
|
18
|
+
# @param options [Hash] install options (jobs, retry, without, path, etc.)
|
|
19
|
+
# @return [void]
|
|
20
|
+
def install(options = {})
|
|
21
|
+
raise NotImplementedError, "#{self.class}#install must be implemented"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Update gems (all or specific gems)
|
|
25
|
+
# @param gems [Array<String>] list of gems to update, empty = all
|
|
26
|
+
# @return [void]
|
|
27
|
+
def update(gems = [])
|
|
28
|
+
raise NotImplementedError, "#{self.class}#update must be implemented"
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Name of the gem manager for display
|
|
32
|
+
# @return [String]
|
|
33
|
+
def name
|
|
34
|
+
raise NotImplementedError, "#{self.class}#name must be implemented"
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Check if the gem manager is available on the system
|
|
38
|
+
# @return [Boolean]
|
|
39
|
+
def available?
|
|
40
|
+
raise NotImplementedError, "#{self.class}#available? must be implemented"
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Validate that the gem manager is available, raising an error if not
|
|
44
|
+
# @raise [OreNotAvailableError] if ore is not available
|
|
45
|
+
# @return [void]
|
|
46
|
+
def validate_availability!
|
|
47
|
+
# Default implementation does nothing (bundler is always available)
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "base"
|
|
4
|
+
|
|
5
|
+
module Appraisal
|
|
6
|
+
module GemManager
|
|
7
|
+
# Bundler adapter for gem management operations.
|
|
8
|
+
# This is the default gem manager and is always available.
|
|
9
|
+
class BundlerAdapter < Base
|
|
10
|
+
DEFAULT_INSTALL_OPTIONS = {"jobs" => 1}.freeze
|
|
11
|
+
|
|
12
|
+
def name
|
|
13
|
+
"bundler"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def available?
|
|
17
|
+
true # Bundler is always available (it's a dependency of appraisal2)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def install(options = {})
|
|
21
|
+
commands = [install_command(options).join(" ")]
|
|
22
|
+
|
|
23
|
+
# Only run check command if not using --without option
|
|
24
|
+
if options["without"].nil? || options["without"].empty?
|
|
25
|
+
commands.unshift(check_command.join(" "))
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
command = commands.join(" || ")
|
|
29
|
+
|
|
30
|
+
if Bundler.settings[:path]
|
|
31
|
+
env = {"BUNDLE_DISABLE_SHARED_GEMS" => "1"}
|
|
32
|
+
Command.new(command, :gemfile => gemfile_path, :env => env).run
|
|
33
|
+
else
|
|
34
|
+
Command.new(command, :gemfile => gemfile_path).run
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def update(gems = [])
|
|
39
|
+
Command.new(update_command(gems), :gemfile => gemfile_path).run
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
private
|
|
43
|
+
|
|
44
|
+
def check_command
|
|
45
|
+
gemfile_option = "--gemfile='#{gemfile_path}'"
|
|
46
|
+
["bundle", "check", gemfile_option]
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def install_command(options = {})
|
|
50
|
+
gemfile_option = "--gemfile='#{gemfile_path}'"
|
|
51
|
+
["bundle", "install", gemfile_option, bundle_options(options)].compact
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def update_command(gems)
|
|
55
|
+
["bundle", "update", *gems].compact
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def bundle_options(options)
|
|
59
|
+
full_options = DEFAULT_INSTALL_OPTIONS.dup.merge(options)
|
|
60
|
+
options_strings = []
|
|
61
|
+
|
|
62
|
+
jobs = full_options.delete("jobs")
|
|
63
|
+
if jobs > 1
|
|
64
|
+
if Utils.support_parallel_installation?
|
|
65
|
+
options_strings << "--jobs=#{jobs}"
|
|
66
|
+
else
|
|
67
|
+
warn("Your current version of Bundler does not support parallel installation. Please " \
|
|
68
|
+
"upgrade Bundler to version >= 1.4.0, or invoke `appraisal` without `--jobs` option.")
|
|
69
|
+
end
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
path = full_options.delete("path")
|
|
73
|
+
if path
|
|
74
|
+
relative_path = project_root.join(options["path"])
|
|
75
|
+
options_strings << "--path #{relative_path}"
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
full_options.each do |flag, val|
|
|
79
|
+
options_strings << "--#{flag} #{val}"
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
options_strings.join(" ") if options_strings != []
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
end
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "bundler_adapter"
|
|
4
|
+
require_relative "ore_adapter"
|
|
5
|
+
|
|
6
|
+
module Appraisal
|
|
7
|
+
module GemManager
|
|
8
|
+
# Factory for creating gem manager adapters.
|
|
9
|
+
# Raises errors for unknown or unavailable gem managers.
|
|
10
|
+
class Factory
|
|
11
|
+
ADAPTERS = {
|
|
12
|
+
"bundler" => BundlerAdapter,
|
|
13
|
+
"ore" => OreAdapter,
|
|
14
|
+
}.freeze
|
|
15
|
+
|
|
16
|
+
DEFAULT_MANAGER = "bundler"
|
|
17
|
+
|
|
18
|
+
class << self
|
|
19
|
+
# Create a gem manager adapter
|
|
20
|
+
# @param gemfile_path [String] path to the gemfile
|
|
21
|
+
# @param project_root [Pathname] root directory of the project
|
|
22
|
+
# @param manager [String, nil] gem manager name (bundler or ore)
|
|
23
|
+
# @return [Base] gem manager adapter instance
|
|
24
|
+
# @raise [UnknownGemManagerError] if manager is not recognized
|
|
25
|
+
# @raise [OreNotAvailableError] if ore is requested but not installed
|
|
26
|
+
def create(gemfile_path, project_root, manager: nil)
|
|
27
|
+
manager_name = normalize_manager_name(manager)
|
|
28
|
+
|
|
29
|
+
adapter_class = ADAPTERS.fetch(manager_name) do
|
|
30
|
+
raise UnknownGemManagerError.new(manager_name, ADAPTERS.keys)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
adapter = adapter_class.new(gemfile_path, project_root)
|
|
34
|
+
adapter.validate_availability!
|
|
35
|
+
adapter
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# List of available gem manager names
|
|
39
|
+
# @return [Array<String>]
|
|
40
|
+
def available_managers
|
|
41
|
+
ADAPTERS.keys
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
private
|
|
45
|
+
|
|
46
|
+
def normalize_manager_name(manager)
|
|
47
|
+
return DEFAULT_MANAGER if manager.nil? || manager.to_s.strip.empty?
|
|
48
|
+
|
|
49
|
+
manager.to_s.strip.downcase
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
54
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "base"
|
|
4
|
+
|
|
5
|
+
module Appraisal
|
|
6
|
+
module GemManager
|
|
7
|
+
# Ore-light adapter for gem management operations.
|
|
8
|
+
# Ore-light is a fast, Go-based alternative to Bundler for gem installation.
|
|
9
|
+
# See: https://github.com/contriboss/ore-light
|
|
10
|
+
class OreAdapter < Base
|
|
11
|
+
ORE_EXECUTABLE = "ore"
|
|
12
|
+
|
|
13
|
+
def name
|
|
14
|
+
"ore"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def available?
|
|
18
|
+
system("which #{ORE_EXECUTABLE} > /dev/null 2>&1")
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def validate_availability!
|
|
22
|
+
raise OreNotAvailableError unless available?
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def install(options = {})
|
|
26
|
+
validate_availability!
|
|
27
|
+
|
|
28
|
+
lockfile = "#{gemfile_path}.lock"
|
|
29
|
+
|
|
30
|
+
# Run ore lock first if lockfile doesn't exist
|
|
31
|
+
unless File.exist?(lockfile)
|
|
32
|
+
lock_command = [ORE_EXECUTABLE, "lock", "-gemfile", gemfile_path]
|
|
33
|
+
run_ore_command(lock_command)
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
command = install_command(options)
|
|
37
|
+
run_ore_command(command)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def update(gems = [])
|
|
41
|
+
validate_availability!
|
|
42
|
+
|
|
43
|
+
command = update_command(gems)
|
|
44
|
+
run_ore_command(command)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
private
|
|
48
|
+
|
|
49
|
+
def install_command(options = {})
|
|
50
|
+
cmd = [ORE_EXECUTABLE, "install"]
|
|
51
|
+
|
|
52
|
+
# Map bundler options to ore options
|
|
53
|
+
# Ore uses -workers instead of --jobs
|
|
54
|
+
jobs = options["jobs"]
|
|
55
|
+
cmd << "-workers=#{jobs}" if jobs && jobs > 1
|
|
56
|
+
|
|
57
|
+
# Ore uses -without with comma-separated groups
|
|
58
|
+
without = options["without"]
|
|
59
|
+
if without && !without.empty?
|
|
60
|
+
# Convert space-separated to comma-separated
|
|
61
|
+
groups = without.split(/\s+/).join(",")
|
|
62
|
+
cmd << "-without=#{groups}"
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# Ore uses -vendor instead of --path
|
|
66
|
+
path = options["path"]
|
|
67
|
+
if path
|
|
68
|
+
relative_path = project_root.join(path)
|
|
69
|
+
cmd << "-vendor=#{relative_path}"
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
# Ore uses -lockfile to specify the lockfile path
|
|
73
|
+
cmd << "-lockfile=#{gemfile_path}.lock"
|
|
74
|
+
|
|
75
|
+
# Note: Ore does not support --retry, so we ignore that option
|
|
76
|
+
|
|
77
|
+
cmd
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def update_command(gems)
|
|
81
|
+
cmd = [ORE_EXECUTABLE, "update", "-gemfile", gemfile_path]
|
|
82
|
+
cmd.concat(gems) if gems.any?
|
|
83
|
+
cmd
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def run_ore_command(command)
|
|
87
|
+
puts ">> BUNDLE_GEMFILE=#{gemfile_path} #{command.join(" ")}"
|
|
88
|
+
|
|
89
|
+
# Ore resolves path dependencies relative to the current working directory,
|
|
90
|
+
# not relative to the gemfile location. We need to cd to the gemfile's
|
|
91
|
+
# directory so that relative paths like "../appraisal2" resolve correctly.
|
|
92
|
+
gemfile_dir = File.dirname(gemfile_path)
|
|
93
|
+
|
|
94
|
+
Bundler.with_original_env do
|
|
95
|
+
ENV["BUNDLE_GEMFILE"] = gemfile_path
|
|
96
|
+
ENV["APPRAISAL_INITIALIZED"] = "1"
|
|
97
|
+
Dir.chdir(gemfile_dir) do
|
|
98
|
+
exit(1) unless Kernel.system(*command)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "errors"
|
|
4
|
+
require_relative "gem_manager/factory"
|
|
5
|
+
|
|
6
|
+
module Appraisal
|
|
7
|
+
# Gem manager abstraction layer.
|
|
8
|
+
# Supports multiple gem managers (bundler, ore-light) via adapter pattern.
|
|
9
|
+
module GemManager
|
|
10
|
+
end
|
|
11
|
+
end
|
data/lib/appraisal/version.rb
CHANGED
data.tar.gz.sig
CHANGED
|
Binary file
|