class Bundler::CLI

Public Class Methods

new(*) click to toggle source
# File lib/bundler/cli.rb, line 9
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
source_root() click to toggle source
# File lib/bundler/cli.rb, line 570
def self.source_root
  File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
end

Public Instance Methods

cache() click to toggle source
# File lib/bundler/cli.rb, line 365
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
check() click to toggle source
# File lib/bundler/cli.rb, line 97
def check
  ENV['BUNDLE_GEMFILE'] = File.expand_path(options[:gemfile]) if options[:gemfile]

  Bundler.settings[:path] = File.expand_path(options[:path]) if options[:path]
  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
clean() click to toggle source
# File lib/bundler/cli.rb, line 577
def clean
  if Bundler.settings[:path] || options[:force]
    Bundler.load.clean
  else
    Bundler.ui.error "Can only use bundle clean when --path is set or --force is set"
    exit 1
  end
end
config(name = nil, *args) click to toggle source
# File lib/bundler/cli.rb, line 430
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
console(group = nil) click to toggle source
# File lib/bundler/cli.rb, line 492
def console(group = nil)
  group ? Bundler.require(:default, *(group.split.map! {|g| g.to_sym })) : Bundler.require
  ARGV.clear

  require 'irb'
  IRB.start
end
exec(*) click to toggle source
# File lib/bundler/cli.rb, line 397
def exec(*)
  ARGV.shift # remove "exec"

  Bundler.load.setup_environment

  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
  rescue ArgumentError
    Bundler.ui.error "bundler: exec needs a command to run"
    exit 128
  end
end
gem(name) click to toggle source
# File lib/bundler/cli.rb, line 539
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 =~ %r-/
  constant_array = constant_name.split('::')
  FileUtils.mkdir_p(File.join(target, 'lib', name))
  git_user_name = %xgit config user.name`.chomp
  git_user_email = %xgit config user.email`.chomp
  opts = {
    :name           => name,
    :constant_name  => constant_name,
    :constant_array => constant_array,
    :author         => git_user_name.empty? ? "TODO: Write your name" : git_user_name,
    :email          => git_user_email.empty? ? "TODO: Write your email address" : git_user_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/LICENSE.tt"),               File.join(target, "LICENSE"),                opts)
  template(File.join("newgem/README.md.tt"),             File.join(target, "README.md"),              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) { %xgit init`; %xgit add .` }
end
help(cli = nil) click to toggle source
# File lib/bundler/cli.rb, line 23
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
init() click to toggle source
# File lib/bundler/cli.rb, line 62
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
install() click to toggle source
# File lib/bundler/cli.rb, line 161
def install
  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 (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 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

  # Can't use Bundler.settings for this because settings needs gemfile.dirname
  Bundler.settings[:path]   = nil if opts[:system]
  Bundler.settings[:path]   = "vendor/bundle" if opts[:deployment]
  Bundler.settings[:path]   = opts[:path] if opts[:path]
  Bundler.settings[:path] ||= "bundle" if opts[:standalone]
  Bundler.settings[:bin]    = opts["binstubs"] if opts[:binstubs]
  Bundler.settings[:shebang] = opts["shebang"] if opts[:shebang]
  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]
  Bundler.settings[:clean] = opts[:clean] if opts[:clean]

  Bundler::Fetcher.disable_endpoint = opts["full-index"]
  # rubygems plugins sometimes hook into the gem install process
  Gem.load_env_plugins if Gem.respond_to?(:load_env_plugins)

  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
  Installer.post_install_messages.to_a.each do |name, msg|
    Bundler.ui.confirm "Post-install message from #{name}:\n#{msg}"
  end

  clean if Bundler.settings[:clean] && Bundler.settings[:path]
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 has no remote sources. If you need "            "gems that are not already on\nyour machine, add a line like this "            "to your Gemfile:\n    source 'https://rubygems.org'"
  end
  raise e
end
open(name) click to toggle source
# File lib/bundler/cli.rb, line 477
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
outdated(*gems) click to toggle source
# File lib/bundler/cli.rb, line 315
def outdated(*gems)
  sources = Array(options[:source])
  current_specs = Bundler.load.specs

  if gems.empty? && sources.empty?
    # We're doing a full update
    definition = Bundler.definition(true)
  else
    definition = Bundler.definition(:gems => gems, :sources => sources)
  end
  options["local"] ? definition.resolve_with_cache! : definition.resolve_remotely!

  Bundler.ui.info ""
  if options["pre"]
    Bundler.ui.info "Outdated gems included in the bundle (including pre-releases):"
  else
    Bundler.ui.info "Outdated gems included in the bundle:"
  end

  out_count = 0
  # Loop through the current specs
  current_specs.each do |current_spec|
    next if !gems.empty? && !gems.include?(current_spec.name)

    active_spec = definition.index[current_spec.name].sort_by { |b| b.version }

    if !current_spec.version.prerelease? && !options[:pre] && active_spec.size > 1
      active_spec = active_spec.delete_if { |b| b.respond_to?(:version) && b.version.prerelease? }
    end

    active_spec = active_spec.last
    next if active_spec.nil?

    gem_outdated = Gem::Version.new(active_spec.version) > Gem::Version.new(current_spec.version)
    git_outdated = current_spec.git_version != active_spec.git_version
    if gem_outdated || git_outdated
      spec_version    = "#{active_spec.version}#{active_spec.git_version}"
      current_version = "#{current_spec.version}#{current_spec.git_version}"
      Bundler.ui.info "  * #{active_spec.name} (#{spec_version} > #{current_version})"
      out_count += 1
    end
    Bundler.ui.debug "from #{active_spec.loaded_from}"
  end

  Bundler.ui.info "  Your bundle is up to date!" if out_count < 1
  Bundler.ui.info ""
end
package() click to toggle source
# File lib/bundler/cli.rb, line 384
def package
  install
  # TODO: move cache contents here now that all bundles are locked
  Bundler.load.cache
end
show(gem_name = nil) click to toggle source
# File lib/bundler/cli.rb, line 287
def show(gem_name = nil)
  Bundler.load.lock

  if gem_name
    Bundler.ui.info locate_gem(gem_name)
  elsif options[:paths]
    Bundler.load.specs.sort_by { |s| s.name }.each do |s|
      Bundler.ui.info locate_gem(s.name)
    end
  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
update(*gems) click to toggle source
# File lib/bundler/cli.rb, line 259
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]}
  # rubygems plugins sometimes hook into the gem install process
  Gem.load_env_plugins if Gem.respond_to?(:load_env_plugins)

  Installer.install Bundler.root, Bundler.definition, opts
  Bundler.load.cache if Bundler.root.join("vendor/cache").exist?
  clean if Bundler.settings[:clean] && Bundler.settings[:path]
  Bundler.ui.confirm "Your bundle is updated! " +
    "Use `bundle show [gemname]` to see where a bundled gem is installed."
end
version() click to toggle source
# File lib/bundler/cli.rb, line 501
def version
  Bundler.ui.info "Bundler version #{Bundler::VERSION}"
end
viz() click to toggle source
# File lib/bundler/cli.rb, line 516
def viz
  output_file = File.expand_path(options[:file])
  output_format = options[:format]
  graph = Graph.new(Bundler.load, output_file, options[:version], options[:requirements], options[:format])

  begin
    graph.viz
  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 =~ %rGraphViz 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