External Code Reviews

  • why?

  • internal vs external

  • do's and don'ts 

Agenda

Why?

To measure wtf/minute

  • Prevent the echo-chamber

And also...

Devs

Reviewer

  • Ensure best practices and guidelines are being followed
  • To identify new best practices/good ideas 
  • To help find defects
  • To improve quality of code
  • To provide guidance and feedback
  • To share knowledge 
  • To help Rangle.io improve it's projects
  • To help developers grow

But really.....

The differences

Internal

  • per-pr
  • before merge 
  • on-going
  • frequent
  • potentially blocking
  • generally smaller scope

External

  • can be per-pr,
  • a few prs,
  • a few commits,
  • a general area of concern
  • on-going
  • less frequent
  • shouldn't be blocking
  • can be done after merging

the condiments

the commandments

*reviewer suggests* .... did you mean

Do - limit scope

  • ~200-400 lines of code
  • More likely to find a bug in 10 lines of code, than 600
  • Ask for an area to focus on
    • Specific PR
    • Specific commit
    • Specific module/area of concern

Do - limit time

  • Limit it to 60 mins of prep
  • Limit the meeting to 60 mins
  • Less than 60 on either is ok

Do - take your time

  • It's better to review 50 lines of code carefully, than 200 carelessly
  • Try to walk through the logic, not jut skim
  • Look for possible errors
  • Look for things that they might have missed, but should be considered
  • Consider the context around the code you are reviewing

Do - consider the guidelines

  • Each project is different, and not every guideline may be fully applicable.
  • Deviations should have reasons

Do - use the metrics

  • Might take extra time on the first time
  • Should hopefully not slow down subsequent reviews
    • If they do - let me know
  • If key things don't improve - escalate them

Don't - let them replace the code review

  • Meant as a baseline 
  • Should not replace in-depth code reviews

Don't - build a bikeshed

to spend time focusing on easy to grasp, but relatively unimportant things
angular.module('myModule',[])
.controller('MyCtrl', function myCtrl($rootScope)
{
    $rootScope.firstName = 'Evan'
    $rootScope.lastName = 'Schultz'
    $rootScope.fullName = $scope.firstName + ' ' + $scope.lastName;
    $("#fullName").text($rootScope.fullName)
 
});

myCtrl vs MyCtrl vs MyController shouldn't be the focus here when there are bigger issues at hand

Do - be constructive

  • Be honest - most people want feedback
  • The meeting should be a discussion, not a lecture
var person = {
  firstName: 'Evan',
  lastName: 'Schultz'
}
var makeUpperCase = R.curry(R.mapObj(function (i) {
  return i.toUpperCase()
}));

makeUpperCase(person)

Bad

var person = {
  firstName: 'Evan',
  lastName: 'Schultz'
}
var makeUpperCase = R.curry(R.mapObj(function (i) {
  return i.toUpperCase()
}));

makeUpperCase(person)

Bad

Why the hell are you currying R.mapObj?

It's totally not needed - you give Ramda a bad name, moron.

var person = {
  firstName: 'Evan',
  lastName: 'Schultz'
}
var makeUpperCase = R.curry(R.mapObj(function (i) {
  return i.toUpperCase()
}));

makeUpperCase(person)

Better

var person = {
  firstName: 'Evan',
  lastName: 'Schultz'
}
var makeUpperCase = R.curry(R.mapObj(function (i) {
  return i.toUpperCase()
}));

makeUpperCase(person)

Better

You don't need R.curry here, as most of Ramdas functions are curried by default, and it doesn't provide any value here. You could also use the R.toUpper and simplify things down to:

var makeUpperCase = R.mapObj(R.toUpper);

Don't - be overly defensive

...but do defend

  • Be open to feedback
  • Often explaining your idea or reasoning out-loud can provide extra insight to yourself, and the reviewer

Do - ask questions

  • Did you think about...
  • Did you consider...
  • Why is it this way?
  • Why didn't you .... 

Don't - focus on style

  • Let linters and beautifiers take care of this
  • ... do check up that this is setup and being used

Do - focus on substance

  • Clarity
  • Cohesion
  • Coupling
  • Encapsulation

Do - call out the crazy

  • Things can make perfect sense to those who build it, but an outsider look might see that they have gone off into the deep-end.

Do - keep an eye out for patterns

  • Are similar things being done in slightly different ways?
  • Are there areas of repeated code that could be refactored
  • Is there a pattern emerging that could be abstracted?
  • Are there spots where using a design pattern could be beneficial

Do - get actionable items

  • Not every review will have them
  • Should be reviewed at the next review
  • Suggestions should also provide reasoning behind it

Don't - forget the tests

  • Are there test/spec files?
  • Are the tests meaningful?
  • Are the tests testing what the person thinks they are
it('should find the given product by id', function() {
  var prodId = 1;
  someSvc.findById(prodId)
  .then(function(result) {
    expect(prodId).to.be.equal(prodId) // did they really mean result.id? 
  });
});

// is this test even going to hit the expect when you expect it to?

Don't - forget the tests

  • Are there test/spec files?
  • Are the tests meaningful?
  • Are the tests testing what the person thinks they are
  • Do the tests do what they say
it('should convert the provided time to minutes', function() {
  var input = "3 hours";
  var result = someSvc.convertToSeconds(input);
  expect(result).to.equal(10800)
});

Do - make notes available

  • Submit a PR day/few hours before the review
  • Give the team a chance to read the notes
  • Use the PR as a discussion - comment on items/etc

and finally .....

celebrate the wins

  • Identify what is done well
  • Suggest where it could be applied elsewhere
  • If you think it could be useful for other projects - let others know

External Code Reviews

By Evan Schultz

External Code Reviews

  • 1,585