loading...
Cover image for Stop Committing TODOs

Stop Committing TODOs

forstmeier profile image John Forstmeier ・2 min read

First and foremost, this post is more of a personal guideline to myself in order to stop, what I consider to be, a bad habit of mine.

Adding in-code TODOs is something I'm trying to move away from. While it does create an immediately contextualized task list when placed in the surrounding code, the list can only be observed when you open those specific files. Essentially, there's a growing list of TODOs with no impetus to get them done until they are rediscovered by opening whichever file they are in.

Additionally, they pose the problem of being difficult to track which makes it hard to chart your progress. They basically sit there, doing nothing and tracking nothing.

My personal goal is to begin migrating all of this TODO tracking into some other format. Options like Todoist projects, Google Keep notes, or desktop options like FromScratch create a more centralized alternative for keeping track of what needs to be done and helping to keep a focused approach. Personally, I'm using GitHub Project boards with Markdown checkbox lists - these have a nice feature of showing a progress bar as you check off items.

Issue example

Now far be it from me to say that all in-code TODOs should be abandoned - there are some instances where it makes sense. For example, I feel like when I'm jumping around in several files, jotting down TODOs as I go, it creates a sense in my head that I'm laying groundwork for the immediate future. Perhaps even using them as "bookmarks" for what I'll jump right into the next day.

This is all just my opinion and if other people have differing opinions / better ways of handling this particular stumbling block of mine, I'm all ears.

Discussion

markdown guide
 

I have this alias in my git config for this exact job

todo = !sh -c 'grep --color=always -rn "TODO" `git ls-files`'

Short, sweet, and it will even tell you which line and which file it is part of. Then you can add a pre-commit git hook and it will remind you of your TODO's every time you commit. OR, you can make it reject your commit if it contains a TODO line in it pretty easily too.

 

That's actually really cool. One of the concerns I have with the in-code TODOs is that they will be lost and buried if they aren't kept front and center.

 

Another thing that I add is a git post-commit hook that will show any todo's in any of the files being committed, so there is a constant reminder that they exist.

 

You say that "the list can only be observed when you open those specific files". Any good editor or IDE will have a tool to negate this problem. Atom has a package called todo-show that shows the type (it supports more than TODO, but also things like FIXME, IDEA, NOTE, REVIEW, BUG, QUESTION, and more), the text after the tag, and what file it is. Eclipse also supports "task tags" which all you to specify a tag (like TODO or even custom tags) and assign the tag a priority and find and filter all of them through open projects. Even Visual Studio supports a task list that's very much like Eclipse's. I don't regularly use emacs or vi (I prefer a more integrated environment that's harder, but not impossible, to get with those editors), but it looks like there are solutions for these editors to do similar things.

Once you get past the problem of finding all TODO-like statements in a project, the value of putting them in the source code significantly increases. They are there for any developer to pick up. At work, we track work to pay off technical debt in JIRA. On personal projects, I put in a GitHub issue for things that I know I need to get back and fix. But I also put in TODOs or similar in the code so when I decide to go back and fix the problems, I have a much better understanding of what is necessary. Especially in a team environment, getting the fact that there exists undone work or technical debt is important, having the information to go forward and do the work or pay down the tech debt belongs in the code.

 

Good to know about the todo-show - I'm an Atom user and I think I'll play around with it.

I'm very much a proponent of self-documenting code but perhaps extending it too sharply into excluding TODOs isn't the best manifestation of that philosophy. The idea of having the TODOs framed by the context of the surrounding code is very appealing but I also like the ability to view things as they relate to the broader project or how TODOs relate to various sub-tasks. Essentially, I'm trying to wrangle out a good balance for myself for where to use in-code TODOs and external trackers without tipping to heavily in favor on relying on one or the other.

 

It's a balancing act, for sure.

I've found that external tracking tools (JIRA, issues in GitHub) are great for planning and tracking. At work, great for showing status to management or letting non-developers understand how work is progressing. In personal projects, figuring out what I want to sit down and do in a limited amount of time.

Lots of different people have different variations of TODO. Personally, I dislike things like FIXME or BUG in my code. If it's a bug, it should be fixed. If, for some reason, it can't be fixed, the issue should be outside the code in an issue tracker. At that point, the TODO becomes a reference to an issue tracker. Other people have other comments - HACK, XXX, TODO, NOTE.

Personally, I think it comes down to audience. If it's at the level of detail that a non-developer needs to know about, put it in a ticket so your non-developers (users, managers, product owners, whoever) can find it. But TODOs can make it extremely easy to find parts of the code that need work and put in more detail.

Like anything in the code, though, it does need good tools to manage. Leaving TODOs without a way of tracking them or the discipline to keep them up-to-date is likely to be harmful.

 
 

A simple rule of thumb for me is that inline todos are only for the branch I'm currently working on. All inline todos must be resolved before submitting a pull request. Any todos that are appropriate to work on at another time go on the project board.

 

Perhaps it's obnoxious to point this out, but this is what grep is for. Unix is there, use it! If you want, put it in a hook so you see it when you interact with source control.

The benefit is that you create the mark when you write the code. It's valuable whenever you are writing code without time to do everything perfectly. Opening an external loses the immediacy.

 

Someone's only going to grep if they know to do so. I think the spirit of the article is to suggest a better task management system than in-code to-do comments.

I have fallen prey to this team myself. Now I use Jira tickets or GitHub issues exclusively​.

 

"This reminds me of a new feature we could add" does not belong in your code, and "I have a funny feeling about doing it this way on line 27" does not belong in a ticketing system. It belongs on line 27.

Both inline TODO and FIXME comments and external tools have a place.

If you hack something under a deadline and don't comment it as a hack out of some notion that inline todo comments are bad, I'm not going to thank you if I'm the one reading the code later on. Of course you can always add "cleanup the hacks in the foo module" to your ticketing system as well.

 

TODO's are an abbreviated issue. They have an advantage over issues in that they are near the code to which they apply. This ensure that somebody coming to work on this code sees relevant information they might need. Unfortunately I've not seen issue systems address this locality problem yet.

As others have pointed out, the lack of a listing is a non-issue: there are numerous ways to get lists of TODOs if you want them.

TODOs have helped me numerous times while tracking down defects. Quite often I see something not work, and then read a TODO saying that it won't work. They can save me a lot of time. Obviously we'd prefer to just have the missing functionality instead of a TODO, but I'd rather have something than just nothing.

That said, TODOs are often better replaced with error messages. Detect what isn't support and report the error.

 

I actually really like the idea of simply using error messages in lieu of missing/planned functionality - it creates a visible and obvious TODO.

 

My teams use checkstyle at build time and will fail the build on checkstyle errors. I added a custom checkstyle rule that will fail if it sees a TODO comment that doesn't reference an issue tracker issue.

As long as the team's small and bought into it, I've found it results in just the right amount of friction such that if you're just pushing something small off until later, the pain of opening an issue and writing out what needs to be done is equal or greater than just doing the TODO. But if it's sufficiently large, then it gets tracked in the issue tracker.

Again, there are plenty of ways to game this kind of system so the team needs to be bought in. The checkstyle rule just serves as a reminder.

 

I recently started adding tasks to my open issues, when necessary, checking them off one by one as I get them done. It's simple and quick, and the comprehensive labeling combined with milestones takes care of prioritizing and such. I like to keep things simple and not over-complicate matters with even more apps, more things to check and keep track of.

 

Well, most IDE will have an option to list TODOs.

However, I'd rather say: never commit something that is not finished.

I apply XP as much as I can and one of the ground rules is to code only the minimal amount of code you need for the current feature you're working on to work. Which means that I sequentially code all features (and sub-features) and make sure they are complete before moving on.

If a feature is complete, then it makes no sense to have a TODO in there.

Sometimes you just can't hold everything in your head and TODOs are a great way to remember. Sometimes it even makes sens to commit it. However it should be fixed a few commits later and never ever survive the pull request.

In other words, do the things that need to be done now, otherwise you're going to end up with a pile of trash that we call "technical debt".

 

I presume TODO's are small/big code changes for refactorings or future functionalities, NOT project TODOs (tasks, business logic), so with this in mind:

a TODO list is not the way you want to do things, for many reasons:

  • the TODO list doesn't have context
  • the TODO list is not in the code
  • devs are lazy and on the run, they will not open a TODO website and search for your TODO list to try and mix and match the list
  • a TODO list, like any out of the code documentation will be soon outdated

You may want to put them in your project task management, this is what we do for big TODO's that didn't fit in the current sprint.
You may want to put them in your code if they are small, and when the next refactoring comes they are deleted.

You put them into your code to guide other devs into the expansion direction you chose for that file.

 

Just grep todo. These entries inside code are tied to specific method or place, TODO's in your notes app have no knowledge of that. It would be painful to write out line numbers etc.

You can easily grep any source code for TODOs, e.g. grep -r "TODO" .

 

One concern I do have is that unless this is a habit everyone interacting with the code has, the TODOs could be gradually buried and the impetus to get them done is lost.

 

Of course, it is best to open ticket / create issue instead if not solo coding.

 

Maybe the real problem is:

  • What type of things are your TODOS;
  • if you keep your TODOs only written on the code.

TODOs that are "Fix me" should not be done at all. Don't write a comment, go fix it right now.

You can write your TODOs on the code, but you have to keep them on a kanban/scrum board as technical debt or on a "centralized TODO base" like google keep.
But even in this case I still think that having that on the code written on the main part of the code affected by the TODO is a good idea, because sometimes a teammate is doing a refactoring someplace else and end up making changes on that part of the code. If the reminder is there, he/she could solve that problem without have to remember of the technical debt that is on the board.

 

We have a lot of tools to manage different projects instead of still using TODO files. I agree with you, we must abandon TODOs.

Btw I use Redmine for my company's developments and Taiga.io for my personal projects.

 

That's one is a really big topic. The biggest problem with in-code TODOs is that they usually consist of very short description of a problem (if any), and then you look at the same thing in a couple of months, it will probably say nothing to you. And even less to someone else on your team. I've seen a lot of such TODO comments in our code base. Some of them are more than 10 years old.

The second biggest problem, is those TODOs are stil comments. And they tend to move away from the original point as the code evolves, and in some not very long time they start to lie.

So yes, please do not commit TODOs. :)

 

Other point to consider is that a contextual TODO may change in a code base. Issues or Jira tickets with links to code surface the information better without requiring code commits to clean up.

 

A good IDE will warn you before committing that you have new TODO's, so I don't see why it's a problem

 

Jetbrain IDE's show you a list of TODO's throughout your project. You can double click them to jump directly to the file and line it's located on.

 

Every time I have an issue to work on, I place a lot of TODO's in the code. The issue is not terminated until all TODO's are done!