2014-09-04

Collaborative Dependency-based Todo Using Makefiles

I once had a project that consisted of many moving parts: a sql procedure, a program to run it against multiple databases and output the results to files, a 3rd party specification for xml meta data describing the extract schema, a program to generate the xml, and on and on. At each stage, there was the potential that customer preference could affect choices made, so progress on each piece could be blocked. I wanted to make sure I could be working on some part of it whenever possible, so I drew up a dependency graph of the project. It occurred to me at the time that a Makefile could easily represent the dependencies, so I wrote a small awk script to translate back and forth between Makefile and tgf so I could generate either from the other.

Recently, @holman asked how people keep track of issues, pulls, next projects, etc. The ensuing conversation was a mixture of web apps, irc bots, and todo text files. Where it seemed to break down was that few people had a good system for managing dependencies across projects and teams or organizations. This got me thinking. Could my Makefile system be extended to work deal with people working in teams?

The basic idea would be that the a Makefile would define the dependencies in the project. My original concept used the existence of a file to indicate a completed task. I figured I could extend this idea to use the location of a file to differentiate between complete tasks and tasks assigned to a particular user. The whole thing could then live in a git repo to allow collaboration.

The result looked something like this:

#Makefile
include todo.mk

application: ui libraryB serviceC

ui: skills/html skills/css skills/javascript

libraryB: skills/math

serviceC: libraryD libraryE skills/rest

libraryD libraryE: skills/sql

#todo.mk
vpath % done $(wildcard users/*)

%: todo/%
    @echo In progress: $<

%:
    @echo Next: $@ with $^
    @false

#directory listing
done/
Makefile
todo.mk
users/
  dick/
    skills/
      math
      rest
    todo/
  harry/
    skills/
      sql
    todo/
  tom/
    skills/
      css
      html
      javascript
    todo/

Typing make will result in:

Next: ui with users/tom/skills/html users/tom/skills/css users/tom/skills/javascript
todo.mk:7: recipe for target 'ui' failed
make: *** [ui] Error 1

So that means ui is the next incomplete task that has all of its prerequisite tasks done. make also found all of the necessary skills belong to tom, so we probably want to assign the task to him with touch users/tom/todo/ui. Once we do that, make will show us:

In progress: users/tom/todo/ui
Next: libraryB with users/dick/skills/math
todo.mk:7: recipe for target 'libraryB' failed
make: *** [libraryB] Error 1

So we can see tasks that are being worked on and also the next task that's ready to start. Let's move things along: touch users/dick/todo/libraryB, touch users/harry/todo/libraryD, mv users/harry/todo/libraryD done/, touch users/harry/todo/libraryE. Now make:

In progress: users/tom/todo/ui
In progress: users/dick/todo/libraryB
In progress: users/harry/todo/libraryE
Next: serviceC with done/libraryD libraryE users/dick/skills/rest
todo.mk:7: recipe for target 'serviceC' failed
make: *** [serviceC] Error 1

Looks like serviceC is the next thing that can be started. But wait. libraryD is done, but it doesn't say that about libraryE. If we've been paying attention, we can see that it's in progress and assigned to harry, but what if we're on a really big project and it we didn't see it? Well, make libraryE:

In progress: users/harry/todo/libraryE

Ok, so it's being worked on. touch users/dick/todo/serviceC, make:

In progress: users/tom/todo/ui
In progress: users/dick/todo/libraryB
In progress: users/harry/todo/libraryE
In progress: users/dick/todo/serviceC
Next: application with ui libraryB serviceC
todo.mk:7: recipe for target 'application' failed
make: *** [application] Error 1

So maybe we can start the application? Let's take a closer look though. make serviceC:

In progress: users/harry/todo/libraryE
In progress: users/dick/todo/serviceC

Okay, so harry needs to finish libraryE, then dick can finish serviceC. Awesome.

This may not be something I'll actually use, and I certainly don't expect you to use it. But it was a fun experiment.

No comments:

Post a Comment