12 hours to rate a rails application

Post on 17-May-2015

2.369 views 0 download

Tags:

description

improved version of 12 hours to rate a rails application - modified after feedback from Euruko and ScotRuby. As presented at Railsconf

Transcript of 12 hours to rate a rails application

hours to rate a Rails application

Elise Huard @elise_huardhttp://jabberwocky.eu

Tuesday 8 June 2010

Acquisition

Tuesday 8 June 2010

Maintenance

Tuesday 8 June 2010

12 hours To Rate a Rails Application

12:00

Tuesday 8 June 2010

Team

Tuesday 8 June 2010

One man’s application

Tuesday 8 June 2010

Maintenance

Maintenance

Innovator

Automator

Control freak

Tuesday 8 June 2010

...

Tuesday 8 June 2010

Vision

photo by OneEighteen

vision

Tuesday 8 June 2010

Methodology

Tuesday 8 June 2010

docman on flickr

issue TrackerVersion control

Tuesday 8 June 2010

Back seat driver

Tuesday 8 June 2010

10:00

12 hours To Rate a Rails Application

Tuesday 8 June 2010

Try the app

Björn Söderqvist on Flickr

Tuesday 8 June 2010

does it work ?

Tuesday 8 June 2010

09:45

12 hours To Rate a Rails Application

Tuesday 8 June 2010

Rails version

Tuesday 8 June 2010

plugins and gems

Photo Lex on Flickr

Tuesday 8 June 2010

Tuesday 8 June 2010

managing updatesBundlerpiston

git submodules(svn externals)

Tuesday 8 June 2010

LicensesBSD, MIT, Apache ...

Tuesday 8 June 2010

NIH syndrom

Tuesday 8 June 2010

Run Tests

Tuesday 8 June 2010

09:00

12 hours To Rate a Rails Application

Tuesday 8 June 2010

Lots of code

Tuesday 8 June 2010

config/routes.rb

match ‘/’, :to => ‘root#index’ match ‘root’, :to => ‘root#index’

namespace :admin do resources :grids do resources :nodes resources :edges do collection do post :all post :update_all end end resources :walkers endend resources :nodes, :only => [:show,:new,:create,:destroy] do put :directions, :on => :collectionend

resources :walkers, :only => [:show,:new,:create,:destroy] do get :select, :on => :collectionendresources :itineraries, :only => [:show]

map.four_oh_four '*path' , :controller => 'four_oh_fours'Tuesday 8 June 2010

modelsrailroad -M | dot Tpng > models.png

rubymine ctrl-alt-D

Tuesday 8 June 2010

names

“There are only two hard things in Computer Science: cache invalidation and naming things”

Phil Karlton

Tuesday 8 June 2010

08:30

12 hours To Rate a Rails Application

Tuesday 8 June 2010

Metricsknow thine tools

docman on flickr

Tuesday 8 June 2010

LOC

rake stats+----------------------+-------+-------+---------+---------+-----+-------+| Name | Lines | LOC | Classes | Methods | M/C | LOC/M |+----------------------+-------+-------+---------+---------+-----+-------+| Controllers | 2702 | 2150 | 36 | 158 | 4 | 11 || Helpers | 358 | 303 | 0 | 22 | 0 | 11 || Models | 1358 | 1104 | 30 | 117 | 3 | 7 || Libraries | 2286 | 1655 | 38 | 152 | 4 | 8 || Integration tests | 0 | 0 | 0 | 0 | 0 | 0 || Functional tests | 1687 | 1322 | 31 | 195 | 6 | 4 || Unit tests | 1356 | 1079 | 27 | 158 | 5 | 4 |+----------------------+-------+-------+---------+---------+-----+-------+| Total | 9747 | 7613 | 162 | 802 | 4 | 7 |+----------------------+-------+-------+---------+---------+-----+-------+ Code LOC: 5212 Test LOC: 2401 Code to Test Ratio: 1:0.5

Tuesday 8 June 2010

RubyParser and Parsetree

Ryan Davis and Eric Hodel(‘Ruby Sadists’)

Tuesday 8 June 2010

RubyParser and Parsetree

Abstract syntax treeRubyParser.new.parse(File.read(‘metrics.rb’),‘metric.rb’)

class Metrics def probe puts "good" end end

s(:class,:Metrics, nil, s(:scope, s(:defn,:probe, s(:args), s(:scope, s(:block, s(:call, nil, :puts, s(:arglist, s(:str, "good"))))))))

Symbolic Expression (Sexp)

Tuesday 8 June 2010

RubyParser and Parsetree

Abstract syntax treeRubyParser.new.parse(File.read(‘metrics.rb’),‘metric.rb’)

class Metrics def probe puts "good" end end

s(:class,:Metrics, nil, s(:scope, s(:defn,:probe, s(:args), s(:scope, s(:block, s(:call, nil, :puts, s(:arglist, s(:str, "good"))))))))

Symbolic Expression (Sexp)

Ruby2Ruby

Tuesday 8 June 2010

RubyParser

Parsetree

pure ruby

ruby and inline c< 1.9

swap out with Ripper ?

Tuesday 8 June 2010

cyclomatic complexity

size

code complexity code similarities

test coverage

antipatterns

rake stats

Flay

ReekRoodi

Flog

Saikuro

Heckle Rcov

Rails

R_B_P

Tuesday 8 June 2010

flog‘the pain your code

is in’

Tuesday 8 June 2010

FLOG

flog lib/flog.rb 647.8: flog total 13.8: flog/method average

87.5: Flog#output_details 58.8: Flog#process_iter 54.2: Flog#flog 48.8: Flog#parse_options 34.1: Flog#none 23.2: Flog#output_method_details 22.1: Flog#score_method 16.0: Flog#process_block_pass 15.6: Flog#report 15.2: Flog#expand_dirs_to_files 15.0: Flog#klass_name

Tuesday 8 June 2010

FLOG

Assignment Branch Condition (ABC) def score_method(tally) a, b, c = 0, 0, 0 tally.each do |cat, score| case cat when :assignment then a += score when :branch then b += score else c += score end end Math.sqrt(a*a + b*b + c*c) end

Tuesday 8 June 2010

FLOG

Weighing the AST with factors def process_if(exp) add_to_score :branch process exp.shift # cond penalize_by 0.1 do process exp.shift # true process exp.shift # false end s() end

Tuesday 8 June 2010

FLOG

Very good: < 20All Right: < 50

Tuesday 8 June 2010

FLAYcode similarities

Tuesday 8 June 2010

flay *.rb Total score (lower is better) = 621

1) IDENTICAL code found in :defn (mass*2 = 188) channel.rb:48 clip.rb:80

2) Similar code found in :defn (mass = 93) channel.rb:150 clip.rb:110 clip.rb:116

3) Similar code found in :defs (mass = 58) contact.rb:32 contact.rb:37

FLAY

Tuesday 8 June 2010

RubyParser def mass @mass ||= self.structure.flatten.size end

Hash of structure of nodes with mass > threshold self.hashes[node.structural_hash] << node

analyze: if same hash = similarif same node = identical

FLAY

Tuesday 8 June 2010

Saikuroサイクロ

cyclomatic complexity

Tuesday 8 June 2010

Saikuro

Tuesday 8 June 2010

Saikuro

ruby-lex

every keyword is interpreted into ‘state’

state used to calculateif, unless, while, until, for, elsif, when, rescue

(blocks)Recursively

Tuesday 8 June 2010

Saikuro

Good:methods < 5

Tuesday 8 June 2010

Roodi‘Ruby Object Oriented Design Inferometer’

nutmeg66 on flickr

Tuesday 8 June 2010

Roodi

app/controllers/itineraries_controller.rb:4 - Method name "show" cyclomatic complexity is 14. It should be 8 or less.app/models/itinerary.rb:41 - Block cyclomatic complexity is 6. It should be 4 or less.app/controllers/itineraries_controller.rb:4 - Method "show" has 30 lines. It should have 20 or less.app/helpers/application_helper.rb:27 - Method "clippy" has 26 lines. It should have 20 or less.

Tuesday 8 June 2010

Roodi

RubyParservisitor pattern visitor: checker (Configurable) visitable: parsed nodes= extensible

Tuesday 8 June 2010

Reek

Tuesday 8 June 2010

Reek

UserSessionsController has no descriptive comment (Irresponsible Module) UserSessionsController#destroy calls current_user_session twice (Duplication)app/controllers/users_controller.rb -- 5 warnings: UsersController has no descriptive comment (Irresponsible Module) UsersController tests @aid_app at least 4 times (Simulated Polymorphism) UsersController#create calls params 3 times (Duplication) UsersController#create calls params[:user] 3 times (Duplication)...

Tuesday 8 June 2010

Reek

RubyParserextends parsed nodes

traverses nodesreturns code after Ruby2Ruby

Tuesday 8 June 2010

rails_best_practices

kamoda on Flickr

Tuesday 8 June 2010

./app/controllers/ws/vmg/aid_user_accounts_controller.rb:160 - move model logic into model (@aid_user_account called_count > 4)./app/controllers/ws/vmg/ipt_controller.rb:102 - move model logic into model (xml called_count > 4)./app/controllers/ws/vmg/ipt_controller.rb:102 - move model logic into model (pf called_count > 4)./config/routes.rb:3 - overuse route customizations (customize_count > 3)./config/routes.rb:35 - overuse route customizations (customize_count > 3)./app/models/vmg/scenario.rb:41 - keep finders on their own model

rails_best_practices

Tuesday 8 June 2010

rails_best_practices

Visitor patternvisitor : checking_visitorvisitable: visitable sexp

Tuesday 8 June 2010

Churn

Tuesday 8 June 2010

Churn

Not only classes but also methods(RubyParser)

Version control: git, Hg, svnLocates changes in source using logs

(as in git log)

Tuesday 8 June 2010

Churn

+-------------------------------------------------+---------------+| file_path | times_changed |+-------------------------------------------------+---------------+| db/schema.rb | 26 || config/routes.rb | 24 || app/controllers/application_controller.rb | 22 || app/controllers/add_apps_controller.rb | 22 || config/environment.rb | 20 || app/views/layouts/application.html.erb | 20 || app/models/ability.rb | 18 |...

Tuesday 8 June 2010

Churn

common sense ... mostly useful in maintenance phase

Tuesday 8 June 2010

Rcov

Tuesday 8 June 2010

Rcov

Total coverage: comments included

Tuesday 8 June 2010

Rcov

Executes testkeeps track of the executed linesUsing C extension when possible

to hook into MRI

(experimental for 1.9)

Tuesday 8 June 2010

Rcov

good: 100% coverage

Tuesday 8 June 2010

Heckle

Tuesday 8 June 2010

Heckle

ParseTree + Ruby2Rubymutate

Tuesday 8 June 2010

Heckle

Initial tests pass. Let's rumble.

************************************************************************* AidApp#property_names loaded with 4 possible mutations**********************************************************************

4 mutations remaining...Replacing AidApp#property_names with:

--- original+++ mutation def property_names- (meta_policy and meta_policy.property_names_for(:aid_app))+ (nil and meta_policy.property_names_for(:aid_app)) end

Tuesday 8 June 2010

time-consuming: combinatorialsmore for small programs (gems, scripts)

doesn’t work for ruby 1.9 (ParseTree)

Heckle

Tuesday 8 June 2010

cyclomatic complexity

size

code complexity code similarities

test coverage

antipatterns

rake stats

Flay

ReekRoodi

Flog

Saikuro

Heckle Rcov

Rails

R_B_P

Tuesday 8 June 2010

metric_fu

Tuesday 8 June 2010

what these metrics don’t tell you

Bugs

Tuesday 8 June 2010

what these metrics don’t tell you

code performanceRuby Profiling

Tuesday 8 June 2010

Reads like a book

Tuesday 8 June 2010

06:30

12 hours To Rate a Rails Application

Tuesday 8 June 2010

OrbitalJoe on flickr

check out the good stuff

Tuesday 8 June 2010

Database

db/schema.rbseed data

everything in migrations ?

Tuesday 8 June 2010

views

Bad:unindenteddivitis(too much) javascript in bodytoo much logic in viewiew

Tuesday 8 June 2010

04:30

12 hours To Rate a Rails Application

Tuesday 8 June 2010

Tests

Tuesday 8 June 2010

maintainable test suite

tests = software

changes in implementationchanges in requirements

Tuesday 8 June 2010

maintainable test suite

express code responsibilityhide implementation detail

Tuesday 8 June 2010

maintainable test suite

-> expressive code

(DRY not mandatory)

Tuesday 8 June 2010

02:30

12 hours To Rate a Rails Application

Tuesday 8 June 2010

Deployment

photo by devilarts on flickrTuesday 8 June 2010

Deployment

Tuesday 8 June 2010

Deployment

Automation, automation, automation

Tuesday 8 June 2010

Deployment

deployment = softwaresame rules apply

Tuesday 8 June 2010

Deployment

TrafficPerformance tests

Bottlenecks

Tuesday 8 June 2010

01:00

12 hours To Rate a Rails Application

Tuesday 8 June 2010

Brownie Points

Tuesday 8 June 2010

Continuous integration

... and they’re using it

Tuesday 8 June 2010

Documentation of any kind

... and it’s up to date

Tuesday 8 June 2010

monitoringexception notification

Log analyzers

Tuesday 8 June 2010

testing javascript

Continuous performance testing

Tuesday 8 June 2010

00:00

12 hours To Rate a Rails Application

Tuesday 8 June 2010