Summary

I work on some projects with other people, but I also spend a lot of time
working on projects by myself. When I'm working by myself, I have difficulties
with the following:

code review

bouncing ideas off of people

peer programming

long slogs

getting help when I'm stuck

publicizing my work

dealing with loneliness

going on vacation

I started a #soloists group at Mozilla figuring there are a bunch of other
Mozillians who are working on solo projects and maybe if we all work alone
together, then that might alleviate some of the problems of working solo. We
hang out in the #soloists IRC channel on irc.mozilla.org. If you're solo,
join us!

I keep thinking about writing a set of blog posts for things we've talked about
in the channel and how I do things. Maybe they'll help you.

Code review on a solo project

In the video, Erik talks about the three reasons you should be doing code
review:

Build an excellent product.

Build people.

Build yourself.

That's awesome! Who wouldn't want that?

But what do you do if you're solo? The whole basis of code review is that
someone else reviews the code, so what if there is no one else? Maybe you're
working on a solo project at work. Maybe you're starting a new open source
project that hasn't picked up contributors.

I think projects differ greatly in a variety of ways. For some projects, there
is no substitute for having someone else knowledgeable in the project review
your code. If you're solo on a project like that, you're pretty stuck without
help. For all the other projects, I think there are some things you can do to at
least get by and help build an excellent product.

I work mostly in Python, so what I do works in Python land for software
development projects. If you're not doing software development or not using
Python, then you might have to adjust accordingly.

How we're going to talk about code reviews

Code reviews can/should look at many aspects of the code change. I'm going to
bucket these roughly into the following five categories:

How to find someone to review your code

For developer best practices and programming language/library best practices,
here are some ways to find someone to review your code:

ask a mentor

ask people you have 1:1 meetings with [2]; run code by them or try rubber
ducking explanations because they might ask questions that surface issues and
suggest better ways to do things

ask people working on similar projects, perhaps other projects at the same
company you're at or other projects that use the same programming language
and libraries; try trading reviews with someone in this group

If you're solo, then you're probably the only person with experience in your
project, so covering that aspect of code reviews is tough.

For open source projects, you could ask for help from someone who works on a
similar project. For example, if you're working on a PEG parsing library and you
go to a PyCon conference, find other people who've worked on parsers and ask to
trade reviews.

Keep in mind that if you're asking for help from people who don't normally help
you, it's best to keep your changes as small as possible. You won't make friends
by asking people to review 1,000+ line changes.

I have 1:1s with people doing totally different things than I am because
we learn a lot from each other and have vastly different perspectives on
things. More on this in a different post.

How to approximate code review with a self-review

Is self review a substitute for someone else reviewing your code? Definitely
not, but the premise here is that you're on a solo project and there isn't a
someone else. If you've exhausted the world's options, then you're just going to
have to get the best approximation you can get.

My development process leading up to code review

Code review is just one step in the development process. I find code review
is easier and less risky if I follow these rules:

Research, think, and plan as much as possible before coding.

Talk to myself about what I'm doing. A lot.

Keep changes small.

The larger a change is, the longer it takes to review and the higher risk
of introducing bugs and failures.

Sometimes I'll break up changes into a set of smaller atomic changes.
Sometimes forcing myself to think about breaking big changes into small
atomic changes makes it easier to do big changes.

My self-review flow

I think those three things create a context in which it's easier to do
self-review.

For self-review, this is roughly what I do:

I run all the linters and tests I have set up for the project.

This covers project conventions and makes sure everything is good as far as
computers can tell. Forcing computers to do work means I do less.

I go take a walk and do something somewhere else for 15 minutes.

This is a good time to get a glass of water [3]. I work at home, so
sometimes I'll spend some time decluttering or cleaning.

I look at the changes in different ways using different tools.

When I come back, I try to look at the code changes in a bunch of different
ways and see if it looks ok.

I do:

git diff master..HEAD

or something equivalent in the terminal and read through my changes
carefully. git has a variety of different diffing and ways to view. For
example:

Definitely worth reading through git diff --help to see what would help
you.

I may also look at each individual commit and the commit comments and
summary.

I may look at the original code in full (checkout the master branch) and then
look at the changed code in full (checkout the branch tip).

Looking at the changes using different tools and views helps force my brain
to be more careful reading because it looks totally different. Different
tools use different diffing algorithms, have different fonts and color
schemes, and show different amounts of context.

This sort of covers developer best practices, programming language/library
best practices, and things that require someone who's been working on the
project for a while.

Fourth, I push my branch and create a pull request on GitHub.

The CI system I use (Circle CI or Travis CI depending on the project) happily runs all my tests
and linters.

If there are CI failures, I'll fix them.

I leave it for a day.

I'll do other things and ignore the PR until the following day. A night of
sleep between creating the PR and reviewing it gives me time to mull over
things and helps me forget bits.

Sometimes I get side-tracked on something else--I usually have multiple
projects I'm working on, so I'll switch between them.

I review my pull request.

I go through the pull request carefully and answer questions like the
following: questions:

How can this code fail? What have I done to prevent those failures? What
have I done to surface those failures so I know if they're happening?

What happens if this code is wrong? Will it cause data loss? Will it break
the service-level agreement I have with my users? Can this change be
backed out quickly if it's bad?

Are these changes appropriately covered by the tests? Do the tests make
sense?

If I'm using mocks in my tests, have I verified that the mocks are
correct?

Do the changes match the documentation and surrounding comments?

I take my time reviewing my pull requests. I don't rush it. If I'm tired, I
take a break.

I write comments to my PRs especially to explain design decisions that I
think might look odd. Future me and any other developers that join this
project will benefit greatly from me explaining why I did what I did. Also,
this is sort of like rubber-ducking and I sometimes discover things I should
change because they're either hard to explain or it becomes clear it's
missing edge cases.

This sort of covers developer best practices, programming language/library
best practices, and things that require someone who's been working on the
project for a while, too.

I land the change!

After all that, I'll land the change. If there are issues, I'll fail forward
and fix them if I can. If I can't do that, I'll back it out. I don't think
I've ever backed anything out, though.

That's pretty much it.

Periodically, I revisit code a couple of weeks or a month later and see if it
still looks ok. Sometimes code doesn't evolve well over time and is worth
refactoring.

Do I do all these steps every time?

No. I try to balance the urgency of the change to land with the risks of failure
with the consequences of failure and base how much time I should spend reviewing
on that.

For example, if I'm fixing documentation, I won't spend a lot of time reviewing
it. If I'm fixing a critical method in a piece of code that needs to be
thread-safe and never fail, then I'll take a couple of days and be more
meticulous.

Warning: Self-review doesn't help you build people or build yourself!

In a self-review, you're both the developer and the reviewer. That bites you
in both directions.

When you review other peoples' code, you share your experience and knowledge
with them and help them grow as a developer and grow as a contributor on your
project. If you're self-reviewing, you're not growing anyone.

When someone else reviews your code, they share their experience and knowledge
with you and cover the things that are unknown to you. Thus code review is a
unique opportunity to learn from others and grow as a developer. If you're
self-reviewing, you're not growing yourself.

If you're self-reviewing, you need to work harder to alleviate these missed
opportunities.

Many thanks

Many thanks to the #soloists who I've bandied about some of these thoughts
with over the last year and those who read this and provided feedback. Many
many thanks to Erik who studiously reviewed earlier drafts and pointed out
many issues.

What do you do?

Ever worked on a solo project? What do you do to alleviate the problems of not
having someone else to review code?

Let me know and I'll update this with your thoughts.

Want to comment? Send an email to willkg at bluesock dot
org. Include the url for the blog entry in your comment so I have
some context as to what you're talking about.