12 Hours To Rate A Rails Application

Preview:

DESCRIPTION

In some situations, it's useful to be able to evaluate a Rails application quickly.I talk about how I work to get the most data as possible to get a good picture of whether an application is well-maintained, and will be easy to maintain later.

Citation preview

hours to rate a Rails application

Elise Huard @elise_huardhttp://jabberwocky.eu

Wednesday 31 March 2010

Acquisition

Wednesday 31 March 2010

Maintenance

Wednesday 31 March 2010

12 hours To Rate a Rails Application

12:00

Wednesday 31 March 2010

Team

Wednesday 31 March 2010

Team: use your gut

Wednesday 31 March 2010

One man’sapplication

Wednesday 31 March 2010

innovator

automator

Maintenance

Maintenance

Control Freak

Wednesday 31 March 2010

...

Wednesday 31 March 2010

Vision

Wednesday 31 March 2010

Methodology

Wednesday 31 March 2010

Bug TrackerVersion control

Wednesday 31 March 2010

Back seat driver

Wednesday 31 March 2010

10:00

12 hours To Rate a Rails Application

Wednesday 31 March 2010

Try the app

Wednesday 31 March 2010

does it work ?

Wednesday 31 March 2010

09:45

12 hours To Rate a Rails Application

Wednesday 31 March 2010

Rails version

Wednesday 31 March 2010

plugins and gems

Wednesday 31 March 2010

Wednesday 31 March 2010

managing updatespiston

git submodules(svn externals)

Wednesday 31 March 2010

Licenses

Wednesday 31 March 2010

NIH syndrom

Wednesday 31 March 2010

09:00

12 hours To Rate a Rails Application

Wednesday 31 March 2010

All that code

Wednesday 31 March 2010

config/routes.rb

map.root :controller => 'root', :action => 'index'

map.namespace :admin do |admin| admin.resources :grids do |grid| grid.resources :nodes grid.resources :edges, :collection => {:all => :post, :update_all => :post} grid.resources :walkers end end

map.resources :nodes, :only => [:new,:create,:show,:destroy], :collection => {:directions => :put} map.resources :walkers, :only => [:show,:new,:create,:destroy], :collection => {:select => :get} map.resources :itineraries, :only => [:show]

map.four_oh_four '*path' , :controller => 'four_oh_fours'

Wednesday 31 March 2010

modelsrailroad -M | dot Tpng > models.png

rubymine ctrl-alt-Duml dumper (needs maintenance)

Wednesday 31 March 2010

names

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

Phil Karlton

Wednesday 31 March 2010

08:30

12 hours To Rate a Rails Application

Wednesday 31 March 2010

Coffee

Wednesday 31 March 2010

metrics

Wednesday 31 March 2010

Know thine tools

Wednesday 31 March 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

Wednesday 31 March 2010

RubyParser and Parsetree

Ryan Davis and Eric Hodel(‘Ruby Sadists’)

Wednesday 31 March 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

Wednesday 31 March 2010

flog‘the pain your

code is in’

Wednesday 31 March 2010

FLOG

Weighing the AST with factorsAssignment Branch Condition (ABC) 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

Wednesday 31 March 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

Wednesday 31 March 2010

FLOG

Very good: < 20All Right: < 50

Wednesday 31 March 2010

FLAYcode similarities

Wednesday 31 March 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

Wednesday 31 March 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

Wednesday 31 March 2010

Saikuroサイクロ

cyclomatic complexity

Wednesday 31 March 2010

Saikuro

ruby-lex

every keyword is interpreted into ‘state’

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

(blocks)Recursively

Wednesday 31 March 2010

Saikuro

Wednesday 31 March 2010

Saikuro

Good:methods < 5

Wednesday 31 March 2010

RoodiRuby Object Oriented Design Inferometer (what ?)“design issues”

Wednesday 31 March 2010

Roodi

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

Wednesday 31 March 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.

Wednesday 31 March 2010

Reek

RubyParserextends parsed nodes

traverses nodesreturns code after Ruby2Ruby

Wednesday 31 March 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)...

Wednesday 31 March 2010

Churn

Frequent changes may indicate issue

Wednesday 31 March 2010

Churn

Not only classes but also methods(RubyParser)

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

(as in git log)

Wednesday 31 March 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 |...

Wednesday 31 March 2010

Churn

common sense ... mostly useful in maintenance phase

Wednesday 31 March 2010

Rcov

Wednesday 31 March 2010

Rcov

Executes testkeeps track of the executed linesUsing C extension when possible

to hook into MRI

(experimental for 1.9)

Wednesday 31 March 2010

Rcov

Total coverage: comments included

Wednesday 31 March 2010

Rcov

good: 100% coverage

Wednesday 31 March 2010

Heckle

Wednesday 31 March 2010

Heckle

ParseTree + Ruby2Rubymutate

doesn’t work for ruby 1.9 (ParseTree)

time-consuming: combinatorialsmore for small programs (gems,

scripts)

Wednesday 31 March 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

Wednesday 31 March 2010

cyclomatic complexity

size

code complexity code similarities

test coverage

antipatterns

rake stats

Flay

ReekRoodi

Flog

Saikuro

Heckle Rcov

Wednesday 31 March 2010

metric_fu

Wednesday 31 March 2010

06:30

12 hours To Rate a Rails Application

Wednesday 31 March 2010

Lunch

Wednesday 31 March 2010

and more Coffee

Wednesday 31 March 2010

read some code

Wednesday 31 March 2010

Expressive code

Wednesday 31 March 2010

Database

db/schema.rbseed data

everything in migrations ?

Wednesday 31 March 2010

Nested_has_many_through

Wednesday 31 March 2010

views

Bad:unindenteddivitisjavascript in the bodytoo much logic in viewiew

Wednesday 31 March 2010

04:30

12 hours To Rate a Rails Application

Wednesday 31 March 2010

run tests

Wednesday 31 March 2010

Time for tests(or autotest/ci)

Wednesday 31 March 2010

maintainable test suite

tests = software

changes in implementationchanges in requirements

Wednesday 31 March 2010

maintainable test suite

express code responsibilityhide incident detailDRY

Wednesday 31 March 2010

02:30

12 hours To Rate a Rails Application

Wednesday 31 March 2010

Deployment

Wednesday 31 March 2010

Deployment

Wednesday 31 March 2010

Deployment

Automation, automation, automation

Wednesday 31 March 2010

Deployment

deployment = softwaresame rules apply

Wednesday 31 March 2010

Traffic

Wednesday 31 March 2010

Performance testsBottlenecks

Wednesday 31 March 2010

01:00

12 hours To Rate a Rails Application

Wednesday 31 March 2010

Brownie Points

Wednesday 31 March 2010

Continuous integration

... and they’re using it

Wednesday 31 March 2010

Documentation of any kind

... and it’s up to date

Wednesday 31 March 2010

monitoringexception notification

Log analyzers

Wednesday 31 March 2010

testing javascriptsContinuous performance testing

Wednesday 31 March 2010

00:00

12 hours To Rate a Rails Application

Wednesday 31 March 2010

Recommended