moneypools-bundler 0.7.1.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.markdown +275 -0
- data/Rakefile +60 -0
- data/lib/bundler.rb +35 -0
- data/lib/bundler/cli.rb +69 -0
- data/lib/bundler/commands/bundle_command.rb +72 -0
- data/lib/bundler/commands/exec_command.rb +36 -0
- data/lib/bundler/dependency.rb +64 -0
- data/lib/bundler/dsl.rb +173 -0
- data/lib/bundler/environment.rb +181 -0
- data/lib/bundler/finder.rb +51 -0
- data/lib/bundler/gem_bundle.rb +11 -0
- data/lib/bundler/gem_ext.rb +33 -0
- data/lib/bundler/remote_specification.rb +50 -0
- data/lib/bundler/repository.rb +256 -0
- data/lib/bundler/resolver.rb +234 -0
- data/lib/bundler/runtime.rb +2 -0
- data/lib/bundler/source.rb +326 -0
- data/lib/bundler/templates/app_script.erb +3 -0
- data/lib/bundler/templates/environment.erb +142 -0
- data/lib/rubygems_plugin.rb +6 -0
- metadata +79 -0
@@ -0,0 +1,72 @@
|
|
1
|
+
class Gem::Commands::BundleCommand < Gem::Command
|
2
|
+
|
3
|
+
def initialize
|
4
|
+
super('bundle', 'Create a gem bundle based on your Gemfile', {:manifest => nil, :update => false})
|
5
|
+
|
6
|
+
add_option('-m', '--manifest MANIFEST', "Specify the path to the manifest file") do |manifest, options|
|
7
|
+
options[:manifest] = manifest
|
8
|
+
end
|
9
|
+
|
10
|
+
add_option('-u', '--update', "Force a remote check for newer gems") do
|
11
|
+
options[:update] = true
|
12
|
+
end
|
13
|
+
|
14
|
+
add_option('--cached', "Only use cached gems when expanding the bundle") do
|
15
|
+
options[:cached] = true
|
16
|
+
end
|
17
|
+
|
18
|
+
add_option('--cache GEM', "Specify a path to a .gem file to add to the bundled gem cache") do |gem, options|
|
19
|
+
options[:cache] = gem
|
20
|
+
end
|
21
|
+
|
22
|
+
add_option('--prune-cache', "Removes all .gem files from the bundle's cache") do
|
23
|
+
options[:prune] = true
|
24
|
+
end
|
25
|
+
|
26
|
+
add_option('--list', "List all gems that are part of the active bundle") do
|
27
|
+
options[:list] = true
|
28
|
+
end
|
29
|
+
|
30
|
+
add_option('--list-outdated', "List all outdated gems that are part of the active bundle") do
|
31
|
+
options[:list_outdated] = true
|
32
|
+
end
|
33
|
+
|
34
|
+
add_option('-b', '--build-options OPTION_FILE', "Specify a path to a yml file with build options for binary gems") do |option_file, options|
|
35
|
+
if File.exist?(option_file)
|
36
|
+
options[:build_options] = YAML.load_file(option_file)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
add_option('--only ENV', "Only expand the given environment. To specify multiple environments, use --only multiple times.") do |env, options|
|
41
|
+
options[:only] ||= []
|
42
|
+
options[:only] << env
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def usage
|
47
|
+
"#{program_name}"
|
48
|
+
end
|
49
|
+
|
50
|
+
def description # :nodoc:
|
51
|
+
<<-EOF
|
52
|
+
Bundle stuff
|
53
|
+
EOF
|
54
|
+
end
|
55
|
+
|
56
|
+
def execute
|
57
|
+
# Prevent the bundler from getting required unless it is actually being used
|
58
|
+
require 'bundler'
|
59
|
+
if options[:cache]
|
60
|
+
Bundler::CLI.run(:cache, options)
|
61
|
+
elsif options[:prune]
|
62
|
+
Bundler::CLI.run(:prune, options)
|
63
|
+
elsif options[:list]
|
64
|
+
Bundler::CLI.run(:list, options)
|
65
|
+
elsif options[:list_outdated]
|
66
|
+
Bundler::CLI.run(:list_outdated, options)
|
67
|
+
else
|
68
|
+
Bundler::CLI.run(:bundle, options)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
if exec = ARGV.index("exec")
|
2
|
+
$command = ARGV[(exec + 1)..-1]
|
3
|
+
ARGV.replace ARGV[0..exec]
|
4
|
+
end
|
5
|
+
|
6
|
+
class Gem::Commands::ExecCommand < Gem::Command
|
7
|
+
|
8
|
+
def initialize
|
9
|
+
super('exec', 'Run a command in context of a gem bundle', {:manifest => nil})
|
10
|
+
|
11
|
+
add_option('-m', '--manifest MANIFEST', "Specify the path to the manifest file") do |manifest, options|
|
12
|
+
options[:manifest] = manifest
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def usage
|
17
|
+
"#{program_name} COMMAND"
|
18
|
+
end
|
19
|
+
|
20
|
+
def arguments # :nodoc:
|
21
|
+
"COMMAND command to run in context of the gem bundle"
|
22
|
+
end
|
23
|
+
|
24
|
+
def description # :nodoc:
|
25
|
+
<<-EOF.gsub(' ', '')
|
26
|
+
Run in context of a bundle
|
27
|
+
EOF
|
28
|
+
end
|
29
|
+
|
30
|
+
def execute
|
31
|
+
# Prevent the bundler from getting required unless it is actually being used
|
32
|
+
require 'bundler'
|
33
|
+
Bundler::CLI.run(:exec, options)
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
module Bundler
|
2
|
+
class InvalidEnvironmentName < StandardError; end
|
3
|
+
|
4
|
+
class Dependency
|
5
|
+
attr_reader :name, :version, :require_as, :only, :except
|
6
|
+
attr_accessor :source
|
7
|
+
|
8
|
+
def initialize(name, options = {}, &block)
|
9
|
+
options.each do |k, v|
|
10
|
+
options[k.to_s] = v
|
11
|
+
end
|
12
|
+
|
13
|
+
@name = name
|
14
|
+
@version = options["version"] || ">= 0"
|
15
|
+
@require_as = options["require_as"]
|
16
|
+
@only = options["only"]
|
17
|
+
@except = options["except"]
|
18
|
+
@source = options["source"]
|
19
|
+
@block = block
|
20
|
+
|
21
|
+
if (@only && @only.include?("rubygems")) || (@except && @except.include?("rubygems"))
|
22
|
+
raise InvalidEnvironmentName, "'rubygems' is not a valid environment name"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def in?(environment)
|
27
|
+
environment = environment.to_s
|
28
|
+
|
29
|
+
return false unless !@only || @only.include?(environment)
|
30
|
+
return false if @except && @except.include?(environment)
|
31
|
+
true
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
to_gem_dependency.to_s
|
36
|
+
end
|
37
|
+
|
38
|
+
def require_env(environment)
|
39
|
+
return unless in?(environment)
|
40
|
+
|
41
|
+
if @require_as
|
42
|
+
Array(@require_as).each { |file| require file }
|
43
|
+
elsif require_as.nil?
|
44
|
+
begin
|
45
|
+
require name
|
46
|
+
rescue LoadError
|
47
|
+
# Do nothing
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
@block.call if @block
|
52
|
+
end
|
53
|
+
|
54
|
+
def to_gem_dependency
|
55
|
+
@gem_dep ||= Gem::Dependency.new(name, version)
|
56
|
+
end
|
57
|
+
|
58
|
+
def ==(o)
|
59
|
+
[name, version, require_as, only, except] ==
|
60
|
+
[o.name, o.version, o.require_as, o.only, o.except]
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
data/lib/bundler/dsl.rb
ADDED
@@ -0,0 +1,173 @@
|
|
1
|
+
module Bundler
|
2
|
+
class ManifestFileNotFound < StandardError; end
|
3
|
+
|
4
|
+
class Dsl
|
5
|
+
def self.evaluate(environment, file)
|
6
|
+
builder = new(environment)
|
7
|
+
builder.instance_eval(File.read(file.to_s), file.to_s, 1)
|
8
|
+
end
|
9
|
+
|
10
|
+
def initialize(environment)
|
11
|
+
@environment = environment
|
12
|
+
@directory_sources = []
|
13
|
+
@git_sources = {}
|
14
|
+
@only, @except, @directory, @git = nil, nil, nil, nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def bundle_path(path)
|
18
|
+
path = Pathname.new(path)
|
19
|
+
@environment.gem_path = (path.relative? ?
|
20
|
+
@environment.root.join(path) : path).expand_path
|
21
|
+
end
|
22
|
+
|
23
|
+
def bin_path(path)
|
24
|
+
path = Pathname.new(path)
|
25
|
+
@environment.bindir = (path.relative? ?
|
26
|
+
@environment.root.join(path) : path).expand_path
|
27
|
+
end
|
28
|
+
|
29
|
+
def disable_rubygems
|
30
|
+
@environment.rubygems = false
|
31
|
+
end
|
32
|
+
|
33
|
+
def disable_system_gems
|
34
|
+
@environment.system_gems = false
|
35
|
+
end
|
36
|
+
|
37
|
+
def source(source)
|
38
|
+
source = GemSource.new(:uri => source)
|
39
|
+
unless @environment.sources.include?(source)
|
40
|
+
@environment.add_source(source)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def only(*env)
|
45
|
+
old, @only = @only, _combine_only(env)
|
46
|
+
yield
|
47
|
+
@only = old
|
48
|
+
end
|
49
|
+
|
50
|
+
def except(*env)
|
51
|
+
old, @except = @except, _combine_except(env)
|
52
|
+
yield
|
53
|
+
@except = old
|
54
|
+
end
|
55
|
+
|
56
|
+
def directory(path, options = {})
|
57
|
+
raise DirectorySourceError, "cannot nest calls to directory or git" if @directory || @git
|
58
|
+
@directory = DirectorySource.new(options.merge(:location => path))
|
59
|
+
@directory_sources << @directory
|
60
|
+
@environment.add_priority_source(@directory)
|
61
|
+
retval = yield if block_given?
|
62
|
+
@directory = nil
|
63
|
+
retval
|
64
|
+
end
|
65
|
+
|
66
|
+
def git(uri, options = {})
|
67
|
+
raise DirectorySourceError, "cannot nest calls to directory or git" if @directory || @git
|
68
|
+
@git = GitSource.new(options.merge(:uri => uri))
|
69
|
+
@git_sources[uri] = @git
|
70
|
+
@environment.add_priority_source(@git)
|
71
|
+
retval = yield if block_given?
|
72
|
+
@git = nil
|
73
|
+
retval
|
74
|
+
end
|
75
|
+
|
76
|
+
def clear_sources
|
77
|
+
@environment.clear_sources
|
78
|
+
end
|
79
|
+
|
80
|
+
def gem(name, *args)
|
81
|
+
options = args.last.is_a?(Hash) ? args.pop : {}
|
82
|
+
version = args.last
|
83
|
+
|
84
|
+
if path = options.delete(:vendored_at)
|
85
|
+
options[:path] = path
|
86
|
+
warn "The :vendored_at option is deprecated. Use :path instead.\nFrom #{caller[0]}"
|
87
|
+
end
|
88
|
+
|
89
|
+
options[:only] = _combine_only(options[:only] || options["only"])
|
90
|
+
options[:except] = _combine_except(options[:except] || options["except"])
|
91
|
+
|
92
|
+
dep = Dependency.new(name, options.merge(:version => version))
|
93
|
+
|
94
|
+
if options.key?(:bundle) && !options[:bundle]
|
95
|
+
dep.source = SystemGemSource.instance
|
96
|
+
elsif @git || options[:git]
|
97
|
+
dep.source = _handle_git_option(name, version, options)
|
98
|
+
elsif @directory || options[:path]
|
99
|
+
dep.source = _handle_vendored_option(name, version, options)
|
100
|
+
end
|
101
|
+
|
102
|
+
@environment.dependencies << dep
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def _handle_vendored_option(name, version, options)
|
108
|
+
dir, path = _find_directory_source(options[:path])
|
109
|
+
|
110
|
+
if dir
|
111
|
+
dir.required_specs << name
|
112
|
+
dir.add_spec(path, name, version) if version
|
113
|
+
dir
|
114
|
+
else
|
115
|
+
directory options[:path] do
|
116
|
+
_handle_vendored_option(name, version, {})
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
def _find_directory_source(path)
|
122
|
+
if @directory
|
123
|
+
return @directory, Pathname.new(path || '')
|
124
|
+
end
|
125
|
+
|
126
|
+
path = @environment.filename.dirname.join(path)
|
127
|
+
|
128
|
+
@directory_sources.each do |s|
|
129
|
+
if s.location.expand_path.to_s < path.expand_path.to_s
|
130
|
+
return s, path.relative_path_from(s.location)
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
nil
|
135
|
+
end
|
136
|
+
|
137
|
+
def _handle_git_option(name, version, options)
|
138
|
+
git = options[:git].to_s
|
139
|
+
ref = options[:commit] || options[:tag]
|
140
|
+
branch = options[:branch]
|
141
|
+
|
142
|
+
if source = @git || @git_sources[git]
|
143
|
+
if ref && source.ref != ref
|
144
|
+
raise GitSourceError, "'#{git}' already specified with ref: #{source.ref}"
|
145
|
+
elsif branch && source.branch != branch
|
146
|
+
raise GitSourceError, "'#{git}' already specified with branch: #{source.branch}"
|
147
|
+
end
|
148
|
+
|
149
|
+
source.required_specs << name
|
150
|
+
source.add_spec(Pathname.new(options[:path] || '.'), name, version) if version
|
151
|
+
source
|
152
|
+
else
|
153
|
+
git(git, :ref => ref, :branch => branch) do
|
154
|
+
_handle_git_option(name, version, options)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
|
159
|
+
def _combine_only(only)
|
160
|
+
return @only unless only
|
161
|
+
only = Array(only).compact.uniq.map { |o| o.to_s }
|
162
|
+
only &= @only if @only
|
163
|
+
only
|
164
|
+
end
|
165
|
+
|
166
|
+
def _combine_except(except)
|
167
|
+
return @except unless except
|
168
|
+
except = Array(except).compact.uniq.map { |o| o.to_s }
|
169
|
+
except |= @except if @except
|
170
|
+
except
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
require "rubygems/source_index"
|
2
|
+
|
3
|
+
module Bundler
|
4
|
+
class DefaultManifestNotFound < StandardError; end
|
5
|
+
class InvalidCacheArgument < StandardError; end
|
6
|
+
class SourceNotCached < StandardError; end
|
7
|
+
|
8
|
+
class Environment
|
9
|
+
attr_reader :filename, :dependencies
|
10
|
+
attr_accessor :rubygems, :system_gems
|
11
|
+
attr_writer :gem_path, :bindir
|
12
|
+
|
13
|
+
def self.load(file = nil)
|
14
|
+
gemfile = Pathname.new(file || default_manifest_file).expand_path
|
15
|
+
|
16
|
+
unless gemfile.file?
|
17
|
+
raise ManifestFileNotFound, "Manifest file not found: #{gemfile.to_s.inspect}"
|
18
|
+
end
|
19
|
+
|
20
|
+
new(gemfile)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.default_manifest_file
|
24
|
+
current = Pathname.new(Dir.pwd)
|
25
|
+
|
26
|
+
until current.root?
|
27
|
+
filename = current.join("Gemfile")
|
28
|
+
return filename if filename.exist?
|
29
|
+
current = current.parent
|
30
|
+
end
|
31
|
+
|
32
|
+
raise DefaultManifestNotFound
|
33
|
+
end
|
34
|
+
|
35
|
+
def initialize(filename)
|
36
|
+
@filename = filename
|
37
|
+
@default_sources = default_sources
|
38
|
+
@sources = []
|
39
|
+
@priority_sources = []
|
40
|
+
@dependencies = []
|
41
|
+
@rubygems = true
|
42
|
+
@system_gems = true
|
43
|
+
|
44
|
+
# Evaluate the Gemfile
|
45
|
+
Dsl.evaluate(self, filename)
|
46
|
+
end
|
47
|
+
|
48
|
+
def install(options = {})
|
49
|
+
if only_envs = options[:only]
|
50
|
+
dependencies.reject! { |d| !only_envs.any? {|env| d.in?(env) } }
|
51
|
+
end
|
52
|
+
|
53
|
+
no_bundle = dependencies.map do |dep|
|
54
|
+
dep.source == SystemGemSource.instance && dep.name
|
55
|
+
end.compact
|
56
|
+
|
57
|
+
update = options[:update]
|
58
|
+
cached = options[:cached]
|
59
|
+
|
60
|
+
repository.install(dependencies, sources,
|
61
|
+
:rubygems => rubygems,
|
62
|
+
:system_gems => system_gems,
|
63
|
+
:manifest => filename,
|
64
|
+
:update => options[:update],
|
65
|
+
:cached => options[:cached],
|
66
|
+
:build_options => options[:build_options],
|
67
|
+
:no_bundle => no_bundle
|
68
|
+
)
|
69
|
+
Bundler.logger.info "Done."
|
70
|
+
end
|
71
|
+
|
72
|
+
def cache(options = {})
|
73
|
+
gemfile = options[:cache]
|
74
|
+
|
75
|
+
if File.extname(gemfile) == ".gem"
|
76
|
+
if !File.exist?(gemfile)
|
77
|
+
raise InvalidCacheArgument, "'#{gemfile}' does not exist."
|
78
|
+
end
|
79
|
+
repository.cache(gemfile)
|
80
|
+
elsif File.directory?(gemfile) || gemfile.include?('/')
|
81
|
+
if !File.directory?(gemfile)
|
82
|
+
raise InvalidCacheArgument, "'#{gemfile}' does not exist."
|
83
|
+
end
|
84
|
+
gemfiles = Dir["#{gemfile}/*.gem"]
|
85
|
+
if gemfiles.empty?
|
86
|
+
raise InvalidCacheArgument, "'#{gemfile}' contains no gemfiles"
|
87
|
+
end
|
88
|
+
repository.cache(*gemfiles)
|
89
|
+
else
|
90
|
+
local = Gem::SourceIndex.from_installed_gems.find_name(gemfile).last
|
91
|
+
|
92
|
+
if !local
|
93
|
+
raise InvalidCacheArgument, "w0t? '#{gemfile}' means nothing to me."
|
94
|
+
end
|
95
|
+
|
96
|
+
gemfile = Pathname.new(local.loaded_from)
|
97
|
+
gemfile = gemfile.dirname.join('..', 'cache', "#{local.full_name}.gem").expand_path
|
98
|
+
repository.cache(gemfile)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def prune(options = {})
|
103
|
+
repository.prune(gem_dependencies, sources)
|
104
|
+
end
|
105
|
+
|
106
|
+
def list(options = {})
|
107
|
+
Bundler.logger.info "Currently bundled gems:"
|
108
|
+
repository.gems.each do |spec|
|
109
|
+
Bundler.logger.info " * #{spec.name} (#{spec.version})"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def list_outdated(options={})
|
114
|
+
outdated_gems = repository.outdated_gems
|
115
|
+
if outdated_gems.empty?
|
116
|
+
Bundler.logger.info "All gems are up to date."
|
117
|
+
else
|
118
|
+
Bundler.logger.info "Outdated gems:"
|
119
|
+
outdated_gems.each do |name|
|
120
|
+
Bundler.logger.info " * #{name}"
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
def setup_environment
|
126
|
+
unless system_gems
|
127
|
+
ENV["GEM_HOME"] = gem_path
|
128
|
+
ENV["GEM_PATH"] = gem_path
|
129
|
+
end
|
130
|
+
ENV["PATH"] = "#{bindir}:#{ENV["PATH"]}"
|
131
|
+
ENV["RUBYOPT"] = "-r#{gem_path}/environment #{ENV["RUBYOPT"]}"
|
132
|
+
end
|
133
|
+
|
134
|
+
def require_env(env = nil)
|
135
|
+
dependencies.each { |d| d.require_env(env) }
|
136
|
+
end
|
137
|
+
|
138
|
+
def root
|
139
|
+
filename.parent
|
140
|
+
end
|
141
|
+
|
142
|
+
def gem_path
|
143
|
+
@gem_path ||= root.join("vendor", "gems")
|
144
|
+
end
|
145
|
+
|
146
|
+
def bindir
|
147
|
+
@bindir ||= root.join("bin")
|
148
|
+
end
|
149
|
+
|
150
|
+
def sources
|
151
|
+
@priority_sources + @sources + @default_sources
|
152
|
+
end
|
153
|
+
|
154
|
+
def add_source(source)
|
155
|
+
@sources << source
|
156
|
+
end
|
157
|
+
|
158
|
+
def add_priority_source(source)
|
159
|
+
@priority_sources << source
|
160
|
+
end
|
161
|
+
|
162
|
+
def clear_sources
|
163
|
+
@sources.clear
|
164
|
+
@default_sources.clear
|
165
|
+
end
|
166
|
+
|
167
|
+
private
|
168
|
+
|
169
|
+
def default_sources
|
170
|
+
[GemSource.new(:uri => "http://gems.rubyforge.org"), SystemGemSource.instance]
|
171
|
+
end
|
172
|
+
|
173
|
+
def repository
|
174
|
+
@repository ||= Repository.new(gem_path, bindir)
|
175
|
+
end
|
176
|
+
|
177
|
+
def gem_dependencies
|
178
|
+
@gem_dependencies ||= dependencies.map { |d| d.to_gem_dependency }
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|