peritor-bundler 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
+ else
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
@@ -0,0 +1,174 @@
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
+ shallow = options[:shallow]
142
+
143
+ if source = @git || @git_sources[git]
144
+ if ref && source.ref != ref
145
+ raise GitSourceError, "'#{git}' already specified with ref: #{source.ref}"
146
+ elsif branch && source.branch != branch
147
+ raise GitSourceError, "'#{git}' already specified with branch: #{source.branch}"
148
+ end
149
+
150
+ source.required_specs << name
151
+ source.add_spec(Pathname.new(options[:path] || '.'), name, version) if version
152
+ source
153
+ else
154
+ git(git, :ref => ref, :branch => branch, :shallow => shallow) do
155
+ _handle_git_option(name, version, options)
156
+ end
157
+ end
158
+ end
159
+
160
+ def _combine_only(only)
161
+ return @only unless only
162
+ only = Array(only).compact.uniq.map { |o| o.to_s }
163
+ only &= @only if @only
164
+ only
165
+ end
166
+
167
+ def _combine_except(except)
168
+ return @except unless except
169
+ except = Array(except).compact.uniq.map { |o| o.to_s }
170
+ except |= @except if @except
171
+ except
172
+ end
173
+ end
174
+ 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