TimeWarrior 1.0.0 - A golang time tracker
After barely programming in Go these past two years I really wanted to get back into using the language, and figured a good starter project would be to port my Ruby time tracker to Go. So a few weeks back I started rewriting that old CLI application in Go, and have now released TimeWarrior 1.1.0 on Github.
TimeWarrior is a CLI based time tracking application used to record timeslips for your freelance and personal projects. Timeslips for a project are stored in their own project data files, with each timeslip saved as a valid JSON string.
Project and Task names are given as CamelCase
; separated by a period. You would start
a new timeslip like this:
$ tw s MyProject.SomeTask
You can pause
and resume
a timeslip at any time (the p
and r
shortcuts are available), and once work on a task is complete, you can mark it as done
:
$ tw d "Some nice description of the work"
It’s also possible to adjust the time you’ve currently worked on a pending timeslip with the adjust command:
$ tw adjust 10m
I recommend you visit the Github repository which has full installation and usage instructions.
At the moment you will need to build the executable yourself, but hopefully I’ll have ready-made downloads for Windows and macOS soon, once I’ve run some tests on a Windows machine!
Please note that there’s currently no reporting functionality. I have a simple old script for my own needs, which I’ll eventually look into adding to the app.
If you’re impatient and you’d like to implement a report
command yourself, please feel free to submit a PR!
The Backstory
As I wrote above, this Go version is a rewrite of an old Ruby GEM; two major versions that I’ve been running now for the past five years.
Back in 2012 I’d started with a lot more freelance/consulting work and was tracking all my time using the excellent Sigma tool from Arrow UK, which integrated directly with the online accounting software I used at the time. However, not only did I want more control of this data, I also wanted to start tracking time for my own projects, so needed something more independent.
After some research I found the very nice TaskWarrior app, but this is really a TODO list rather than a time tracker. In fact there were a number of other possible solutions but none that would allow me to generate simple timeslips, so I wrote my own.
TaskWarrior did have some nice features, which I used as inspiration for my own app: I liked how they used the Project.Task
format for naming of the project/task as well as their pending
/complete
file format - okay, so you might also notice that the name is similar; originally TimeWarrior was just a WIP name, but well, it seems to have stuck over these last 5 years!
Here’s an example of that first timeslip data format:
$ cat time_warrior/completed.data
[description:"Some task" end:"1330647345" entry:"1330646400" modified:"1330647345" project:"ProjectName.SomeTask" status:"completed" uuid:"93802d17-7f67-453e-9678-c86b135fe6d0"]
This worked well for a while, but I didn’t like the commands and that data format was not so nice to parse. So with new ideas in hand, I created v2. The UI was update, which was actually very similar to the new Go version, but I also refreshed timeslips format from a custom string to a valid JSON string:
$ cat time_warrior/completed.data`
{"project":"ProjectName","task":"SomeTask","comment":"some work on a task","started":"1441148400","duration":"1560","finished":"1441149960","modified":"1441149960","status":"completed","uuid":"8a0f6ad1-84fc-4eec-bc9a-87fa38215d0c"}
Although the key names changed, it’s mostly the same. I refrained from wrapping everything in an array [{"project":"Name" ...}]
to reduce the need to parse the file contents when adding a new timeslip, which also meant there was less chance for data loss.
The latest Go version of TimeWarrior saves timeslips in a project based data file, and renames a couple of field names.
$ cat time_warrior/time_warrior.json
{"project":"TimeWarrior","task":"GoRewrite","description":"App setup","started":1442660653,"worked":6877,"finished":1442669388,"modified":1442669388,"status":"completed","uuid":"0ad1db06-4d76-4edb-bf3b-6f54a9d5a2e2"}
Project data files are generated from the CamelCase
project name, by converting to snake_case
. duration
is renamed to worked
and comment
to description
.
The CLI commands are also mostly the same, with the biggest change to starting a new project, changing from tw s -p Project.Task
to tw s Project.Task
…fewer key strokes is always a good thing!
A new adjust
command was added for this release - I was always forgetting to pause/resume a timeslip so needed to edit the .pending
file and manually adjust the time. Now there’s a command for that!
Although the first public release of TimeWarrior has been given a version of 1.0.0
, to me this is really v3.0.0
.