honkster-bundler 1.1.pre
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.
- data/.gitignore +14 -0
- data/CHANGELOG.md +547 -0
- data/ISSUES.md +32 -0
- data/LICENSE +20 -0
- data/README.md +29 -0
- data/Rakefile +150 -0
- data/UPGRADING.md +103 -0
- data/bin/bundle +21 -0
- data/bundler.gemspec +30 -0
- data/lib/bundler.rb +268 -0
- data/lib/bundler/capistrano.rb +11 -0
- data/lib/bundler/cli.rb +515 -0
- data/lib/bundler/definition.rb +427 -0
- data/lib/bundler/dependency.rb +114 -0
- data/lib/bundler/deployment.rb +37 -0
- data/lib/bundler/dsl.rb +245 -0
- data/lib/bundler/environment.rb +47 -0
- data/lib/bundler/gem_helper.rb +145 -0
- data/lib/bundler/graph.rb +130 -0
- data/lib/bundler/index.rb +114 -0
- data/lib/bundler/installer.rb +84 -0
- data/lib/bundler/lazy_specification.rb +71 -0
- data/lib/bundler/lockfile_parser.rb +108 -0
- data/lib/bundler/remote_specification.rb +59 -0
- data/lib/bundler/resolver.rb +454 -0
- data/lib/bundler/rubygems_ext.rb +203 -0
- data/lib/bundler/runtime.rb +148 -0
- data/lib/bundler/settings.rb +117 -0
- data/lib/bundler/setup.rb +15 -0
- data/lib/bundler/shared_helpers.rb +151 -0
- data/lib/bundler/source.rb +662 -0
- data/lib/bundler/spec_set.rb +134 -0
- data/lib/bundler/templates/Executable +16 -0
- data/lib/bundler/templates/Gemfile +4 -0
- data/lib/bundler/templates/newgem/Gemfile.tt +4 -0
- data/lib/bundler/templates/newgem/Rakefile.tt +2 -0
- data/lib/bundler/templates/newgem/bin/newgem.tt +3 -0
- data/lib/bundler/templates/newgem/gitignore.tt +3 -0
- data/lib/bundler/templates/newgem/lib/newgem.rb.tt +7 -0
- data/lib/bundler/templates/newgem/lib/newgem/version.rb.tt +7 -0
- data/lib/bundler/templates/newgem/newgem.gemspec.tt +21 -0
- data/lib/bundler/ui.rb +60 -0
- data/lib/bundler/vendor/thor.rb +319 -0
- data/lib/bundler/vendor/thor/actions.rb +297 -0
- data/lib/bundler/vendor/thor/actions/create_file.rb +105 -0
- data/lib/bundler/vendor/thor/actions/directory.rb +93 -0
- data/lib/bundler/vendor/thor/actions/empty_directory.rb +134 -0
- data/lib/bundler/vendor/thor/actions/file_manipulation.rb +229 -0
- data/lib/bundler/vendor/thor/actions/inject_into_file.rb +104 -0
- data/lib/bundler/vendor/thor/base.rb +556 -0
- data/lib/bundler/vendor/thor/core_ext/file_binary_read.rb +9 -0
- data/lib/bundler/vendor/thor/core_ext/hash_with_indifferent_access.rb +75 -0
- data/lib/bundler/vendor/thor/core_ext/ordered_hash.rb +100 -0
- data/lib/bundler/vendor/thor/error.rb +30 -0
- data/lib/bundler/vendor/thor/invocation.rb +168 -0
- data/lib/bundler/vendor/thor/parser.rb +4 -0
- data/lib/bundler/vendor/thor/parser/argument.rb +67 -0
- data/lib/bundler/vendor/thor/parser/arguments.rb +161 -0
- data/lib/bundler/vendor/thor/parser/option.rb +120 -0
- data/lib/bundler/vendor/thor/parser/options.rb +174 -0
- data/lib/bundler/vendor/thor/shell.rb +88 -0
- data/lib/bundler/vendor/thor/shell/basic.rb +275 -0
- data/lib/bundler/vendor/thor/shell/color.rb +108 -0
- data/lib/bundler/vendor/thor/shell/html.rb +121 -0
- data/lib/bundler/vendor/thor/task.rb +114 -0
- data/lib/bundler/vendor/thor/util.rb +229 -0
- data/lib/bundler/vendor/thor/version.rb +3 -0
- data/lib/bundler/version.rb +6 -0
- data/lib/bundler/vlad.rb +9 -0
- data/man/bundle-config.ronn +90 -0
- data/man/bundle-exec.ronn +98 -0
- data/man/bundle-install.ronn +310 -0
- data/man/bundle-package.ronn +59 -0
- data/man/bundle-update.ronn +176 -0
- data/man/bundle.ronn +77 -0
- data/man/gemfile.5.ronn +273 -0
- data/man/index.txt +6 -0
- data/spec/cache/gems_spec.rb +205 -0
- data/spec/cache/git_spec.rb +9 -0
- data/spec/cache/path_spec.rb +27 -0
- data/spec/cache/platform_spec.rb +57 -0
- data/spec/install/deploy_spec.rb +197 -0
- data/spec/install/deprecated_spec.rb +43 -0
- data/spec/install/gems/c_ext_spec.rb +48 -0
- data/spec/install/gems/env_spec.rb +107 -0
- data/spec/install/gems/flex_spec.rb +272 -0
- data/spec/install/gems/groups_spec.rb +228 -0
- data/spec/install/gems/packed_spec.rb +72 -0
- data/spec/install/gems/platform_spec.rb +195 -0
- data/spec/install/gems/resolving_spec.rb +72 -0
- data/spec/install/gems/simple_case_spec.rb +749 -0
- data/spec/install/gems/sudo_spec.rb +77 -0
- data/spec/install/gems/win32_spec.rb +26 -0
- data/spec/install/gemspec_spec.rb +96 -0
- data/spec/install/git_spec.rb +553 -0
- data/spec/install/invalid_spec.rb +17 -0
- data/spec/install/path_spec.rb +329 -0
- data/spec/install/upgrade_spec.rb +26 -0
- data/spec/lock/flex_spec.rb +650 -0
- data/spec/lock/git_spec.rb +35 -0
- data/spec/other/check_spec.rb +221 -0
- data/spec/other/config_spec.rb +40 -0
- data/spec/other/console_spec.rb +54 -0
- data/spec/other/exec_spec.rb +241 -0
- data/spec/other/ext_spec.rb +16 -0
- data/spec/other/gem_helper_spec.rb +126 -0
- data/spec/other/help_spec.rb +36 -0
- data/spec/other/init_spec.rb +40 -0
- data/spec/other/newgem_spec.rb +24 -0
- data/spec/other/open_spec.rb +35 -0
- data/spec/other/show_spec.rb +82 -0
- data/spec/pack/gems_spec.rb +22 -0
- data/spec/quality_spec.rb +55 -0
- data/spec/resolver/basic_spec.rb +20 -0
- data/spec/resolver/platform_spec.rb +57 -0
- data/spec/runtime/environment_rb_spec.rb +162 -0
- data/spec/runtime/executable_spec.rb +110 -0
- data/spec/runtime/load_spec.rb +102 -0
- data/spec/runtime/platform_spec.rb +90 -0
- data/spec/runtime/require_spec.rb +231 -0
- data/spec/runtime/setup_spec.rb +412 -0
- data/spec/runtime/with_clean_env_spec.rb +15 -0
- data/spec/spec_helper.rb +82 -0
- data/spec/support/builders.rb +566 -0
- data/spec/support/helpers.rb +243 -0
- data/spec/support/indexes.rb +113 -0
- data/spec/support/matchers.rb +89 -0
- data/spec/support/path.rb +71 -0
- data/spec/support/platforms.rb +49 -0
- data/spec/support/ruby_ext.rb +19 -0
- data/spec/support/rubygems_ext.rb +30 -0
- data/spec/support/rubygems_hax/rubygems_plugin.rb +9 -0
- data/spec/support/sudo.rb +21 -0
- data/spec/update/gems_spec.rb +112 -0
- data/spec/update/git_spec.rb +159 -0
- data/spec/update/source_spec.rb +50 -0
- metadata +251 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
module Bundler
|
|
2
|
+
class Graph
|
|
3
|
+
|
|
4
|
+
USER_OPTIONS = {:style => 'filled', :fillcolor => '#B9B9D5'}.freeze
|
|
5
|
+
|
|
6
|
+
def initialize(env)
|
|
7
|
+
@env = env
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def nodes
|
|
11
|
+
populate
|
|
12
|
+
@nodes
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def groups
|
|
16
|
+
populate
|
|
17
|
+
@groups
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def viz(output_file, show_gem_versions = false, show_dependency_requirements = false)
|
|
21
|
+
require 'graphviz'
|
|
22
|
+
populate
|
|
23
|
+
|
|
24
|
+
graph_viz = GraphViz::new('Gemfile', {:concentrate => true, :normalize => true, :nodesep => 0.55})
|
|
25
|
+
graph_viz.edge[:fontname] = graph_viz.node[:fontname] = 'Arial, Helvetica, SansSerif'
|
|
26
|
+
graph_viz.edge[:fontsize] = 12
|
|
27
|
+
|
|
28
|
+
viz_nodes = {}
|
|
29
|
+
|
|
30
|
+
# populate all of the nodes
|
|
31
|
+
nodes.each do |name, node|
|
|
32
|
+
label = name.dup
|
|
33
|
+
label << "\n#{node.version}" if show_gem_versions
|
|
34
|
+
options = { :label => label }
|
|
35
|
+
options.merge!( USER_OPTIONS ) if node.is_user
|
|
36
|
+
viz_nodes[name] = graph_viz.add_node( name, options )
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
group_nodes = {}
|
|
40
|
+
@groups.each do |name, dependencies|
|
|
41
|
+
group_nodes[name] = graph_viz.add_node(name.to_s, { :shape => 'box3d', :fontsize => 16 }.merge(USER_OPTIONS))
|
|
42
|
+
dependencies.each do |dependency|
|
|
43
|
+
options = { :weight => 2 }
|
|
44
|
+
if show_dependency_requirements && (dependency.requirement.to_s != ">= 0")
|
|
45
|
+
options[:label] = dependency.requirement.to_s
|
|
46
|
+
end
|
|
47
|
+
graph_viz.add_edge( group_nodes[name], viz_nodes[dependency.name], options )
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
@groups.keys.select { |group| group != :default }.each do |group|
|
|
52
|
+
graph_viz.add_edge( group_nodes[group], group_nodes[:default], { :weight => 2 } )
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
viz_nodes.each do |name, node|
|
|
56
|
+
nodes[name].dependencies.each do |dependency|
|
|
57
|
+
options = { }
|
|
58
|
+
if nodes[dependency.name].is_user
|
|
59
|
+
options[:constraint] = false
|
|
60
|
+
end
|
|
61
|
+
if show_dependency_requirements && (dependency.requirement.to_s != ">= 0")
|
|
62
|
+
options[:label] = dependency.requirement.to_s
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
graph_viz.add_edge( node, viz_nodes[dependency.name], options )
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
graph_viz.output( :png => output_file )
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
private
|
|
73
|
+
|
|
74
|
+
def populate
|
|
75
|
+
return if @populated
|
|
76
|
+
|
|
77
|
+
# hash of name => GraphNode
|
|
78
|
+
@nodes = {}
|
|
79
|
+
@groups = {}
|
|
80
|
+
|
|
81
|
+
# Populate @nodes
|
|
82
|
+
@env.specs.each { |spec| @nodes[spec.name] = GraphNode.new(spec.name, spec.version) }
|
|
83
|
+
|
|
84
|
+
# For gems in Gemfile, add details
|
|
85
|
+
@env.current_dependencies.each do |dependency|
|
|
86
|
+
node = @nodes[dependency.name]
|
|
87
|
+
node.is_user = true
|
|
88
|
+
|
|
89
|
+
dependency.groups.each do |group|
|
|
90
|
+
if @groups.has_key? group
|
|
91
|
+
group = @groups[group]
|
|
92
|
+
else
|
|
93
|
+
group = @groups[group] = []
|
|
94
|
+
end
|
|
95
|
+
group << dependency
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
# walk though a final time and add edges
|
|
100
|
+
@env.specs.each do |spec|
|
|
101
|
+
|
|
102
|
+
from = @nodes[spec.name]
|
|
103
|
+
spec.runtime_dependencies.each do |dependency|
|
|
104
|
+
from.dependencies << dependency
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
@nodes.freeze
|
|
110
|
+
@groups.freeze
|
|
111
|
+
@populated = true
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# Add version info
|
|
117
|
+
class GraphNode
|
|
118
|
+
|
|
119
|
+
def initialize(name, version)
|
|
120
|
+
@name = name
|
|
121
|
+
@version = version
|
|
122
|
+
@is_user = false
|
|
123
|
+
@dependencies = []
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
attr_reader :name, :dependencies, :version
|
|
127
|
+
attr_accessor :is_user
|
|
128
|
+
|
|
129
|
+
end
|
|
130
|
+
end
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
module Bundler
|
|
2
|
+
class Index
|
|
3
|
+
include Enumerable
|
|
4
|
+
|
|
5
|
+
def self.build
|
|
6
|
+
i = new
|
|
7
|
+
yield i
|
|
8
|
+
i
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def initialize
|
|
12
|
+
@cache = {}
|
|
13
|
+
@specs = Hash.new { |h,k| h[k] = [] }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def initialize_copy(o)
|
|
17
|
+
super
|
|
18
|
+
@cache = {}
|
|
19
|
+
@specs = Hash.new { |h,k| h[k] = [] }
|
|
20
|
+
merge!(o)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def empty?
|
|
24
|
+
each { return false }
|
|
25
|
+
true
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def search(query)
|
|
29
|
+
case query
|
|
30
|
+
when Gem::Specification, RemoteSpecification, LazySpecification then search_by_spec(query)
|
|
31
|
+
when String then @specs[query]
|
|
32
|
+
else search_by_dependency(query)
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def search_for_all_platforms(dependency, base = [])
|
|
37
|
+
specs = @specs[dependency.name] + base
|
|
38
|
+
|
|
39
|
+
wants_prerelease = dependency.requirement.prerelease?
|
|
40
|
+
only_prerelease = specs.all? {|spec| spec.version.prerelease? }
|
|
41
|
+
found = specs.select { |spec| dependency =~ spec }
|
|
42
|
+
|
|
43
|
+
unless wants_prerelease || only_prerelease
|
|
44
|
+
found.reject! { |spec| spec.version.prerelease? }
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
found.sort_by {|s| [s.version, s.platform.to_s == 'ruby' ? "\0" : s.platform.to_s] }
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def sources
|
|
51
|
+
@specs.values.map do |specs|
|
|
52
|
+
specs.map{|s| s.source.class }
|
|
53
|
+
end.flatten.uniq
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
alias [] search
|
|
57
|
+
|
|
58
|
+
def <<(spec)
|
|
59
|
+
arr = @specs[spec.name]
|
|
60
|
+
|
|
61
|
+
arr.delete_if do |s|
|
|
62
|
+
s.version == spec.version && s.platform == spec.platform
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
arr << spec
|
|
66
|
+
spec
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def each(&blk)
|
|
70
|
+
@specs.values.each do |specs|
|
|
71
|
+
specs.each(&blk)
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def use(other)
|
|
76
|
+
return unless other
|
|
77
|
+
other.each do |s|
|
|
78
|
+
next if search_by_spec(s).any?
|
|
79
|
+
@specs[s.name] << s
|
|
80
|
+
end
|
|
81
|
+
self
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def ==(o)
|
|
85
|
+
all? do |s|
|
|
86
|
+
s2 = o[s].first and (s.dependencies & s2.dependencies).empty?
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
private
|
|
91
|
+
|
|
92
|
+
def search_by_spec(spec)
|
|
93
|
+
@specs[spec.name].select do |s|
|
|
94
|
+
s.version == spec.version && Gem::Platform.new(s.platform) == Gem::Platform.new(spec.platform)
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def search_by_dependency(dependency)
|
|
99
|
+
@cache[dependency.hash] ||= begin
|
|
100
|
+
specs = @specs[dependency.name]
|
|
101
|
+
|
|
102
|
+
wants_prerelease = dependency.requirement.prerelease?
|
|
103
|
+
only_prerelease = specs.all? {|spec| spec.version.prerelease? }
|
|
104
|
+
found = specs.select { |spec| dependency =~ spec && Gem::Platform.match(spec.platform) }
|
|
105
|
+
|
|
106
|
+
unless wants_prerelease || only_prerelease
|
|
107
|
+
found.reject! { |spec| spec.version.prerelease? }
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
found.sort_by {|s| [s.version, s.platform.to_s == 'ruby' ? "\0" : s.platform.to_s] }
|
|
111
|
+
end
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
require 'erb'
|
|
2
|
+
require 'rubygems/dependency_installer'
|
|
3
|
+
|
|
4
|
+
module Bundler
|
|
5
|
+
class Installer < Environment
|
|
6
|
+
def self.install(root, definition, options = {})
|
|
7
|
+
installer = new(root, definition)
|
|
8
|
+
installer.run(options)
|
|
9
|
+
installer
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def run(options)
|
|
13
|
+
if Bundler.settings[:frozen]
|
|
14
|
+
@definition.ensure_equivalent_gemfile_and_lockfile
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
if dependencies.empty?
|
|
18
|
+
Bundler.ui.warn "The Gemfile specifies no dependencies"
|
|
19
|
+
return
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
if Bundler.default_lockfile.exist? && !options["update"]
|
|
23
|
+
begin
|
|
24
|
+
tmpdef = Definition.build(Bundler.default_gemfile, Bundler.default_lockfile, nil)
|
|
25
|
+
local = true unless tmpdef.new_platform? || tmpdef.missing_specs.any?
|
|
26
|
+
rescue BundlerError
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Since we are installing, we can resolve the definition
|
|
31
|
+
# using remote specs
|
|
32
|
+
unless local
|
|
33
|
+
options["local"] ?
|
|
34
|
+
@definition.resolve_with_cache! :
|
|
35
|
+
@definition.resolve_remotely!
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# Ensure that BUNDLE_PATH exists
|
|
39
|
+
Bundler.mkdir_p(Bundler.bundle_path) unless File.exist?(Bundler.bundle_path)
|
|
40
|
+
|
|
41
|
+
# Must install gems in the order that the resolver provides
|
|
42
|
+
# as dependencies might actually affect the installation of
|
|
43
|
+
# the gem.
|
|
44
|
+
specs.each do |spec|
|
|
45
|
+
spec.source.fetch(spec) if spec.source.respond_to?(:fetch)
|
|
46
|
+
|
|
47
|
+
# unless requested_specs.include?(spec)
|
|
48
|
+
# Bundler.ui.debug " * Not in requested group; skipping."
|
|
49
|
+
# next
|
|
50
|
+
# end
|
|
51
|
+
|
|
52
|
+
begin
|
|
53
|
+
old_args = Gem::Command.build_args
|
|
54
|
+
Gem::Command.build_args = [Bundler.settings["build.#{spec.name}"]]
|
|
55
|
+
spec.source.install(spec)
|
|
56
|
+
ensure
|
|
57
|
+
Gem::Command.build_args = old_args
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
Bundler.ui.info ""
|
|
61
|
+
generate_bundler_executable_stubs(spec) if Bundler.settings[:bin]
|
|
62
|
+
FileUtils.rm_rf(Bundler.tmp)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
lock
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
private
|
|
69
|
+
|
|
70
|
+
def generate_bundler_executable_stubs(spec)
|
|
71
|
+
bin_path = Bundler.bin_path
|
|
72
|
+
template = File.read(File.expand_path('../templates/Executable', __FILE__))
|
|
73
|
+
relative_gemfile_path = Bundler.default_gemfile.relative_path_from(bin_path)
|
|
74
|
+
ruby_command = Thor::Util.ruby_command
|
|
75
|
+
|
|
76
|
+
spec.executables.each do |executable|
|
|
77
|
+
next if executable == "bundle"
|
|
78
|
+
File.open "#{bin_path}/#{executable}", 'w', 0755 do |f|
|
|
79
|
+
f.puts ERB.new(template, nil, '-').result(binding)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
require "uri"
|
|
2
|
+
require "rubygems/spec_fetcher"
|
|
3
|
+
|
|
4
|
+
module Bundler
|
|
5
|
+
class LazySpecification
|
|
6
|
+
include MatchPlatform
|
|
7
|
+
|
|
8
|
+
attr_reader :name, :version, :dependencies, :platform
|
|
9
|
+
attr_accessor :source
|
|
10
|
+
|
|
11
|
+
def initialize(name, version, platform, source = nil)
|
|
12
|
+
@name = name
|
|
13
|
+
@version = version
|
|
14
|
+
@dependencies = []
|
|
15
|
+
@platform = platform
|
|
16
|
+
@source = source
|
|
17
|
+
@specification = nil
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def full_name
|
|
21
|
+
if platform == Gem::Platform::RUBY or platform.nil? then
|
|
22
|
+
"#{@name}-#{@version}"
|
|
23
|
+
else
|
|
24
|
+
"#{@name}-#{@version}-#{platform}"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def satisfies?(dependency)
|
|
29
|
+
@name == dependency.name && dependency.requirement.satisfied_by?(Gem::Version.new(@version))
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def to_lock
|
|
33
|
+
if platform == Gem::Platform::RUBY or platform.nil?
|
|
34
|
+
out = " #{name} (#{version})\n"
|
|
35
|
+
else
|
|
36
|
+
out = " #{name} (#{version}-#{platform})\n"
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
dependencies.sort_by {|d| d.name }.each do |dep|
|
|
40
|
+
next if dep.type == :development
|
|
41
|
+
out << " #{dep.to_lock}\n"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
out
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def __materialize__
|
|
48
|
+
@specification = source.specs.search(Gem::Dependency.new(name, version)).last
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def respond_to?(*args)
|
|
52
|
+
super || @specification.respond_to?(*args)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def to_s
|
|
56
|
+
"#{name} (#{version})"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def method_missing(method, *args, &blk)
|
|
62
|
+
if Gem::Specification.new.respond_to?(method)
|
|
63
|
+
raise "LazySpecification has not been materialized yet (calling :#{method} #{args.inspect})" unless @specification
|
|
64
|
+
@specification.send(method, *args, &blk)
|
|
65
|
+
else
|
|
66
|
+
super
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
require "strscan"
|
|
2
|
+
|
|
3
|
+
module Bundler
|
|
4
|
+
class LockfileParser
|
|
5
|
+
attr_reader :sources, :dependencies, :specs, :platforms
|
|
6
|
+
|
|
7
|
+
def initialize(lockfile)
|
|
8
|
+
@platforms = []
|
|
9
|
+
@sources = []
|
|
10
|
+
@dependencies = []
|
|
11
|
+
@specs = []
|
|
12
|
+
@state = :source
|
|
13
|
+
|
|
14
|
+
lockfile.split(/(\r?\n)+/).each do |line|
|
|
15
|
+
if line == "DEPENDENCIES"
|
|
16
|
+
@state = :dependency
|
|
17
|
+
elsif line == "PLATFORMS"
|
|
18
|
+
@state = :platform
|
|
19
|
+
else
|
|
20
|
+
send("parse_#{@state}", line)
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
TYPES = {
|
|
28
|
+
"GIT" => Bundler::Source::Git,
|
|
29
|
+
"GEM" => Bundler::Source::Rubygems,
|
|
30
|
+
"PATH" => Bundler::Source::Path
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
def parse_source(line)
|
|
34
|
+
case line
|
|
35
|
+
when "GIT", "GEM", "PATH"
|
|
36
|
+
@current_source = nil
|
|
37
|
+
@opts, @type = {}, line
|
|
38
|
+
when " specs:"
|
|
39
|
+
@current_source = TYPES[@type].from_lock(@opts)
|
|
40
|
+
@sources << @current_source
|
|
41
|
+
when /^ ([a-z]+): (.*)$/i
|
|
42
|
+
value = $2
|
|
43
|
+
value = true if value == "true"
|
|
44
|
+
value = false if value == "false"
|
|
45
|
+
|
|
46
|
+
key = $1
|
|
47
|
+
|
|
48
|
+
if @opts[key]
|
|
49
|
+
@opts[key] = Array(@opts[key])
|
|
50
|
+
@opts[key] << value
|
|
51
|
+
else
|
|
52
|
+
@opts[key] = value
|
|
53
|
+
end
|
|
54
|
+
else
|
|
55
|
+
parse_spec(line)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
NAME_VERSION = '(?! )(.*?)(?: \(([^-]*)(?:-(.*))?\))?'
|
|
60
|
+
|
|
61
|
+
def parse_dependency(line)
|
|
62
|
+
if line =~ %r{^ {2}#{NAME_VERSION}(!)?$}
|
|
63
|
+
name, version, pinned = $1, $2, $4
|
|
64
|
+
version = version.split(",").map { |d| d.strip } if version
|
|
65
|
+
|
|
66
|
+
dep = Bundler::Dependency.new(name, version)
|
|
67
|
+
|
|
68
|
+
if pinned && dep.name != 'bundler'
|
|
69
|
+
spec = @specs.find { |s| s.name == dep.name }
|
|
70
|
+
dep.source = spec.source if spec
|
|
71
|
+
|
|
72
|
+
# Path sources need to know what the default name / version
|
|
73
|
+
# to use in the case that there are no gemspecs present. A fake
|
|
74
|
+
# gemspec is created based on the version set on the dependency
|
|
75
|
+
# TODO: Use the version from the spec instead of from the dependency
|
|
76
|
+
if version && version.size == 1 && version.first =~ /^\s*= (.+)\s*$/ && dep.source.is_a?(Bundler::Source::Path)
|
|
77
|
+
dep.source.name = name
|
|
78
|
+
dep.source.version = $1
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
@dependencies << dep
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def parse_spec(line)
|
|
87
|
+
if line =~ %r{^ {4}#{NAME_VERSION}$}
|
|
88
|
+
name, version = $1, Gem::Version.new($2)
|
|
89
|
+
platform = $3 ? Gem::Platform.new($3) : Gem::Platform::RUBY
|
|
90
|
+
@current_spec = LazySpecification.new(name, version, platform)
|
|
91
|
+
@current_spec.source = @current_source
|
|
92
|
+
@specs << @current_spec
|
|
93
|
+
elsif line =~ %r{^ {6}#{NAME_VERSION}$}
|
|
94
|
+
name, version = $1, $2
|
|
95
|
+
version = version.split(',').map { |d| d.strip } if version
|
|
96
|
+
dep = Gem::Dependency.new(name, version)
|
|
97
|
+
@current_spec.dependencies << dep
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
def parse_platform(line)
|
|
102
|
+
if line =~ /^ (.*)$/
|
|
103
|
+
@platforms << Gem::Platform.new($1)
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
end
|
|
108
|
+
end
|