class Bundler::CLI
def self.source_root
def self.source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates')) end
def cache
def cache Bundler.definition.resolve_with_cache! Bundler.load.cache Bundler.settings[:no_prune] = true if options["no-prune"] Bundler.load.lock rescue GemNotFound => e Bundler.ui.error(e.message) Bundler.ui.warn "Run `bundle install` to install missing gems." exit 128 end
def check
def check ENV['BUNDLE_GEMFILE'] = File.expand_path(options[:gemfile]) if options[:gemfile] begin not_installed = Bundler.definition.missing_specs rescue GemNotFound, VersionConflict Bundler.ui.error "Your Gemfile's dependencies could not be satisfied" Bundler.ui.warn "Install missing gems with `bundle install`" exit 1 end if not_installed.any? Bundler.ui.error "The following gems are missing" not_installed.each { |s| Bundler.ui.error " * #{s.name} (#{s.version})" } Bundler.ui.warn "Install missing gems with `bundle install`" exit 1 else Bundler.load.lock Bundler.ui.info "The Gemfile's dependencies are satisfied" end end
def config(name = nil, *args)
def config(name = nil, *args) values = ARGV.dup values.shift # remove config values.shift # remove the name unless name Bundler.ui.confirm "Settings are listed in order of priority. The top value will be used.\n" Bundler.settings.all.each do |setting| Bundler.ui.confirm "#{setting}" with_padding do Bundler.settings.pretty_values_for(setting).each do |line| Bundler.ui.info line end end Bundler.ui.confirm "" end return end if values.empty? Bundler.ui.confirm "Settings for `#{name}` in order of priority. The top value will be used" with_padding do Bundler.settings.pretty_values_for(name).each { |line| Bundler.ui.info line } end else locations = Bundler.settings.locations(name) if local = locations[:local] Bundler.ui.info "Your application has set #{name} to #{local.inspect}. This will override the " \ "system value you are currently setting" end if global = locations[:global] Bundler.ui.info "You are replacing the current system value of #{name}, which is currently #{global}" end if env = locations[:env] Bundler.ui.info "You have set a bundler environment variable for #{env}. This will take precedence " \ "over the system value you are setting" end Bundler.settings.set_global(name, values.join(" ")) end end
def console(group = nil)
def console(group = nil) group ? Bundler.require(:default, *(group.split.map! {|g| g.to_sym })) : Bundler.require ARGV.clear require 'irb' IRB.start end
def exec(*)
def exec(*) ARGV.shift # remove "exec" Bundler.setup begin # Run Kernel.exec(*ARGV) rescue Errno::EACCES Bundler.ui.error "bundler: not executable: #{ARGV.first}" exit 126 rescue Errno::ENOENT Bundler.ui.error "bundler: command not found: #{ARGV.first}" Bundler.ui.warn "Install missing gem executables with `bundle install`" exit 127 end end
def gem(name)
def gem(name) name = name.chomp("/") # remove trailing slash if present target = File.join(Dir.pwd, name) constant_name = name.split('_').map{|p| p[0..0].upcase + p[1..-1] }.join constant_name = constant_name.split('-').map{|q| q[0..0].upcase + q[1..-1] }.join('::') if constant_name =~ /-/ constant_array = constant_name.split('::') git_author_name = `git config user.name`.chomp git_author_email = `git config user.email`.chomp author_name = git_author_name.empty? ? "TODO: Write your name" : git_author_name author_email = git_author_email.empty? ? "TODO: Write your email address" : git_author_email FileUtils.mkdir_p(File.join(target, 'lib', name)) opts = {:name => name, :constant_name => constant_name, :constant_array => constant_array, :author_name => author_name, :author_email => author_email} template(File.join("newgem/Gemfile.tt"), File.join(target, "Gemfile"), opts) template(File.join("newgem/Rakefile.tt"), File.join(target, "Rakefile"), opts) template(File.join("newgem/gitignore.tt"), File.join(target, ".gitignore"), opts) template(File.join("newgem/newgem.gemspec.tt"), File.join(target, "#{name}.gemspec"), opts) template(File.join("newgem/lib/newgem.rb.tt"), File.join(target, "lib/#{name}.rb"), opts) template(File.join("newgem/lib/newgem/version.rb.tt"), File.join(target, "lib/#{name}/version.rb"), opts) if options[:bin] template(File.join("newgem/bin/newgem.tt"), File.join(target, 'bin', name), opts) end Bundler.ui.info "Initializating git repo in #{target}" Dir.chdir(target) { `git init`; `git add .` } end
def have_groff?
def have_groff? !(`which groff` rescue '').empty? end
def help(cli = nil)
def help(cli = nil) case cli when "gemfile" then command = "gemfile.5" when nil then command = "bundle" else command = "bundle-#{cli}" end manpages = %w( bundle bundle-config bundle-exec bundle-install bundle-package bundle-update gemfile.5) if manpages.include?(command) root = File.expand_path("../man", __FILE__) if have_groff? && root !~ %r{^file:/.+!/META-INF/jruby.home/.+} groff = "groff -Wall -mtty-char -mandoc -Tascii" pager = ENV['MANPAGER'] || ENV['PAGER'] || 'less -R' Kernel.exec "#{groff} #{root}/#{command} | #{pager}" else puts File.read("#{root}/#{command}.txt") end else super end end
def init
def init opts = options.dup if File.exist?("Gemfile") Bundler.ui.error "Gemfile already exists at #{Dir.pwd}/Gemfile" exit 1 end if opts[:gemspec] gemspec = File.expand_path(opts[:gemspec]) unless File.exist?(gemspec) Bundler.ui.error "Gem specification #{gemspec} doesn't exist" exit 1 end spec = Gem::Specification.load(gemspec) puts "Writing new Gemfile to #{Dir.pwd}/Gemfile" File.open('Gemfile', 'wb') do |file| file << "# Generated from #{gemspec}\n" file << spec.to_gemfile end else puts "Writing new Gemfile to #{Dir.pwd}/Gemfile" FileUtils.cp(File.expand_path('../templates/Gemfile', __FILE__), 'Gemfile') end end
def initialize(*)
def initialize(*) super the_shell = (options["no-color"] ? Thor::Shell::Basic.new : shell) Bundler.ui = UI::Shell.new(the_shell) Bundler.ui.debug! if options["verbose"] Bundler.rubygems.ui = UI::RGProxy.new(Bundler.ui) end
def install(path = nil)
def install(path = nil) opts = options.dup if opts[:without] opts[:without].map!{|g| g.split(" ") } opts[:without].flatten! opts[:without].map!{|g| g.to_sym } end # Can't use Bundler.settings for this because settings needs gemfile.dirname ENV['BUNDLE_GEMFILE'] = File.expand_path(opts[:gemfile]) if opts[:gemfile] ENV['RB_USER_INSTALL'] = '1' if Bundler::FREEBSD # Just disable color in deployment mode Bundler.ui.shell = Thor::Shell::Basic.new if opts[:deployment] if (path || opts[:path] || opts[:deployment]) && opts[:system] Bundler.ui.error "You have specified both a path to install your gems to, \n" \ "as well as --system. Please choose." exit 1 end if path && opts[:path] Bundler.ui.error "You have specified a path via `bundle install #{path}` as well as\n" \ "by `bundle install --path #{options[:path]}`. These options are\n" \ "equivalent, so please use one or the other." exit 1 end if opts["disable-shared-gems"] Bundler.ui.error "The disable-shared-gem option is no longer available.\n\n" \ "Instead, use `bundle install` to install to your system,\n" \ "or `bundle install --path path/to/gems` to install to an isolated\n" \ "location. Bundler will resolve relative paths relative to\n" \ "your `Gemfile`." exit 1 end if opts[:deployment] || opts[:frozen] unless Bundler.default_lockfile.exist? flag = opts[:deployment] ? '--deployment' : '--frozen' raise ProductionError, "The #{flag} flag requires a Gemfile.lock. Please make " \ "sure you have checked your Gemfile.lock into version control " \ "before deploying." end if Bundler.root.join("vendor/cache").exist? opts[:local] = true end Bundler.settings[:frozen] = '1' end # When install is called with --no-deployment, disable deployment mode if opts[:deployment] == false Bundler.settings.delete(:frozen) opts[:system] = true end Bundler.settings[:path] = nil if opts[:system] Bundler.settings[:path] = "vendor/bundle" if opts[:deployment] Bundler.settings[:path] = path if path Bundler.settings[:path] = opts[:path] if opts[:path] Bundler.settings[:bin] = opts["binstubs"] if opts[:binstubs] Bundler.settings[:no_prune] = true if opts["no-prune"] Bundler.settings[:disable_shared_gems] = Bundler.settings[:path] ? '1' : nil Bundler.settings.without = opts[:without] Bundler.ui.be_quiet! if opts[:quiet] Installer.install(Bundler.root, Bundler.definition, opts) Bundler.load.cache if Bundler.root.join("vendor/cache").exist? && !options["no-cache"] if Bundler.settings[:path] absolute_path = File.expand_path(Bundler.settings[:path]) relative_path = absolute_path.sub(File.expand_path('.'), '.') Bundler.ui.confirm "Your bundle is complete! " + "It was installed into #{relative_path}" else Bundler.ui.confirm "Your bundle is complete! " + "Use `bundle show [gemname]` to see where a bundled gem is installed." end if path Bundler.ui.warn "The path argument to `bundle install` is deprecated. " + "It will be removed in version 1.1. " + "Please use `bundle install --path #{path}` instead." end rescue GemNotFound => e if opts[:local] && Bundler.app_cache.exist? Bundler.ui.warn "Some gems seem to be missing from your vendor/cache directory." end if Bundler.definition.no_sources? Bundler.ui.warn "Your Gemfile doesn't have any sources. You can add one with a line like 'source :rubygems'" end raise e end
def locate_gem(name)
def locate_gem(name) spec = Bundler.load.specs.find{|s| s.name == name } raise GemNotFound, "Could not find gem '#{name}' in the current bundle." unless spec if spec.name == 'bundler' return File.expand_path('../../../', __FILE__) end spec.full_gem_path end
def lock
def lock Bundler.ui.warn "Lock is deprecated. Your bundle is now locked whenever you run `bundle install`." end
def open(name)
def open(name) editor = [ENV['BUNDLER_EDITOR'], ENV['VISUAL'], ENV['EDITOR']].find{|e| !e.nil? && !e.empty? } if editor gem_path = locate_gem(name) Dir.chdir(gem_path) do command = "#{editor} #{gem_path}" success = system(command) Bundler.ui.info "Could not run '#{command}'" unless success end else Bundler.ui.info("To open a bundled gem, set $EDITOR or $BUNDLER_EDITOR") end end
def package
def package install # TODO: move cache contents here now that all bundles are locked Bundler.load.cache end
def show(gem_name = nil)
def show(gem_name = nil) Bundler.load.lock if gem_name Bundler.ui.info locate_gem(gem_name) else Bundler.ui.info "Gems included by the bundle:" Bundler.load.specs.sort_by { |s| s.name }.each do |s| Bundler.ui.info " * #{s.name} (#{s.version}#{s.git_version})" end end end
def unlock
def unlock Bundler.ui.warn "Unlock is deprecated. To update to newer gem versions, use `bundle update`." end
def update(*gems)
def update(*gems) sources = Array(options[:source]) if gems.empty? && sources.empty? # We're doing a full update Bundler.definition(true) else Bundler.definition(:gems => gems, :sources => sources) end opts = {"update" => true, "local" => options[:local]} Installer.install Bundler.root, Bundler.definition, opts Bundler.load.cache if Bundler.root.join("vendor/cache").exist? Bundler.ui.confirm "Your bundle is updated! " + "Use `bundle show [gemname]` to see where a bundled gem is installed." end
def version
def version Bundler.ui.info "Bundler version #{Bundler::VERSION}" end
def viz
def viz output_file = File.expand_path(options[:file]) graph = Graph.new( Bundler.load ) begin graph.viz(output_file, options[:version], options[:requirements]) Bundler.ui.info output_file rescue LoadError => e Bundler.ui.error e.inspect Bundler.ui.warn "Make sure you have the graphviz ruby gem. You can install it with:" Bundler.ui.warn "`gem install ruby-graphviz`" rescue StandardError => e if e.message =~ /GraphViz not installed or dot not in PATH/ Bundler.ui.error e.message Bundler.ui.warn "The ruby graphviz gem requires GraphViz to be installed" else raise end end end