Upgrade to Pro — share decks privately, control downloads, hide ads and more …

How Does Bundle Install Work?

Sponsored · SiteGround - Reliable hosting with speed, security, and support you can count on. →

How Does Bundle Install Work?

Bundler is part of every ruby developers workflow but have you ever wondered what happens when you run bundle install? We'll take a look at the parts that make up Bundler such as the Bundler Definition, CLI, RubyGems and the version resolver. We'll also take a quick look at the upcoming changes for Bundler 2

Avatar for Colby Swandale

Colby Swandale

August 30, 2017

More Decks by Colby Swandale

Other Decks in Technology

Transcript

  1. › bundle install Using bundler 1.15.4 Using diff-lcs 1.3 Using

    rack 2.0.3 Using rspec-support 3.6.0 Using rspec-core 3.6.0 Using rspec-expectations 3.6.0 Using rspec-mocks 3.6.0 Using rspec 3.6.0 Bundle complete! 2 Gemfile dependencies, 8 gems now installed. Use `bundle info [gemname]` to see where a bundled gem is installed.
  2. $ ls lib/bundler/cli add.rb common.rb gem.rb issue.rb package.rb update.rb binstubs.rb

    config.rb info.rb list.rb platform.rb viz.rb cache.rb console.rb init.rb lock.rb plugin.rb check.rb doctor.rb inject.rb open.rb pristine.rb clean.rb exec.rb install.rb outdated.rb show.rb
  3. # lib/bundler/cli/install.rb 
 module Bundler class CLI::Install attr_reader :options def

    initialize(options) @options = options end def run Bundler.ui.level = "error" if options[:quiet] warn_if_root normalize_groups ..
  4. Holds all the information and operations about your Gemfile &

    Gemfile.lock Definition Deps Sources Groups Platforms Runtime
  5. source 'https://rubygems.org' gem "rails", "4.2.8" gem "addressable", "2.4.0" if RUBY_VERSION

    < "2.0" require 'erb' require 'yaml' database_file = File.join(File.dirname(__FILE__), "config/database.yml") if File.exist?(database_file) database_config = YAML::load(ERB.new(IO.read(database_file)).result) adapters = database_config.values.map {|c| c['adapter']}.compact.uniq if adapters.any? adapters.each do |adapter| case adapter when 'mysql2' gem "mysql2", "~> 0.4.6", :platforms => [:mri, :mingw, :x64_mingw] when /postgresql/ gem "pg", "~> 0.18.1", :platforms => [:mri, :mingw, :x64_mingw] when /sqlite3/ gem "sqlite3", (RUBY_VERSION < "2.0" && RUBY_PLATFORM =~ /mingw/ ? "1.3.12" : "~>1.3.12"), :platforms => [:mri, :mingw, :x64_mingw] when /sqlserver/ gem "tiny_tds", (RUBY_VERSION >= "2.0" ? "~> 1.0.5" : "~> 0.7.0"), :platforms => [:mri, :mingw, :x64_mingw] gem "activerecord-sqlserver-adapter", :platforms => [:mri, :mingw, :x64_mingw] else warn("Unknown database adapter `#{adapter}` found in config/database.yml, use Gemfile.local to load your own database gems") end end else warn("No adapter found in config/database.yml, please configure it first") end else warn("Please configure your config/database.yml first") end
  6. DSL

  7. # lib/bundler/dsl.rb module Bundler class Dsl def self.evaluate(gemfile, lockfile, unlock)

    builder = new builder.eval_gemfile(gemfile) builder.to_definition(lockfile, unlock) end end end
  8. # lib/bundler/lockfile_parser.rb lockfile.split(/(?:\r?\n)+/).each do |line| if SOURCE.include?(line) @state = :source

    parse_source(line) elsif line == DEPENDENCIES @state = :dependency elsif line == PLATFORMS @state = :platform elsif line == RUBY @state = :ruby elsif line == BUNDLED @state = :bundled_with elsif line =~ /^[^\s]/ @state = nil elsif @state send("parse_#{@state}", line) end end
  9. GEM remote: https://rubygems.org/ specs: actioncable (5.1.3) actionpack (= 5.1.3) nio4r

    (~> 2.0) nio4r (2.1.0) actionpack (5.1.3) rails (5.1.3) actioncable (= 5.1.3) DEPENDENCIES rails (~> 5.1.3)
  10. › curl https://index.rubygems.org/versions | head -n 30 - 1 05d0116933ba44b0b5d0ee19bfd35ccc

    .cat 0.0.1 631fd60a806eaf5026c86fff3155c289 0mq 0.1.0,0.1.1,0.1.2,0.2.0,0.2.1,0.3.0,0.4.0,0.4.1,0.5.0,0.5.1,0.5.2,0.5.3 61 0xffffff 0.0.1,0.1.0 0a4a9aeae24152cdb467be02f40482f9 10to1-crack 0.1.1,0.1.2,0.1.3 e7218e76477e2137355d2e7ded094925 1234567890_ 1.0,1.1 233e818c2db65d2dad9f9ea9a27b1a30 12_hour_time 0.0.2,0.0.3,0.0.4 4e58bc03e301f704950410b713c20b69 16watts-fluently 0.3.0,0.3.1 555088e2b18e97e0293cab1d90dbb0d2 189seg 0.0.1 c4d329f7d3eb88b6e602358968be0242 196demo 0.0.0 e00c558565f7b03a438fbd93d854b7de 1_as_identity_function 1.0.0,1.0.1 bee2f0fbbc3c5c83008c0b8fc64cb168 1and1 1.1 1853e4495b036ddc5da2035523d48f0d 1hdoc 0.1.3,0.2.0,0.2.2,0.2.3,0.2.4 7076f29c196df12047a3700c4d6e5915 1pass 0.1.0,0.1.1,0.1.2 d209547aae4b8f3d67123f18f738ac99 21-day-challenge-countdown 0.1.0,0.1.1,0.1.2 57e8873fe713063f4e54e85bbbd709bb 24games 0.2.1,0.2.2,0.2.3,0.2.4 9e4d164dec466b7fe285653289e8468f 24point 0.0.1,0.0.2 80d1d0efb3811e31f40160237cc9c115 2DArray 0.1.0,0.1.2,0.1.3,0.1.5,0.1.6 848ea9e77b596cad24688a44c57a25c3 2Performant 0.0.1,0.0.2,0.0.3,0.0.4,0.0.5,0.0.6,0.0.7,0.0.8,0.1.0,0.1.1,0.1.3
  11. › curl https://index.rubygems.org/info/activerecord 5.1.0 activemodel:= 5.1.0,activesupport:= 5.1.0,arel:~> 8.0|checksum:b57713e8d 5.0.3 activemodel:=

    5.0.3,activesupport:= 5.0.3,arel:~> 7.0|checksum:6a38454ba 5.1.1 activemodel:= 5.1.1,activesupport:= 5.1.1,arel:~> 8.0|checksum:61c0dba29 4.2.9.rc1 activemodel:= 4.2.9.rc1,activesupport:= 4.2.9.rc1,arel:~> 6.0|checks 5.0.4.rc1 activemodel:= 5.0.4.rc1,activesupport:= 5.0.4.rc1,arel:~> 7.0|checks 5.0.4 activemodel:= 5.0.4,activesupport:= 5.0.4,arel:~> 7.0|checksum:d82ba1b35 4.2.9.rc2 activemodel:= 4.2.9.rc2,activesupport:= 4.2.9.rc2,arel:~> 6.0|checks 5.1.2.rc1 activemodel:= 5.1.2.rc1,activesupport:= 5.1.2.rc1,arel:~> 8.0|checks 4.2.9 activemodel:= 4.2.9,activesupport:= 4.2.9,arel:~> 6.0|checksum:0be77a1f7 5.1.2 activemodel:= 5.1.2,activesupport:= 5.1.2,arel:~> 8.0|checksum:a3757003b 5.1.3.rc1 activemodel:= 5.1.3.rc1,activesupport:= 5.1.3.rc1,arel:~> 8.0|checks 5.0.5.rc1 activemodel:= 5.0.5.rc1,activesupport:= 5.0.5.rc1,arel:~> 7.0|checks 5.1.3.rc2 activemodel:= 5.1.3.rc2,activesupport:= 5.1.3.rc2,arel:~> 8.0|checks 5.0.5.rc2 activemodel:= 5.0.5.rc2,activesupport:= 5.0.5.rc2,arel:~> 7.0|checks 5.0.5 activemodel:= 5.0.5,activesupport:= 5.0.5,arel:~> 7.0|checksum:89651a138 5.1.3.rc3 activemodel:= 5.1.3.rc3,activesupport:= 5.1.3.rc3,arel:~> 8.0|checks 5.1.3 activemodel:= 5.1.3,activesupport:= 5.1.3,arel:~> 8.0|checksum:e83b04f42 5.0.6.rc1 activemodel:= 5.0.6.rc1,activesupport:= 5.0.6.rc1,arel:~> 7.0|checks 5.1.4.rc1 activemodel:= 5.1.4.rc1,activesupport:= 5.1.4.rc1,arel:~> 8.0|checks
  12. # lib/bundler/source/rubygems.rb installed_spec = Bundler::RubyGemsGemInstaller.at(path, :install_dir => install_path.to_s, :bin_dir =>

    bin_path.to_s, :ignore_dependencies => true, :wrappers => true, :env_shebang => true, :build_args => opts[:build_args], :bundler_expected_checksum => spec.respond_to?(:checksum) && spec.checksum, :bundler_extension_cache_path => extension_cache_path(spec) ).install