Thoughts on using the `bug tracker `_ effectively. These aren't tips, yet, just something I'm mulling over. How do we need to deal with issues? ----------------------------------- Three modes: 1. customer service - very fast response 2. triage - fast response (seek info + convergence) 3. maintenance - whenever we can Making it work right -------------------- - need use of the bug-tracker to be transparent so that just about anybody can do triage... no complicated policies! - but... we still need *some* policy, something rigid... something that makes it easier to take a bug and know what to do about it next - need to distinguish between triaged and non-triaged bugs (but having something like a triaged topic seems like a pain)... - possible states: - [need-info] waiting for somebody to tell us something (assigned if we know who) - [need-volunteer] we know (roughly) what needs to be done, and we need to somebody to do the coding - [deferred] we're not really going to think about this right now, but feel free to hack on it, of course - [chatting/assigned] we know what to do and we know who is the best person to do it - [in-progress] somebody is working on it right now - ... `http://bugs.darcs.net/issue778 `_ is an example of a bug I don't know how to pigeonhole... we can see that it may be a problem, but we don't know how to reproduce it, nor what to do about it... it's a "huh?", but is it untriaged, then? - bugs which do not fit into one of these neat categories need to stand out somehow - main problem is that from the front page, we can't tell the difference between untriaged bugs (our 'huh?' stack) and bugs we know what to do about, but we don't have anybody assigned to yet... - I wish there was an easy way to tell (precisely) how much people care about a bug. Should be able to count duplicates, at least Fields ------ Title ~~~~~ Rough conventions (very informal! the goal is to make things easier to understand at a glance) - 'command => specific error message (darcs version)' - prefix wishes/features with 'wish: ' Priority and Status ~~~~~~~~~~~~~~~~~~~ Priority: - feature vs. wishlist : these are priorities, so a feature is basically a wish that we **really** want to have (for example, progress reporting, back in the darcs 1.0 days), whereas a wish is just something that would be nice Status: - in-progress : somebody is working on it and if there are patches, they have not made it into the mainline repositories yet - testing: the patch is in, now can you tell us if it does what we want? *`EricKow `_ thinks we should abandon this status* Tricky: - duplicate vs. resolved vs. deferred: - I don't like using resolved for duplicates, because it makes it harder to search for a bug and determine if it has already been fixed or not - But if we just use 'duplicate' we can't tell if it's a duplicate of a fixed bug or not - Maybe: deferred for 'this is an interesting duplicate; if the superceder gets resolved, we should get back in touch with the reporter' and duplicate for 'this is a boring duplicate; no need to get back to the superceder' Topic ~~~~~ Still feel like we're not using the Topics feature in the best way possible - Default roundup doesn't display topics in a very nice way (I wish they were more like tags) - Topics we ought to use more consistently: Questions --------- - What is the Darcs2 topic for, and is it still meaningful? Procedures ---------- Some notes on how to do things. Bulk change of issue status ~~~~~~~~~~~~~~~~~~~~~~~~~~~ We wanted to change all issues marked as resolved-in-unstable before a certain date, to resolved. The roundup-admin command-line tool on darcs.net was useful for exploring, but not powerful enough for this task. An interactive python prompt (in an emacs shell for editability) plus the `Roundup design document `_ was the solution, once I figured out the api. Here is a simplified transcript. Note I checked the last activity date rather than the date of being marked resolved-in-unstable; the latter was too difficult and turned out to be unnecessary after inspection. {{{ $ python Python 2.4.4 (#2, Apr 15 2008, 23:43:20) [GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from roundup import instance >>> t = instance.open('/var/lib/roundup/trackers/darcs') >>> t >>> db = t.open('admin') >>> db >>> db.issue >>> db.issue.list() ['145', '202', '259', '354', '448', ...etc >>> db.issue.count() 1054L >>> from pprint import pprint as pp >>> pp(db.issue.getprops()) {'activity': , 'actor': , 'assignedto': , 'creation': , 'creator': , 'files': , 'id': , 'messages': , 'nosy': , 'priority': , 'status': , 'superseder': , 'title': , 'topic': } >>> help(db.issue.get) Help on method get in module roundup.backends.rdbms\_common: get(self, nodeid, propname, default=[], cache=1) method of roundup.backends.back\_postgresql.`IssueClass `_ instance Get the value of a property on an existing node of this class. 'nodeid' must be the id of an existing node of this class or an `IndexError `_ is raised. 'propname' must be the name of a property of this class or a `KeyError `_ is raised. 'cache' exists for backwards compatibility, and is not used. >>> db.issue.get('792','creation') >>> db.issue.getnode(792) >>> db.issue.getnode(792).values() ['7', [], 'Account for --remote-repo in defaultrepo code', ['7', '8', '9', '992'], , ... >>> db.issue.getnode(792).keys() ['status', 'topic', 'title', 'nosy', 'creation', 'messages', 'actor', 'priority', 'assignedto', 'creator', 'activity', ... >>> db.issue.getnode(792).items() [('status', '7'), ('topic', []), ('title', 'Account for --remote-repo in defaultrepo code'), ('nosy', ['7', '8', '9', ... >>> db.issue.getnode(792)['status'] '7' >>> db.issue.getnode(792).status '7' >>> db.status >>> db.status.list() ['2', '6', '8', '1', '3', '5', '9', '10', '12', '7', '15', '16', '4'] >>> pp([db.status.getnode(id).items() for id in db.status.list()]) [[('name', 'deferred'), ('creator', '1'), ('creation', ), ('actor', '1'), ('order', 2.0), ('activity', ), ('id', '2')], [('name', 'testing'), ('creator', '1'), ('creation', ), ('actor', '1'), ('order', 6.0), ('activity', ), ('id', '6')], ... >>> db.issue.find(status='7') # resolved-in-unstable ['145', '200', '22', '207', '580', '136', '510', '209', ... >>> db.issue.filter(None, {'status':'7'}, [], []) # similar to find ['12', '16', '22', '24', '31', '43', '46', '60', '61', ... >>> [db.issue.getnode(id).creation for id in db.issue.filter(None, {'status':'7'}, [], [])] [, , ... >>> from roundup.date import \* >>> Date('2008-06-24') >>> issues = ([db.issue.getnode(id) for id in db.issue.filter(None, {'status':'7'}, [], []) if db.issue.getnode(id).activity < Date('2008-06-24')]) >>> len(issues) 194 >>> issues[0].status '7' >>> issues[0].status = '8' # resolved >>> issues[0].status '8' >>> for i in issues: i.status = '8' ... >>> db.commit() $ }}} And again, more briefly: {{{ $ python Python 2.4.4 (#2, Apr 15 2008, 23:43:20) [GCC 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> from roundup.date import \* from roundup import instance db = instance.open('/var/lib/roundup/trackers/darcs').open('admin') issue = db.issue.getnode def filterissues(spec={},sort=[],group=[]): return db.issue.filter(None,spec,sort,group) >>> >>> >>> >>> ... >>> >>> [i for i in filterissues({'status':'10'}) if issue(i).activity < Date('2008-06-24')] # resolved-in-stable ['37', '65', '69', '113', '127', '141', '143', '147', '173', '186', '218', '259', '264', ... >>> # manually inspect issues in web interface to see if the above is close enough >>> [setattr(issue(i),'status','8') for i in filterissues({'status':'10'}) if issue(i).activity < Date('2008-06-24')] #resolved [None, None, None, None, None, None, None, None, None, None, None, None, None, None, None, ... >>> db.commit() >>> $ }}} Note the commit is done soon after opening the db connection, since I'm not sure how an open db connection interacts with simultaneous changes via the web. See also -------- - `BugTrackerIssueManagement `_ - `BugTrackerKeywordValues `_