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

SpreeConf DC 2013 - Open Source War Stories

SpreeConf DC 2013 - Open Source War Stories

Managing an open source project as large as Spree comes with its own interesting challenges. I go through some of these within this talk.

These are the slides of a talk that I gave at Ruby on Ales 2013, Los Angeles Ruby Users Group in March, and SpreeConf DC in May.

Ryan Bigg

May 20, 2013
Tweet

More Decks by Ryan Bigg

Other Decks in Programming

Transcript

  1. 0 175 350 525 700 01/01/2010 01/05/2010 01/09/2010 01/01/2011 01/05/2011

    01/09/2011 01/01/2012 01/05/2012 01/09/2012 01/01/2013 Posts to Spree User Saturday, 25 May 13
  2. 0 175 350 525 700 01/01/2010 01/05/2010 01/09/2010 01/01/2011 01/05/2011

    01/09/2011 01/01/2012 01/05/2012 01/09/2012 01/01/2013 Posts to Spree User Saturday, 25 May 13
  3. 0 175 350 525 700 01/01/2010 01/05/2010 01/09/2010 01/01/2011 01/05/2011

    01/09/2011 01/01/2012 01/05/2012 01/09/2012 01/01/2013 Posts to Spree User Saturday, 25 May 13
  4. 0 225 450 675 900 01/01/2010 01/05/2010 01/09/2010 01/01/2011 01/05/2011

    01/09/2011 01/01/2012 01/05/2012 01/09/2012 01/01/2013 Posts to Spree User 855! Saturday, 25 May 13
  5. 0 225 450 675 900 01/01/2010 01/05/2010 01/09/2010 01/01/2011 01/05/2011

    01/09/2011 01/01/2012 01/05/2012 01/09/2012 01/01/2013 Posts to Spree User Saturday, 25 May 13
  6. 0 50 100 150 200 01/07/2010 01/01/2011 01/07/2011 01/01/2012 01/07/2012

    01/01/2013 Spree Issues by month Saturday, 25 May 13
  7. “I'm having the same error and restarting heroku or resetting

    the database have not fixed the problem.” boxfirepress Saturday, 25 May 13
  8. #1247 “When filing an issue on the Spree project, please

    provide these details: • A comprehensive list of steps to reproduce the issue. • The version of Spree and the version of Rails. • A list of all extensions. • Any relevant stack traces (‘Full trace’ preferred) Filing an issue ” Saturday, 25 May 13
  9. #1247 “Please don't expect help if you're going to be

    passive aggressive with us.” Saturday, 25 May 13
  10. “ I'm being openly agressive and I was only reflecting

    your rudeness. Had there been a material difference in the setup, I would've made it a point to tell you since I posted more information in the stack trace than the last person did (yet he still managed to get a reply that wasn't: you didn't follow the arbitrary rules in some guide so no help for you.)” #1247 boxfirepress Saturday, 25 May 13
  11. #1247 “I just quickly generated an app using PostgreSQL as

    the DB with Spree 1.3.2, no products loaded in the products table and going to /admin/products works fine.” Saturday, 25 May 13
  12. #1247 However, on Heroku I have now been able to

    reproduce this issue. Saturday, 25 May 13
  13. @ryanbigg not sure? Is there something wrong with it? It's

    managed by directly by a contractor… @boxfirepress Saturday, 25 May 13
  14. @ryanbigg interesting… really sorry about that. We don't actually do

    our own development, a variety of contractors do. @boxfirepress Saturday, 25 May 13
  15. @ryanbigg thanks for letting us know. We've been using a

    couple guys through oDesk for the last year, which has been a mixed bag. @boxfirepress Saturday, 25 May 13
  16. Tyler Menezes “... From presentations full of porn and jokes

    at the expense of women, DongML, to refusing to acknowledge [the] design flaw [of] semi-colons in URLs [and] mass- assignment protection ... ” Saturday, 25 May 13
  17. “Mr. Homakov is not representative of the Rails community at

    all. He is, to me, an outsider who spends his time trying to show that he’s an “uber l33t hacker” by breaking GitHub or any other Rails site. ” Saturday, 25 May 13
  18. By default there is no api key generated. I just

    managed to break into api on test installation using ?token[], one of my favourite CVEs. @radar, please take a look at Mr. Outsider's PR #2492 homakov Saturday, 25 May 13
  19. “Mr. Homakov is not representative of the Rails community at

    all. He is, to me, an outsider who spends his time trying to show that he’s an “uber l33t hacker” by breaking GitHub or any other Rails site. ” Saturday, 25 May 13
  20. commit 3c2015e5b8df36b08188978f78443e3c385548bb Author: Egor Homakov <[email protected]> Date: Sat Jan 26

    14:17:39 2013 +0700 Stringify api_key By default there is no api key generated... @radar, please take a look at Mr. Outsider's PR Fixes #2492 Saturday, 25 May 13
  21. def  index    respond_with(@collection)  do  |format|        format.json

     do          render  :json  =>  @collection.to_json(collection_serialization_options)        end    end end app/controllers/spree/api/base_controller.rb The Old API Saturday, 25 May 13
  22. def  create    if  @object.save        render  :text

     =>  "Resource  created\n",                      :status  =>  201,                      :location  =>  object_url    else        respond_with(@object.errors,  :status  =>  422)    end end app/controllers/spree/api/base_controller.rb The Old API Saturday, 25 May 13
  23. def  create    if  @object.save        render  :text

     =>  "Resource  created\n",                      :status  =>  201,                      :location  =>  object_url    else        respond_with(@object.errors,  :status  =>  422)    end end app/controllers/spree/api/base_controller.rb The Old API Saturday, 25 May 13
  24. def  index    if  params[:ids]        @products  =

     product_scope.where(:id  =>  params[:ids])    else        @products  =  product_scope.ransack(params[:q]).result    end      @products  =  @products.page(params[:page]).per(params[:per_page])      respond_with(@products) end app/controllers/spree/api/products_controller.rb The New API Saturday, 25 May 13
  25. object  false node(:count)  {  @products.count  } node(:total_count)  {  @products.total_count  }

    node(:current_page)  {  params[:page]  ?  params[:page].to_i  :  1  } node(:pages)  {  @products.num_pages  } child(@products)  do    extends  "spree/api/products/show" end app/views/spree/api/products/index.v1.rabl The New API https://github.com/nesquena/rabl Saturday, 25 May 13
  26. object  @product attributes  *product_attributes child  :variants_including_master  =>  :variants  do  

     attributes  *variant_attributes ... app/views/spree/api/products/show.v1.rabl The New API Saturday, 25 May 13
  27. def  product_attributes    [:id,  :name,  :description,  :price,  :available_on,  :permalink,  

       :count_on_hand,  :meta_description,  :meta_keywords,  :taxon_ids] end app/helpers/spree/api_helpers.rb The New API Saturday, 25 May 13
  28. module  Spree    module  AuthenticationHelpers        def  self.included(receiver)

               receiver.send  :helper_method,  :spree_login_path            receiver.send  :helper_method,  :spree_signup_path            receiver.send  :helper_method,  :spree_logout_path            receiver.send  :helper_method,  :spree_current_user        end          def  spree_current_user            current_person        end          def  spree_login_path            main_app.login_path        end          def  spree_signup_path            main_app.signup_path        end          def  spree_logout_path            main_app.logout_path        end    end end   Spree::BaseController.send  :include,  Spree::AuthenticationHelpers ApplicationController.send  :include,  Spree::AuthenticationHelpers Saturday, 25 May 13
  29. Deface::Override.new({    :name  =>  "auth_shared_login_bar",    :virtual_path  =>  "spree/shared/_nav_bar",  

       :insert_before  =>  "li#search-­‐bar",    :partial  =>  "spree/shared/login_bar" }) app/overrides/auth_login_bar.rb Saturday, 25 May 13
  30. <%  if  spree_current_user  %>    <li><%=  link_to  t(:logout),  spree_logout_path,  :method

     =>  :delete  %></li> <%  else  %>    <li><%=  link_to  t(:login),  spree_login_path  %></li>    <li><%=  link_to  t(:signup),  spree_signup_path  %></li> <%  end  %> app/views/spree/shared/_login_bar.html.erb Saturday, 25 May 13
  31. product.price = 100 I18n.locale = :en number_to_currency(product.price) $100 I18n.locale =

    :jp number_to_currency(product.price) Saturday, 25 May 13
  32. product.price = 100 I18n.locale = :en number_to_currency(product.price) $100 I18n.locale =

    :jp number_to_currency(product.price) ¥100 Saturday, 25 May 13
  33. require  'money' module  Spree    class  Money      

     def  initialize(amount,  options={})            @money  =  ::Money.new(amount  *  100,  Spree::Config[:currency])            @options  =  {}            @options[:with_currency]  =  true  if  Spree::Config[:display_currency]            @options.merge!(options)        end          def  to_s            @money.format(@options)        end    end end Saturday, 25 May 13
  34. Spree::Config[:currency] = “USD” product.price = 100 I18n.locale = :en Spree::Money.new(product.price)

    $100 I18n.locale = :jp Spree::Money.new(product.price) $100 Saturday, 25 May 13
  35. require  'money'   module  Spree    class  Money    

       attr_reader  :money          def  initialize(amount,  options={})            @money  =  ::Money.parse([amount,  (options[:currency]  ||  Spree::Config[:currency])].join)            @options  =  {}            @options[:with_currency]  =  Spree::Config[:display_currency]            @options[:symbol_position]  =  Spree::Config[:currency_symbol_position].to_sym            @options[:no_cents]  =  Spree::Config[:hide_cents]            @options.merge!(options)            #  Must  be  a  symbol  because  the  Money  gem  doesn't  do  the  conversion            @options[:symbol_position]  =  @options[:symbol_position].to_sym        end          def  to_s            @money.format(@options)        end          def  to_html            output  =  @money.format(@options.merge(:html  =>  true))            #  1)  prevent  blank,  breaking  spaces            #  2)  prevent  escaping  of  HTML  character  entities            output.gsub("  ",  "&nbsp;").html_safe        end          def  ==(obj)            @money  ==  obj.money        end    end end Saturday, 25 May 13
  36. Spree::Order.state_machine[:state]  =   StateMachine::Machine.new(Spree::Order,  :initial  =>  "cart")  do    event

     :next  do        transition  :from  =>  'cart',  :to  =>  'summary'        transition  :from  =>  'summary',  :to  =>  'complete'    end end app/models/spree/order_decorator.rb Saturday, 25 May 13
  37. 2527 Ryan Bigg (29%) 1816 Sean Schofield (21%) 501 Brian

    Quinn (5.7%) (spree) git shortlog -sn 55.7% Saturday, 25 May 13
  38. 2527 Ryan Bigg (29%) (spree) git shortlog -sn 55.7% 1816

    Sean Schofield (21%) 501 Brian Quinn (5.7%) ???? ???? ???? ???? ???? ???? Saturday, 25 May 13
  39. 2527 Ryan Bigg (29%) (spree) git shortlog -sn 1816 Sean

    Schofield (21%) 501 Brian Quinn (5.7%) ???? ???? ???? ???? ???? ???? Saturday, 25 May 13
  40. 2527 Ryan Bigg (29%) (spree) git shortlog -sn 1816 Sean

    Schofield (21%) 501 Brian Quinn (5.7%) ???? ???? ???? ???? ???? ???? Saturday, 25 May 13
  41. 871 Andre Arko (29%) 391 José Valim (13%) 324 Terence

    Lee (10%) (bundler) git shortlog -sn 52% Saturday, 25 May 13
  42. 871 Andre Arko (36.2%) 324 Terence Lee (13.4%) 312 Carl

    Lerche (12.9%) 180 Carlhuda (7.94%) 67 wycats (2.7%) (bundler) git shortlog --since "Jan 11 2010" -sn 73.14% Saturday, 25 May 13
  43. (jquery) git shortlog -sn 1714 John Resig (33.3%) 460 Dave

    Methvin (9.02%) ... 14 more people ... 52 Yehuda Katz (1.02%) Saturday, 25 May 13
  44. 3409 DHH (9.47%) 3356 Jeremy Kemper (9.32%) 2500 José Valim

    (6.94%) 2273 Aaron Patterson (6.31%) 1637 Xavier Noria (4.55%) 1099 Joshua Peek (3.05%) (rails) git shortlog -sn 39.64% Saturday, 25 May 13
  45. (rails) git shortlog -sn 63% of commits have been done

    by top 20 contributors Saturday, 25 May 13
  46. (rails) git shortlog -sn 37% of commits have been done

    by 2,155 contributors Saturday, 25 May 13
  47. (bundler) git shortlog -sn 41% of commits have been done

    by 195 contributors Saturday, 25 May 13
  48. (spree) git shortlog -sn 44% of commits have been done

    by 350 contributors Saturday, 25 May 13