Eurucamp 2015: Deep Diving: How to Explore a new Codebase

Eurucamp 2015: Deep Diving: How to Explore a new Codebase

As a developer, diving in a new code base is not uncommon: you’ve just been hired, you change projects, you want to help an open source project, the open source library your project depends on is buggy, etc. It’s like swimming through a underwater cave, you don’t know what treasures or monsters you’ll find, if the path is treacherous, or if it’s a true labyrinth where you’ll get lost. However, if you plan your visit, you can prepare, equip yourself, and survive to find the gem you’re looking for…

code snippet to trace the whole call graph from a piece of code https://gist.github.com/toch/82fd93ca449500d21f00

3f8fcddf7ab5d1bd90b0a0a9adfd6527?s=128

Christophe Philemotte

August 01, 2015
Tweet

Transcript

  1. Deep Diving: How to Explore a New Codebase Andy Spearing

    © 2009
  2. _toch toch Hi, I'm Christophe

  3. @matylda © 2011 Intro

  4. @matylda © 2011 The most common task

  5. continuous typing

  6. None
  7. but continuous reading Jono Witts © 2008

  8. Each written line is read at least 1 time Gavin

    St. Ours © 20013
  9. • 300 dev days • 14633 LOC • 634595 Changed

    lines • → 634595 / 14633 ~ 43 changed LOC / LOC
  10. For 1 final line, I read at least 43 lines.

  11. None
  12. How to Dive into a project Stuart Hamilton © 2008

  13. DO NOT Wander without a plan Felix Esteban © 2004

  14. Journey Needs Plan Peter Southwood © 20011

  15. Plan 1. Goal 2. Map 3. Equipment & Dive 4.

    Next? Peter Southwood © 20011
  16. 1. Goal Peter Southwood © 20011

  17. ➔ fix a bug ➔ implement a feature ➔ write

    some doc ➔ style the code ➔ refactor a small piece of code ➔ simply use it
  18. None
  19. http_proxy=http://127.0.0.1 \ ruby -e " require 'open-uri' open( 'http://google.com', proxy:

    nil ) "
  20. ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:878:in `initialize': Connection refused - connect(2) (Errno::ECONNREFUSED) from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:878:in `open'

    from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:878:in `block in connect' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/timeout.rb:52:in `timeout' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:877:in `connect' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:862:in `do_start' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:851:in `start' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:313:in `open_http' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:708:in `buffer_open' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:210:in `block in open_loo from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:208:in `catch' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:208:in `open_loop' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:149:in `open_uri' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:688:in `open' from ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:34:in `open' from -e:1:in `<main>'
  21. 2. Map Peter Southwood © 20011

  22. Find the Map ➔ Repository URI ➔ Project URI ➔

    Intro Doc: README
  23. Find the Map • https://github.com/ruby/ruby • https://bugs.ruby-lang.org/ • https://github.com/ruby/ruby/blob/trunk/ README.md

  24. Find the Legend

  25. a Legend

  26. Find the Legend ➔ CONTRIBUTING Guideline

  27. Find the Legend ➔ CONTRIBUTING Guideline https://github.com/ruby/ruby/blob/trunk/ CONTRIBUTING.md

  28. Find the Legend ➔ CONTRIBUTING Guideline https://github.com/ruby/ruby/blob/trunk/ CONTRIBUTING.md

  29. Find the Legend ➔ CONTRIBUTING Guideline ➔ Directory Structure

  30. Find the Legend ➔ CONTRIBUTING Guideline ➔ Directory Structure

  31. Find the Legend ➔ CONTRIBUTING Guideline ➔ Directory Structure ➔

    Talk to other contributors, maintainers
  32. Find the Legend ➔ CONTRIBUTING Guideline ➔ Directory Structure ➔

    Talk to other contributors, maintainers ➔ Participate to the dev meeting
  33. If blocked? ➔ ASK!

  34. Boris Dimitrov © 20009 3. Equipment & Dive

  35. Get a Toolbelt ➔ Pick an Editor

  36. xkcd

  37. Get a Toolbelt ➔ Pick an Editor ➔ Bundle

  38. $ cd GitLab $ bundle viz

  39. $ cd GitLab $ bundle viz

  40. $ cd GitLab $ bundle viz

  41. Get a Toolbelt ➔ Pick an Editor ➔ Bundle ➔

    Run Tests
  42. Get a Toolbelt ➔ Pick an Editor ➔ Bundle ➔

    Run Tests ➔ Others
  43. Get a Toolbelt ➔ ST3 ➔ Apply a Patch &

    Use it ➔ MRI WIKI DeveloperHowto ➔ Sign up to Ruby Redmine
  44. Use your Toolbelt ➔ Run the App & Use it

  45. http_proxy=http://127.0.0.1 \ ruby -e " require 'open-uri' open( 'http://google.com', proxy:

    nil ) "
  46. Use your Toolbelt ➔ Run the App & Use it

    ➔ Read the Code
  47. $ wc -l *.rb 1001 common.rb 257 ftp.rb 1676 generic.rb

    106 http.rb 22 https.rb 260 ldap.rb 20 ldaps.rb 280 mailto.rb 3622 total open-uri
  48. ➔ Find proxy management ➔ Understand how open_http works ➔

    Spot the bug URI
  49. ➔ Trace the Calls Dive into URI

  50. def get_call_graph_on scope = {} trace = TracePoint.new(:call, :line) do

    |tp| case tp.event when :call then puts "#{tp.path}:#{tp.lineno} #{tp.defined_class}::#{tp.method_id} called from " \ "#{scope[:path]}:#{scope[:lineno]} #{scope[:class]}::#{scope[:method_id]}" when :line then scope = { event: :line, lineno: tp.lineno, path: tp.path, class: tp.defined_class, method_id: tp.method_id } end end trace.enable yield trace.disable end
  51. require 'open-uri' get_call_graph_on do open( 'http://google.com', proxy: nil ) end

  52. ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:28 Kernel::open ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:746 #<Class:URI>::parse ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:209 URI::Parser::parse ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:120 URI::Parser::split ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:659 #<Class:URI>::scheme_list

    ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:659 #<Class:URI>::scheme_list ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/http.rb:83 URI::HTTP::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:173 URI::Generic::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:342 URI::Generic::set_scheme ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:523 URI::Generic::set_userinfo ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:556 URI::Generic::split_userinfo ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:617 URI::Generic::set_host ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:709 URI::Generic::set_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:842 URI::Generic::set_path ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:907 URI::Generic::set_query ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:970 URI::Generic::set_opaque ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:779 URI::Generic::set_registry ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:1013 URI::Generic::set_fragment ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:36 URI::Generic::default_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:29 #<Class:URI::Generic>::defaul ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:36 URI::Generic::default_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:29 #<Class:URI::Generic>::defaul ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:709 URI::Generic::set_port
  53. ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:28 Kernel::open ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:746 #<Class:URI>::parse ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:209 URI::Parser::parse ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:120 URI::Parser::split ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:659 #<Class:URI>::scheme_list

    ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:659 #<Class:URI>::scheme_list ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/http.rb:83 URI::HTTP::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:173 URI::Generic::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:342 URI::Generic::set_scheme ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:523 URI::Generic::set_userinfo ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:556 URI::Generic::split_userinfo ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:617 URI::Generic::set_host ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:709 URI::Generic::set_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:842 URI::Generic::set_path ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:907 URI::Generic::set_query ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:970 URI::Generic::set_opaque ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:779 URI::Generic::set_registry ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:1013 URI::Generic::set_fragment ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:36 URI::Generic::default_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:29 #<Class:URI::Generic>::defaul ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:36 URI::Generic::default_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:29 #<Class:URI::Generic>::defaul ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:709 URI::Generic::set_port
  54. ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:659 #<Class:URI>::scheme_list ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:659 #<Class:URI>::scheme_list ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/http.rb:83 URI::HTTP::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:173 URI::Generic::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:342 URI::Generic::set_scheme

    ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:523 URI::Generic::set_userinfo ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:556 URI::Generic::split_userinfo ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:617 URI::Generic::set_host ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:709 URI::Generic::set_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:842 URI::Generic::set_path ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:907 URI::Generic::set_query ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:970 URI::Generic::set_opaque ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:779 URI::Generic::set_registry ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:1013 URI::Generic::set_fragment ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:36 URI::Generic::default_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:29 #<Class:URI::Generic>::defaul ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:36 URI::Generic::default_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:29 #<Class:URI::Generic>::defaul ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:709 URI::Generic::set_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:687 OpenURI::OpenRead::open ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:130 #<Class:OpenURI>::open_uri
  55. ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:29 #<Class:URI::Generic>::defaul ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:709 URI::Generic::set_port ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:687 OpenURI::OpenRead::open ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:130 #<Class:OpenURI>::open_uri ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:120 #<Class:OpenURI>::scan_open_opt

    ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:111 #<Class:OpenURI>::check_options ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:166 #<Class:OpenURI>::open_loop ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:376 OpenURI::Buffer::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:707 URI::HTTP::buffer_open ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:253 #<Class:OpenURI>::open_http ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:571 URI::Generic::userinfo ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3 ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:183 MonitorMixin::mon_enter ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:1118 #<Class:Gem>::find_u ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:889 #<Class:Gem>::suffixe ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/specification.rb:1168 #<Clas unresolved_deps ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:194 MonitorMixin::mon_exit ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:244 MonitorMixin::mon_check_owner ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3
  56. ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:707 URI::HTTP::buffer_open ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:253 #<Class:OpenURI>::open_http ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:571 URI::Generic::userinfo ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3 ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:183 MonitorMixin::mon_enter ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:1118

    #<Class:Gem>::find_u ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:889 #<Class:Gem>::suffixe ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/specification.rb:1168 #<Clas unresolved_deps ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:194 MonitorMixin::mon_exit ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:244 MonitorMixin::mon_check_owner ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3 ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:183 MonitorMixin::mon_enter ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:1118 #<Class:Gem>::find_u ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:889 #<Class:Gem>::suffixe ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/specification.rb:1168 #<Clas unresolved_deps ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:194 MonitorMixin::mon_exit ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:244 MonitorMixin::mon_check_owner ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3
  57. ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:707 URI::HTTP::buffer_open ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/open-uri.rb:253 #<Class:OpenURI>::open_http ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:571 URI::Generic::userinfo ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3 ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:183 MonitorMixin::mon_enter ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:1118

    #<Class:Gem>::find_u ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:889 #<Class:Gem>::suffixe ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/specification.rb:1168 #<Clas unresolved_deps ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:194 MonitorMixin::mon_exit ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:244 MonitorMixin::mon_check_owner ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3 ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:183 MonitorMixin::mon_enter ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:1118 #<Class:Gem>::find_u ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:889 #<Class:Gem>::suffixe ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/specification.rb:1168 #<Clas unresolved_deps ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:194 MonitorMixin::mon_exit ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:244 MonitorMixin::mon_check_owner ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3
  58. ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:244 MonitorMixin::mon_check_owner ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3 ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:183 MonitorMixin::mon_enter ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:1118 #<Class:Gem>::find_u ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:889 #<Class:Gem>::suffixe ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/specification.rb:1168

    #<Clas Specification>::unresolved_deps ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:194 MonitorMixin::mon_exit ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:244 MonitorMixin::mon_check_owner ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3 ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:183 MonitorMixin::mon_enter ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:1118 #<Class:Gem>::find_u ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:889 #<Class:Gem>::suffixe ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/specification.rb:1168 #<Clas Specification>::unresolved_deps ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:194 MonitorMixin::mon_exit ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:244 MonitorMixin::mon_check_owner ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:3 ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:183 MonitorMixin::mon_enter ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/site_ruby/2.0.0/rubygems.rb:1118 #<Class:Gem>::find_u
  59. ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:194 MonitorMixin::mon_exit ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/monitor.rb:244 MonitorMixin::mon_check_owner ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:660 URI::Generic::hostname ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/http.rb:95 URI::HTTP::request_uri ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:1442 URI::Generic::path_query

    ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:608 #<Class:Net::HTTP>::new ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:632 Net::HTTP::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:993 #<Class:Net::HTTP>::proxy_class ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:847 Net::HTTP::start ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:861 Net::HTTP::do_start ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:867 Net::HTTP::connect ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:1012 Net::HTTP::proxy? ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/net/http.rb:1026 Net::HTTP::proxy_uri ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:990 Kernel::URI ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:746 #<Class:URI>::parse ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:209 URI::Parser::parse ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:120 URI::Parser::split ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:659 #<Class:URI>::scheme_list ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/common.rb:659 #<Class:URI>::scheme_list ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/http.rb:83 URI::HTTP::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:173 URI::Generic::initialize ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:342 URI::Generic::set_scheme ~/.rvm/rubies/ruby-2.0.0-p247/lib/ruby/2.0.0/uri/generic.rb:523 URI::Generic::set_userinfo
  60. http = klass.new( target_host, target_port )

  61. ➔ Trace the Calls ➔ Search the Source Dive into

    URI
  62. Search the Source $ grep -nr "open_http". ./open-uri.rb:253: def OpenURI.open_http(buf,

    target, proxy, option ./open-uri.rb:708: OpenURI.open_http(buf, self, proxy, options) ./open-uri.rb:717: OpenURI.open_http(buf, self, proxy, option
  63. Search the Source $ grep -rn "class HTTP " .

    ./net/http.rb:384: class HTTP < Protocol ./uri/http.rb:22: class HTTP < Generic
  64. Search the Source $ EDITOR=subl \ bundle open gitlab_omniauth-ldap

  65. ➔ Trace the Calls ➔ Search the Source ➔ Get

    Context with a Test Dive into URI
  66. Get Context with a Test context "without params['markdown_img']" do it

    "returns an error" do get_call_graph_on do post :upload_image, id: project.to_param, format: :json end expect(response.status).to eq(422) end end
  67. Use your Toolbelt ➔ Run the App & Use it

    ➔ Read the Code ➔ Edit the Code
  68. http = proxy ? klass.new(target_host, target_port) : klass.new(target_host, target_port, nil)

  69. Use your Toolbelt ➔ Run the App & Use it

    ➔ Read & Edit the Code ➔ Report a bug ➔ Submit a contribution
  70. None
  71. If blocked? ➔ ASK!

  72. 4. Next? Peter Southwood © 20011

  73. How long? ➔ Keep it reasonable at first ➔ From

    ½ to 1 day
  74. Find Next Goal ➔ Fix a bug ➔ Develop a

    feature ➔ Run Static Analysis Tools ➔ Review a PullRequest
  75. Iterate ➔ :) Jean-Marc Kuffer © 2007

  76. If blocked? ➔ ASK!

  77. Outro 1. Goal 2. Map 3. Equipment & Dive

  78. ? _toch toch