peritor-bundler 0.7.0

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.
@@ -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