DITrack: a quick tour

$Id: index.html 2197 2007-10-17 23:30:35Z vss $ $HeadURL: https://svn.xiolabs.com/ditrack/src/tags/0.8/doc/quicktour/index.html $

This is a quick tour of DITrack capabilities. It's not indended to serve as documentation, but rather a short description of a workflow and some design details to get you a feel of what DITrack is.

This document covers DITrack 0.6.

Issue database initialization

So, you've got a brand new project and need to start tracking bugs in that as soon as possible. And yes, you've got Subversion and DITrack installed. First off, you have to decide where the issue database will be located in your repository. Since issues are going to be applicable to different versions and branches of the code, a logical place for the issue database is something like '/issues'.

From now on we'll assume that environment variable 'R' points to your project's repository root:

	~ $ export R=http://your.svn.server.com/repos/myproject
To initialize the issue database you have to run 'dt-createdb.py' script, giving it the repository root, your chosen name of the issue database directory and the name of the local directory you want to work in ("work" for now, while initializing the issue database: you'll see what it means in a moment).
	~ $ dt-createdb $R issues myproject
	property 'ditrack:format' set on 'myproject/issues'
	property 'svn:ignore' set on 'myproject/issues'

	Empty issue database created at:
	'myproject/issues'

	Now you should probably type something like:

	svn commit myproject/issues

	~ $

As you can see, the script has (nonrecursively) checked out the root of your repository (assuming $R is pointing to the root, which is not really required) into 'myproject', created directory 'issues', populated it with some data and scheduled all for addition to SVN:

	~ $ ls myproject/
	issues
	~ $ cd myproject/
        myproject $ svn st
	A      issues
	A      issues/meta
	A      issues/meta/next-id
	A      issues/data
	A      issues/etc
	A      issues/etc/listing-format
	A      issues/etc/users
	A      issues/etc/categories
	A      issues/etc/filters
	A      issues/etc/versions
	A      issues/README.txt
        myproject $

Ok, now it's time to do a little customization. All the settings that might be of interest to you reside in issues/etc. Start with the 'users' file, which contains a list of users of the system. It would be helpful if DITrack user names actually match SVN user names. The format of the file is just one user name per line:

	myproject $ (echo "joe"; echo "sally") > issues/etc/users
	myproject $ cat issues/etc/users
	joe
	sally
        myproject $
Now let's define some categories. Each issue filed in the DITrack system is assigned to one of categories. Each category has a default owner and a set of "versions" (more on that later). For example, your project could have two components — frontend and backend — released on different schedules and each having its own version number. Thus you'd add at least two categories to the system. File 'categories' in issues/etc defines a set of categories; the entries are separated by blank lines and each entry is a set of lines following "Key: value" syntax. Below is the sample of how you might set up the categories.
	myproject $ vi issues/etc/categories
	... editing ...
	myproject $ cat issues/etc/categories
	Category: frontend
	Default-owner: joe
	Version-set: frontend-versions

	Category: frontend/docs
	Default-owner: joe
	Version-set: frontend-versions

	Category: backend
	Default-owner: sally
	Version-set: backend-versions
        myproject $

Note that for frontend we have two categories (one for code, one for docs) that share the same version set. What is version set? It's just a set of versions that are shared among different categories. In this case frontend and backend are released on different schedules, so the version sets are different. On the other hand the front end code and its documentation are released at the same time, so they share one.

As a product develops, the set of version numbers associated with that grows. First, there are future versions of the product, yet to be created; these are called "future versions" in DITrack. Then, there is [usually] a few version numbers that represent the currenly used releases of the project — against which bugs are reported; we call these "current versions". At last, there are version numbers that are no longer in use; we call them "past versions". So, the version set is just an enumeration of past, current and future versions of the product. DITrack needs to know which versions (for each category) can bugs be reported against and which target versions can be assigned. This all is specified in the 'versions' file in issues/etc. Each line of the file follows the syntax: "version-set-name: past versions / current versions / future versions". Let's say that you've already released versions 0.1 and 0.2 of your frontend and you want to plan for upcoming releases 0.3, 0.4 and 0.5 (there are no past versions since the project is still young). As for backend, versions 0.1, 0.2 and 0.2p1 are no longer in use, you run 0.3 and plan for 0.4 and 0.5. This is how that would be represented in the config:

	myproject $ vi issues/etc/versions
	... editing ...
	myproject $ cat issues/etc/versions
	frontend-versions: / 0.1 0.2 / 0.3 0.4 0.5
	backend-versions: 0.1 0.2 0.2p1 / 0.3 / 0.4 0.5
        myproject $
Ok, this is the absolute minimum that needs to be edited, you can tweak the rest later. So let's go ahead and finish our database initialization by committing the changes to the repository:
	myproject $ svn ci issues -m "Initialized issues database"
	Adding         issues
	Adding         issues/README.txt
	Adding         issues/data
	Adding         issues/etc
	Adding         issues/etc/categories
	Adding         issues/etc/filters
	Adding         issues/etc/listing-format
	Adding         issues/etc/users
	Adding         issues/etc/versions
	Adding         issues/meta
	Adding         issues/meta/next-id
	Transmitting file data .......
	Committed revision 1.
	myproject $

Ok, now we are ready to file some issues.

Working with issue database

Let's first check out the issue database into some convenient location.

	myproject $ cd ~
	~ $ rm -rf myproject
	~ $ svn co $R/issues my-issues
	A    my-issues/meta
	A    my-issues/meta/next-id
	A    my-issues/data
	A    my-issues/README.txt
	A    my-issues/etc
	A    my-issues/etc/listing-format
	A    my-issues/etc/users
	A    my-issues/etc/categories
	A    my-issues/etc/filters
	A    my-issues/etc/versions
	 U   my-issues
	Checked out revision 1.
	~ $

Now to save some extra typing, we are going to point DITrack to this directory by setting up DITRACK_ROOT environment variable (this can always be overridden with '-d' switch to 'dt'):

	~ $ export DITRACK_ROOT=`pwd`/my-issues

Adding issues

Ok, we are ready to add a new issue. This is accomplished with 'new' command of 'dt' (if your login name is different from the one you use in DITrack, you might need to use '-u' option). DITrack will ask a few questions and drop you to an editor so that you can enter the issue description:

	~ $ dt new
	Choose the issue category:
	1) backend
	2) frontend
	3) frontend/docs
	a) abort
	> 1
	Choose the version the issue is reported against:
	1) 0.3
	a) abort
	> 1
	Enter the issue title:
	> possible memory leak in dispatcher

	... editor starts here ...

	Choose the version the issue is due:
	1) 0.4
	2) 0.5
	a) abort
	> 1
	New local issue #A committed as i#1
	~ $
The last line of the output tells us that the issue you've just typed has been stored under number 1. Let's add another one for the frontend:
	~ $ dt new
	Choose the issue category:
	1) backend
	2) frontend
	3) frontend/docs
	a) abort
	> 2
	Choose the version the issue is reported against:
	1) 0.1
	2) 0.2
	a) abort
	> 2
	Enter the issue title:
	> funny characters in the main window

	... editor starts here ...

	Choose the version the issue is due:
	1) 0.3
	2) 0.4
	3) 0.5
	a) abort
	> 1
	New local issue #A committed as i#2
	~ $

Viewing issues

Ok, now we have two issues in the database. We can always get a list of issues (possibly, filtered by some criteria) with the 'ls' command:

	~ $ dt ls
	1    sally    0.4      open   possible memory leak in dispatcher
	2    joe      0.3      open   funny characters in the main window
	~ $ 

The output gives us an issue number, owner, due version, status and a title. There is a way to customize the output (see '-f' option and etc/listing-formats file under the database root). We won't get into these details for now.

We can also filter the output by specifying the filter expression as an argument to 'ls'. Here we filter by the issue owner:

	$ ~ dt ls Owned-by=joe
	2    joe      0.3      open   funny characters in the main window
	$ ~

Where did we get the 'Owned-by' part from? It's a standard DITrack header which is present in each issue. To learn which headers are there we can use the 'cat' command which basically 'concatenates' an issue to the standard output. Here is the simple form:

	$ ~ dt cat 2
	Issue: 2
	Category: frontend
	Due-in: 0.3
	Opened-by: joe
	Opened-on: 1192578520 2007-10-16 16:48:40 Tue -0700
	Owned-by: joe
	Reported-for: 0.2
	Status: open
	Title: funny characters in the main window

	There is a few funny-looking characters in the main window when viewed in IE.
	Firefox seems to be ok.

	==============================================================================
	$ ~

You can see there is an issue header, followed by a blank line and then the issue description that we originally entered. The header includes a number of fields which are maintained by DITrack (but you can freely edit them, actually; or add new ones, specific to your needs).

Currently the issue has only original description (which is called 'comment 0' in DITrack speak), since it has not been yet commented. We can always display specific comment by adding '.' followed by the comment number to the issue number in 'cat' argument. So, if we'd need to display comment 10 of issue 123, we'd say 'dt cat 123.10'.

Any comment has a header and a text. If we'd like to display header only, we have to specify '--headers-only' option to 'cat'. Since our goal was currently to learn about various headers, it is best achieved with:

	~ $ dt cat --headers-only 2.0
	Issue: 2
	Category: frontend
	Due-in: 0.3
	Opened-by: joe
	Opened-on: 1192578520 2007-10-16 16:48:40 Tue -0700
	Owned-by: joe
	Reported-for: 0.2
	Status: open
	Title: funny characters in the main window
	~ $

Working with issues

Okay. Now, let's say we discovered that issue 2 (the conventional notation in DITrack for this is 'i#2') is too hard to get delivered for 0.3 and thus we want to move it to version 0.4. To do something about an issue we have to use the 'act' command, which offers us a menu to close/reopen the issue, change due version, add a comment text (you might skip adding any text and just change header fields, so this is optional), manage files attached to the issue, manually edit the header or reassign issue to another user. We want to change the due version, so here we go:

	~ $ dt act 2

	Acting on:

	[frontend-versions]:
	i#2: funny characters in the main window


	Choose an action for the issue(s):
	a) abort, discarding changes
	c) close the issue
	d) change due version
	e) edit comment text
	f) manage file attaches
	h) edit the issue header
	o) reassign the issue owner
	q) quit, saving changes
	> d
	Current due version: 0.3
	Choose new due version:
	1) 0.3
	2) 0.4
	3) 0.5
	> 2

	Acting on:

	[frontend-versions]:
	i#2: funny characters in the main window


	Choose an action for the issue(s):
	a) abort, discarding changes
	c) close the issue
	d) change due version
	e) edit comment text
	f) manage file attaches
	h) edit the issue header
	o) reassign the issue owner
	q) quit, saving changes
	>

	...

As you can see, when entering the action, DITrack prints out the list of issues we are working with (here it's just one, but we can actually specify multiple issue numbers as arguments to 'dt act') and the version sets the issues belong to (here i#2 belongs to 'frontend-versions'). Then we have a menu which we exploit to change the due version. After doing that we end up in the same menu so we can do more stuff with the issue. We are going to post an excuse for delaying the fix by entering a comment text:

	...

	Acting on:

	[frontend-versions]:
	i#2: funny characters in the main window


	Choose an action for the issue(s):
	a) abort, discarding changes
	c) close the issue
	d) change due version
	e) edit comment text
	f) manage file attaches
	h) edit the issue header
	o) reassign the issue owner
	q) quit, saving changes
	> e

	... editor starts here ...

	Acting on:

	[frontend-versions]:
	i#2: funny characters in the main window


	Choose an action for the issue(s):
	a) abort, discarding changes
	c) close the issue
	d) change due version
	e) edit comment text
	f) manage file attaches
	h) edit the issue header
	o) reassign the issue owner
	q) quit, saving changes
	> q
	Comment A added to issue 2
	Local i#2.A committed as i#2.1
	~ $

After hitting 'q' the newly added comment gets committed to the database. We can ensure it's there by using the familiar 'cat' command:

	~ $ dt cat 2
	Issue: 2
	Category: frontend
	Due-in: 0.4
	Opened-by: joe
	Opened-on: 1192578520 2007-10-16 16:48:40 Tue -0700
	Owned-by: joe
	Reported-for: 0.2
	Status: open
	Title: funny characters in the main window

	There is a few funny-looking characters in the main window when viewed in
	IE.
	Firefox seems to be ok.

	==============================================================================
	Comment: 1
	Added-by: joe
	Added-on: 1192657999 2007-10-17 14:53:19 Wed -0700
	DT-New-Due-in: 0.4
	DT-Old-Due-in: 0.3

	Too hard to get it done for 0.3 -- needs much more testing.

	==============================================================================
	~ $

You can see now that the issue header (first block of lines in the output) has new due version and there is a comment added. The comment also consists of a header and a text and the former shows us that the 'Due-in' field was changed from '0.3' to '0.4'.

Syncing the database

DITrack is a distributed system which uses Subversion as its underlying versioned distributed storage layer. Thus the working copy your issue database is checked out into is a snapshot of the repository at a given time. As with any version control system you need to periodically bring your copy of the data with the master. DITrack offers 'update' command for this (abbreviated as 'up'):

	~ $ dt up
	A    /u/joe/my-issues/data/i1/comment1
	Updated to revision 8.
	~ $

What happened is DITrack invoked Subversion to update the working copy and you can see that there is something happened with i#1.

Under the hood

Here we are going to make a quick look under DITrack's hood to show you the way your valuable data ends up being stored. First, this is how the top directory of our issue database looks like:

	~ $ ls -la my-issues
	total 16
	drwxr-xr-x  7 joe  users  512 Oct 16 16:43 .
	drwxr-xr-x  4 joe  users  512 Oct 15 16:50 ..
	drwxr-xr-x  2 joe  users  512 Oct 15 16:56 .ditrack
	drwxr-xr-x  6 joe  users  512 Oct 17 15:04 .svn
	-rw-r--r--  1 joe  users  105 Oct 15 16:50 README.txt
	drwxr-xr-x  5 joe  users  512 Oct 16 16:48 data
	drwxr-xr-x  3 joe  users  512 Oct 15 16:56 etc
	drwxr-xr-x  3 joe  users  512 Oct 16 16:42 meta
	~ $

Skipping '.svn' (since it's a Subversion working copy) and 'README.txt' (which is a short description of what the heck this directory is), there is:

.ditrack
This hidden directory serves for DITrack internal purposes and is present only on your local machine. It is used to store some metadata about this snapshot of the database (such as "when was the last time we synced up?") and also an "LMA", which stands for "Local Modifications Area". The LMA is a kind of a buffer which holds all your local changes right up to the moment when we are about to commit. The philosophy behind DITrack is that the database working copy should be exact copy of the repository at all times. Thus we store all the changes in LMA and only when a commit is about to happen, changes are written to the working copy. This also helps us out when there is no network connectivity: LMA is the place where everything goes until we want to (and can) push our changes to the server.
data
This is where all issue data resides. We'll look inside shortly.
etc
All database-wide configuration files are here (we've seen a few while setting up the database).
meta
DITrack metadata which is shared with other users (as opposed to '.ditrack' which is exclusively yours).

All you really care about is under 'data', specifically:

	~ $ ls -l my-issues/data
	total 4
	drwxr-xr-x  3 vss  users  512 Oct 17 15:04 i1
	drwxr-xr-x  3 vss  users  512 Oct 17 14:53 i2
	~ $

...e.g. a directory for each existing issue with plain text (RFC2822) files representing "comments" (i.e. changes to issues):

	~ $ cat my-issues/data/i1/comment0
	Added-by: joe
	Added-on: 1192578325 2007-10-16 16:45:25 Tue -0700
	DT-New-Category: backend
	DT-New-Due-in: 0.4
	DT-New-Opened-by: joe
	DT-New-Opened-on: 1192578325 2007-10-16 16:45:25 Tue -0700
	DT-New-Owned-by: sally
	DT-New-Reported-for: 0.3
	DT-New-Status: open
	DT-New-Title: possible memory leak in dispatcher
	DT-Old-Category: 
	DT-Old-Due-in: 
	DT-Old-Opened-by: 
	DT-Old-Opened-on: 
	DT-Old-Owned-by: 
	DT-Old-Reported-for: 
	DT-Old-Status: 
	DT-Old-Title: 

	The dispatcher seems to leak memory. Restart helps.

	This seems to have started happening after the ABC changes.
	~ $ cat my-issues/data/i1/comment1
	Added-by: sally
	Added-on: 1192658476 2007-10-17 15:01:16 Wed -0700
	DT-New-Resolution: fixed
	DT-New-Status: closed
	DT-Old-Resolution: 
	DT-Old-Status: open

	Fixed in r12345.
	~ $ 

Besides the exciting fact that it's all plain text (hello, /bin/cat and /usr/bin/vi in emergency!) there is one important point to note. DITrack never modifies existing data, only adds new. Hence conflict resolution is [going to be] easy. However, if, say, there is a mistake in one of the older comments, you can just go ahead and fix it in a text editor and commit the change without using DITrack at all. This is our equivalent of hand-editing a row in an SQL database. Or, if you feel like, you can roll back the whole issue database to an older revision (now, there is no easy way to do this with traditional issue tracking systems!). And one final neat thing is that you can also use 'svn log' to walk through an issue history:

	~ $ svn log my-issues/data/i1
	------------------------------------------------------------------------
	r8 | joe | 2007-10-17 15:01:16 -0700 (Wed, 17 Oct 2007) | 6 lines

	i#1: possible memory leak in dispatcher
	 * closed as fixed

	Fixed in r12345.


	------------------------------------------------------------------------
	r5 | joe | 2007-10-16 16:45:25 -0700 (Tue, 16 Oct 2007) | 1 line

	i#1 added: possible memory leak in dispatcher
	------------------------------------------------------------------------
	~ $

Isn't that nice, huh?

Not covered

This is the end of our introduction to DITrack. There is quite a few things that are left uncovered (so feel free to ask on the mailing list about those or use 'dt help' to work your way through), among which are:

Hope by now you've got enough interest in DITrack to try it out! Enjoy!