bundler 1.6.0.pre.1 → 1.6.0.pre.2
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.
Potentially problematic release.
This version of bundler might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +17 -3
- data/Rakefile +12 -7
- data/lib/bundler.rb +3 -3
- data/lib/bundler/cli.rb +36 -619
- data/lib/bundler/cli/binstubs.rb +36 -0
- data/lib/bundler/cli/cache.rb +34 -0
- data/lib/bundler/cli/check.rb +35 -0
- data/lib/bundler/cli/clean.rb +19 -0
- data/lib/bundler/cli/common.rb +54 -0
- data/lib/bundler/cli/config.rb +84 -0
- data/lib/bundler/cli/console.rb +42 -0
- data/lib/bundler/cli/exec.rb +37 -0
- data/lib/bundler/cli/gem.rb +61 -0
- data/lib/bundler/cli/init.rb +33 -0
- data/lib/bundler/cli/inject.rb +33 -0
- data/lib/bundler/cli/install.rb +123 -0
- data/lib/bundler/cli/open.rb +25 -0
- data/lib/bundler/cli/outdated.rb +80 -0
- data/lib/bundler/cli/package.rb +36 -0
- data/lib/bundler/cli/platform.rb +43 -0
- data/lib/bundler/cli/show.rb +44 -0
- data/lib/bundler/cli/update.rb +73 -0
- data/lib/bundler/cli/viz.rb +27 -0
- data/lib/bundler/dsl.rb +46 -26
- data/lib/bundler/fetcher.rb +50 -4
- data/lib/bundler/installer.rb +1 -1
- data/lib/bundler/parallel_workers/worker.rb +1 -1
- data/lib/bundler/remote_specification.rb +1 -1
- data/lib/bundler/resolver.rb +30 -18
- data/lib/bundler/source/git.rb +0 -4
- data/lib/bundler/source/git/git_proxy.rb +2 -2
- data/lib/bundler/source/rubygems.rb +1 -14
- data/lib/bundler/templates/newgem/spec/newgem_spec.rb.tt +1 -1
- data/lib/bundler/vendor/thor/base.rb +1 -1
- data/lib/bundler/version.rb +1 -1
- data/spec/bundler/bundler_spec.rb +46 -47
- data/spec/bundler/{cli_rspec.rb → cli_spec.rb} +0 -1
- data/spec/bundler/definition_spec.rb +3 -7
- data/spec/bundler/dsl_spec.rb +43 -21
- data/spec/bundler/gem_helper_spec.rb +152 -123
- data/spec/bundler/retry_spec.rb +6 -7
- data/spec/bundler/settings_spec.rb +0 -2
- data/spec/bundler/source_spec.rb +4 -4
- data/spec/commands/newgem_spec.rb +7 -7
- data/spec/commands/outdated_spec.rb +11 -0
- data/spec/install/gems/dependency_api_spec.rb +41 -0
- data/spec/install/gems/simple_case_spec.rb +1 -17
- data/spec/other/ext_spec.rb +1 -1
- data/spec/support/artifice/endpoint_strict_basic_authentication.rb +18 -0
- data/spec/support/builders.rb +43 -42
- data/spec/support/permissions.rb +0 -1
- data/spec/update/gems_spec.rb +11 -0
- metadata +51 -30
@@ -0,0 +1,36 @@
|
|
1
|
+
module Bundler
|
2
|
+
class CLI::Binstubs
|
3
|
+
attr_reader :options, :gems
|
4
|
+
def initialize(options, gems)
|
5
|
+
@options = options
|
6
|
+
@gems = gems
|
7
|
+
end
|
8
|
+
|
9
|
+
def run
|
10
|
+
Bundler.definition.validate_ruby!
|
11
|
+
Bundler.settings[:bin] = options["path"] if options["path"]
|
12
|
+
Bundler.settings[:bin] = nil if options["path"] && options["path"].empty?
|
13
|
+
installer = Installer.new(Bundler.root, Bundler.definition)
|
14
|
+
|
15
|
+
if gems.empty?
|
16
|
+
Bundler.ui.error "`bundle binstubs` needs at least one gem to run."
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
gems.each do |gem_name|
|
21
|
+
spec = installer.specs.find{|s| s.name == gem_name }
|
22
|
+
unless spec
|
23
|
+
raise GemNotFound, Bundler::CLI::Common.gem_not_found_message(
|
24
|
+
gem_name, Bundler.definition.specs)
|
25
|
+
end
|
26
|
+
|
27
|
+
if spec.name == "bundler"
|
28
|
+
Bundler.ui.warn "Sorry, Bundler can only be run via Rubygems."
|
29
|
+
else
|
30
|
+
installer.generate_bundler_executable_stubs(spec, :force => options[:force], :binstubs_cmd => true)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Bundler
|
2
|
+
class CLI::Cache
|
3
|
+
attr_reader :options
|
4
|
+
def initialize(options)
|
5
|
+
@options = options
|
6
|
+
end
|
7
|
+
|
8
|
+
def run
|
9
|
+
Bundler.definition.validate_ruby!
|
10
|
+
Bundler.definition.resolve_with_cache!
|
11
|
+
setup_cache_all
|
12
|
+
Bundler.load.cache
|
13
|
+
Bundler.settings[:no_prune] = true if options["no-prune"]
|
14
|
+
Bundler.load.lock
|
15
|
+
rescue GemNotFound => e
|
16
|
+
Bundler.ui.error(e.message)
|
17
|
+
Bundler.ui.warn "Run `bundle install` to install missing gems."
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def setup_cache_all
|
24
|
+
Bundler.settings[:cache_all] = options[:all] if options.key?("all")
|
25
|
+
|
26
|
+
if Bundler.definition.sources.any? { |s| !s.is_a?(Source::Rubygems) } && !Bundler.settings[:cache_all]
|
27
|
+
Bundler.ui.warn "Your Gemfile contains path and git dependencies. If you want " \
|
28
|
+
"to package them as well, please pass the --all flag. This will be the default " \
|
29
|
+
"on Bundler 2.0."
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Bundler
|
2
|
+
class CLI::Check
|
3
|
+
attr_reader :options
|
4
|
+
def initialize(options)
|
5
|
+
@options = options
|
6
|
+
end
|
7
|
+
|
8
|
+
def run
|
9
|
+
Bundler.settings[:path] = File.expand_path(options[:path]) if options[:path]
|
10
|
+
begin
|
11
|
+
definition = Bundler.definition
|
12
|
+
definition.validate_ruby!
|
13
|
+
not_installed = definition.missing_specs
|
14
|
+
rescue GemNotFound, VersionConflict
|
15
|
+
Bundler.ui.error "Bundler can't satisfy your Gemfile's dependencies."
|
16
|
+
Bundler.ui.warn "Install missing gems with `bundle install`."
|
17
|
+
exit 1
|
18
|
+
end
|
19
|
+
|
20
|
+
if not_installed.any?
|
21
|
+
Bundler.ui.error "The following gems are missing"
|
22
|
+
not_installed.each { |s| Bundler.ui.error " * #{s.name} (#{s.version})" }
|
23
|
+
Bundler.ui.warn "Install missing gems with `bundle install`"
|
24
|
+
exit 1
|
25
|
+
elsif !Bundler.default_lockfile.exist? && Bundler.settings[:frozen]
|
26
|
+
Bundler.ui.error "This bundle has been frozen, but there is no Gemfile.lock present"
|
27
|
+
exit 1
|
28
|
+
else
|
29
|
+
Bundler.load.lock unless options[:"dry-run"]
|
30
|
+
Bundler.ui.info "The Gemfile's dependencies are satisfied"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Bundler
|
2
|
+
class CLI::Clean
|
3
|
+
attr_reader :options
|
4
|
+
|
5
|
+
def initialize(options)
|
6
|
+
@options = options
|
7
|
+
end
|
8
|
+
|
9
|
+
def run
|
10
|
+
if Bundler.settings[:path] || options[:force]
|
11
|
+
Bundler.load.clean(options[:"dry-run"])
|
12
|
+
else
|
13
|
+
Bundler.ui.error "Can only use bundle clean when --path is set or --force is set"
|
14
|
+
exit 1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Bundler
|
2
|
+
module CLI::Common
|
3
|
+
def self.without_groups_message
|
4
|
+
groups = Bundler.settings.without
|
5
|
+
group_list = [groups[0...-1].join(", "), groups[-1..-1]].
|
6
|
+
reject{|s| s.to_s.empty? }.join(" and ")
|
7
|
+
group_str = (groups.size == 1) ? "group" : "groups"
|
8
|
+
"Gems in the #{group_str} #{group_list} were not installed."
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.select_spec(name, regex_match = nil)
|
12
|
+
specs = []
|
13
|
+
regexp = Regexp.new(name) if regex_match
|
14
|
+
|
15
|
+
Bundler.definition.specs.each do |spec|
|
16
|
+
return spec if spec.name == name
|
17
|
+
specs << spec if regexp && spec.name =~ regexp
|
18
|
+
end
|
19
|
+
|
20
|
+
case specs.count
|
21
|
+
when 0
|
22
|
+
raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
|
23
|
+
when 1
|
24
|
+
specs.first
|
25
|
+
else
|
26
|
+
ask_for_spec_from(specs)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.ask_for_spec_from(specs)
|
31
|
+
if !$stdout.tty? && ENV['BUNDLE_SPEC_RUN'].nil?
|
32
|
+
raise GemNotFound, gem_not_found_message(name, Bundler.definition.dependencies)
|
33
|
+
end
|
34
|
+
|
35
|
+
specs.each_with_index do |spec, index|
|
36
|
+
Bundler.ui.info "#{index.succ} : #{spec.name}", true
|
37
|
+
end
|
38
|
+
Bundler.ui.info '0 : - exit -', true
|
39
|
+
|
40
|
+
num = Bundler.ui.ask('> ').to_i
|
41
|
+
num > 0 ? specs[num - 1] : nil
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.gem_not_found_message(missing_gem_name, alternatives)
|
45
|
+
require 'bundler/similarity_detector'
|
46
|
+
message = "Could not find gem '#{missing_gem_name}'."
|
47
|
+
alternate_names = alternatives.map { |a| a.respond_to?(:name) ? a.name : a }
|
48
|
+
suggestions = SimilarityDetector.new(alternate_names).similar_word_list(missing_gem_name)
|
49
|
+
message += "\nDid you mean #{suggestions}?" if suggestions
|
50
|
+
message
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
module Bundler
|
2
|
+
class CLI::Config
|
3
|
+
attr_reader :options, :thor
|
4
|
+
attr_accessor :args
|
5
|
+
|
6
|
+
def initialize(options, args, thor)
|
7
|
+
@options = options
|
8
|
+
@args = args
|
9
|
+
@thor = thor
|
10
|
+
end
|
11
|
+
|
12
|
+
def run
|
13
|
+
peek = args.shift
|
14
|
+
|
15
|
+
if peek && peek =~ /^\-\-/
|
16
|
+
name, scope = args.shift, $'
|
17
|
+
else
|
18
|
+
name, scope = peek, "global"
|
19
|
+
end
|
20
|
+
|
21
|
+
unless name
|
22
|
+
Bundler.ui.confirm "Settings are listed in order of priority. The top value will be used.\n"
|
23
|
+
|
24
|
+
Bundler.settings.all.each do |setting|
|
25
|
+
Bundler.ui.confirm "#{setting}"
|
26
|
+
thor.with_padding do
|
27
|
+
Bundler.settings.pretty_values_for(setting).each do |line|
|
28
|
+
Bundler.ui.info line
|
29
|
+
end
|
30
|
+
end
|
31
|
+
Bundler.ui.confirm ""
|
32
|
+
end
|
33
|
+
return
|
34
|
+
end
|
35
|
+
|
36
|
+
case scope
|
37
|
+
when "delete"
|
38
|
+
Bundler.settings.set_local(name, nil)
|
39
|
+
Bundler.settings.set_global(name, nil)
|
40
|
+
when "local", "global"
|
41
|
+
if args.empty?
|
42
|
+
Bundler.ui.confirm "Settings for `#{name}` in order of priority. The top value will be used"
|
43
|
+
thor.with_padding do
|
44
|
+
Bundler.settings.pretty_values_for(name).each { |line| Bundler.ui.info line }
|
45
|
+
end
|
46
|
+
return
|
47
|
+
end
|
48
|
+
|
49
|
+
locations = Bundler.settings.locations(name)
|
50
|
+
|
51
|
+
if scope == "global"
|
52
|
+
if local = locations[:local]
|
53
|
+
Bundler.ui.info "Your application has set #{name} to #{local.inspect}. This will override the " \
|
54
|
+
"global value you are currently setting"
|
55
|
+
end
|
56
|
+
|
57
|
+
if env = locations[:env]
|
58
|
+
Bundler.ui.info "You have a bundler environment variable for #{name} set to #{env.inspect}. " \
|
59
|
+
"This will take precedence over the global value you are setting"
|
60
|
+
end
|
61
|
+
|
62
|
+
if global = locations[:global]
|
63
|
+
Bundler.ui.info "You are replacing the current global value of #{name}, which is currently #{global.inspect}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
if scope == "local" && local = locations[:local]
|
68
|
+
Bundler.ui.info "You are replacing the current local value of #{name}, which is currently #{local.inspect}"
|
69
|
+
end
|
70
|
+
|
71
|
+
if name.match(/\Alocal\./)
|
72
|
+
pathname = Pathname.new(args.join(" "))
|
73
|
+
self.args = [pathname.expand_path.to_s] if pathname.directory?
|
74
|
+
end
|
75
|
+
|
76
|
+
Bundler.settings.send("set_#{scope}", name, args.join(" "))
|
77
|
+
else
|
78
|
+
Bundler.ui.error "Invalid scope --#{scope} given. Please use --local or --global."
|
79
|
+
exit 1
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Bundler
|
2
|
+
class CLI::Console
|
3
|
+
attr_reader :options, :group, :consoles
|
4
|
+
def initialize(options, group, consoles)
|
5
|
+
@options = options
|
6
|
+
@group = group
|
7
|
+
@consoles = consoles
|
8
|
+
end
|
9
|
+
|
10
|
+
def run
|
11
|
+
group ? Bundler.require(:default, *(group.split.map! {|g| g.to_sym })) : Bundler.require
|
12
|
+
ARGV.clear
|
13
|
+
|
14
|
+
preferred = Bundler.settings[:console] || 'irb'
|
15
|
+
|
16
|
+
# See if console is available
|
17
|
+
begin
|
18
|
+
require preferred || true
|
19
|
+
rescue LoadError
|
20
|
+
# Is it in Gemfile?
|
21
|
+
Bundler.ui.error "Could not load the #{preferred} console"
|
22
|
+
Bundler.ui.info "Falling back on IRB..."
|
23
|
+
|
24
|
+
require 'irb'
|
25
|
+
preferred = 'irb'
|
26
|
+
end
|
27
|
+
|
28
|
+
constant = consoles[preferred]
|
29
|
+
|
30
|
+
console = begin
|
31
|
+
Object.const_get(constant)
|
32
|
+
rescue NameError => e
|
33
|
+
Bundler.ui.error e.inspect
|
34
|
+
Bundler.ui.error "Could not load the #{constant} console"
|
35
|
+
return
|
36
|
+
end
|
37
|
+
|
38
|
+
console.start
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Bundler
|
2
|
+
class CLI::Exec
|
3
|
+
attr_reader :options, :args
|
4
|
+
|
5
|
+
def initialize(options, args)
|
6
|
+
@options = options
|
7
|
+
@args = args
|
8
|
+
end
|
9
|
+
|
10
|
+
def run
|
11
|
+
Bundler.definition.validate_ruby!
|
12
|
+
Bundler.load.setup_environment
|
13
|
+
|
14
|
+
begin
|
15
|
+
if RUBY_VERSION >= "2.0"
|
16
|
+
@args << { :close_others => !options.keep_file_descriptors? }
|
17
|
+
elsif options.keep_file_descriptors?
|
18
|
+
Bundler.ui.warn "Ruby version #{RUBY_VERSION} defaults to keeping non-standard file descriptors on Kernel#exec."
|
19
|
+
end
|
20
|
+
|
21
|
+
# Run
|
22
|
+
Kernel.exec(*args)
|
23
|
+
rescue Errno::EACCES
|
24
|
+
Bundler.ui.error "bundler: not executable: #{args.first}"
|
25
|
+
exit 126
|
26
|
+
rescue Errno::ENOENT
|
27
|
+
Bundler.ui.error "bundler: command not found: #{args.first}"
|
28
|
+
Bundler.ui.warn "Install missing gem executables with `bundle install`"
|
29
|
+
exit 127
|
30
|
+
rescue ArgumentError
|
31
|
+
Bundler.ui.error "bundler: exec needs a command to run"
|
32
|
+
exit 128
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module Bundler
|
2
|
+
class CLI::Gem
|
3
|
+
attr_reader :options, :gem_name, :thor
|
4
|
+
def initialize(options, gem_name, thor)
|
5
|
+
@options = options
|
6
|
+
@gem_name = gem_name
|
7
|
+
@thor = thor
|
8
|
+
end
|
9
|
+
|
10
|
+
def run
|
11
|
+
name = gem_name.chomp("/") # remove trailing slash if present
|
12
|
+
namespaced_path = name.tr('-', '/')
|
13
|
+
target = File.join(Dir.pwd, name)
|
14
|
+
constant_name = name.split('_').map{|p| p[0..0].upcase + p[1..-1] }.join
|
15
|
+
constant_name = constant_name.split('-').map{|q| q[0..0].upcase + q[1..-1] }.join('::') if constant_name =~ /-/
|
16
|
+
constant_array = constant_name.split('::')
|
17
|
+
git_user_name = `git config user.name`.chomp
|
18
|
+
git_user_email = `git config user.email`.chomp
|
19
|
+
opts = {
|
20
|
+
:name => name,
|
21
|
+
:namespaced_path => namespaced_path,
|
22
|
+
:constant_name => constant_name,
|
23
|
+
:constant_array => constant_array,
|
24
|
+
:author => git_user_name.empty? ? "TODO: Write your name" : git_user_name,
|
25
|
+
:email => git_user_email.empty? ? "TODO: Write your email address" : git_user_email,
|
26
|
+
:test => options[:test]
|
27
|
+
}
|
28
|
+
gemspec_dest = File.join(target, "#{name}.gemspec")
|
29
|
+
thor.template(File.join("newgem/Gemfile.tt"), File.join(target, "Gemfile"), opts)
|
30
|
+
thor.template(File.join("newgem/Rakefile.tt"), File.join(target, "Rakefile"), opts)
|
31
|
+
thor.template(File.join("newgem/LICENSE.txt.tt"), File.join(target, "LICENSE.txt"), opts)
|
32
|
+
thor.template(File.join("newgem/README.md.tt"), File.join(target, "README.md"), opts)
|
33
|
+
thor.template(File.join("newgem/gitignore.tt"), File.join(target, ".gitignore"), opts)
|
34
|
+
thor.template(File.join("newgem/newgem.gemspec.tt"), gemspec_dest, opts)
|
35
|
+
thor.template(File.join("newgem/lib/newgem.rb.tt"), File.join(target, "lib/#{namespaced_path}.rb"), opts)
|
36
|
+
thor.template(File.join("newgem/lib/newgem/version.rb.tt"), File.join(target, "lib/#{namespaced_path}/version.rb"), opts)
|
37
|
+
if options[:bin]
|
38
|
+
thor.template(File.join("newgem/bin/newgem.tt"), File.join(target, 'bin', name), opts)
|
39
|
+
end
|
40
|
+
case options[:test]
|
41
|
+
when 'rspec'
|
42
|
+
thor.template(File.join("newgem/rspec.tt"), File.join(target, ".rspec"), opts)
|
43
|
+
thor.template(File.join("newgem/spec/spec_helper.rb.tt"), File.join(target, "spec/spec_helper.rb"), opts)
|
44
|
+
thor.template(File.join("newgem/spec/newgem_spec.rb.tt"), File.join(target, "spec/#{namespaced_path}_spec.rb"), opts)
|
45
|
+
when 'minitest'
|
46
|
+
thor.template(File.join("newgem/test/minitest_helper.rb.tt"), File.join(target, "test/minitest_helper.rb"), opts)
|
47
|
+
thor.template(File.join("newgem/test/test_newgem.rb.tt"), File.join(target, "test/test_#{namespaced_path}.rb"), opts)
|
48
|
+
end
|
49
|
+
if options[:test]
|
50
|
+
thor.template(File.join("newgem/.travis.yml.tt"), File.join(target, ".travis.yml"), opts)
|
51
|
+
end
|
52
|
+
Bundler.ui.info "Initializing git repo in #{target}"
|
53
|
+
Dir.chdir(target) { `git init`; `git add .` }
|
54
|
+
|
55
|
+
if options[:edit]
|
56
|
+
thor.run("#{options["edit"]} \"#{gemspec_dest}\"") # Open gemspec in editor
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Bundler
|
2
|
+
class CLI::Init
|
3
|
+
attr_reader :options
|
4
|
+
def initialize(options)
|
5
|
+
@options = options
|
6
|
+
end
|
7
|
+
|
8
|
+
def run
|
9
|
+
if File.exist?("Gemfile")
|
10
|
+
Bundler.ui.error "Gemfile already exists at #{Dir.pwd}/Gemfile"
|
11
|
+
exit 1
|
12
|
+
end
|
13
|
+
|
14
|
+
if options[:gemspec]
|
15
|
+
gemspec = File.expand_path(options[:gemspec])
|
16
|
+
unless File.exist?(gemspec)
|
17
|
+
Bundler.ui.error "Gem specification #{gemspec} doesn't exist"
|
18
|
+
exit 1
|
19
|
+
end
|
20
|
+
spec = Gem::Specification.load(gemspec)
|
21
|
+
puts "Writing new Gemfile to #{Dir.pwd}/Gemfile"
|
22
|
+
File.open('Gemfile', 'wb') do |file|
|
23
|
+
file << "# Generated from #{gemspec}\n"
|
24
|
+
file << spec.to_gemfile
|
25
|
+
end
|
26
|
+
else
|
27
|
+
puts "Writing new Gemfile to #{Dir.pwd}/Gemfile"
|
28
|
+
FileUtils.cp(File.expand_path('../../templates/Gemfile', __FILE__), 'Gemfile')
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|