comparison doc/customizing.txt @ 1559:6bfb9c9de03c

added blockers customisation example to doc
author Richard Jones <richard@users.sourceforge.net>
date Wed, 26 Mar 2003 06:03:58 +0000
parents d20680d611a6
children 3f2e516b8de3
comparison
equal deleted inserted replaced
1558:7914c286b68e 1559:6bfb9c9de03c
1 =================== 1 ===================
2 Customising Roundup 2 Customising Roundup
3 =================== 3 ===================
4 4
5 :Version: $Revision: 1.78 $ 5 :Version: $Revision: 1.79 $
6 6
7 .. This document borrows from the ZopeBook section on ZPT. The original is at: 7 .. This document borrows from the ZopeBook section on ZPT. The original is at:
8 http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx 8 http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx
9 9
10 .. contents:: 10 .. contents::
2893 </tal:block> 2893 </tal:block>
2894 </tal:block> 2894 </tal:block>
2895 </table> 2895 </table>
2896 2896
2897 2897
2898 Blocking issues that depend on other issues
2899 -------------------------------------------
2900
2901 We needed the ability to mark certain issues as "blockers" - that is,
2902 they can't be resolved until another issue (the blocker) they rely on
2903 is resolved. To achieve this:
2904
2905 1. Create a new property on the issue Class, ``blockers=Multilink("issue")``.
2906 Edit your tracker's dbinit.py file. Where the "issue" class is defined,
2907 something like::
2908
2909 issue = IssueClass(db, "issue",
2910 assignedto=Link("user"), topic=Multilink("keyword"),
2911 priority=Link("priority"), status=Link("status"))
2912
2913 add the blockers entry like so::
2914
2915 issue = IssueClass(db, "issue",
2916 blockers=Multilink("issue"),
2917 assignedto=Link("user"), topic=Multilink("keyword"),
2918 priority=Link("priority"), status=Link("status"))
2919
2920 2. Add the new "blockers" property to the issue.item edit page, using
2921 something like:
2922
2923 <th nowrap>Waiting On</th>
2924 <td>
2925 <span tal:replace="structure python:context.blockers.field(showid=1,
2926 size=20)" />
2927 <span tal:replace="structure python:db.issue.classhelp('id,title')" />
2928 <span tal:condition="context/blockers" tal:repeat="blk context/blockers">
2929 <br>View: <a tal:attributes="href string:issue${blk/id}"
2930 tal:content="blk/id"></a>
2931 </span>
2932
2933 You'll need to fiddle with your item page layout to find an appropriate
2934 place to put it - I'll leave that fun part up to you. Just make sure it
2935 appears in the first table, possibly somewhere near the "superseders"
2936 field.
2937
2938 3. Create a new detector module (attached) which enforces the rules:
2939
2940 - issues may not be resolved if they have blockers
2941 - when a blocker is resolved, it's removed from issues it blocks
2942
2943 The contents of the detector should be something like this::
2944
2945 def blockresolution(db, cl, nodeid, newvalues):
2946 ''' If the issue has blockers, don't allow it to be resolved.
2947 '''
2948 if nodeid is None:
2949 blockers = []
2950 else:
2951 blockers = cl.get(nodeid, 'blockers')
2952 blockers = newvalues.get('blockers', blockers)
2953
2954 # don't do anything if there's no blockers or the status hasn't changed
2955 if not blockers or not newvalues.has_key('status'):
2956 return
2957
2958 # get the resolved state ID
2959 resolved_id = db.status.lookup('resolved')
2960
2961 # format the info
2962 u = db.config.TRACKER_WEB
2963 s = ', '.join(['<a href="%sissue%s">%s</a>'%(u,id,id) for id in blockers])
2964 if len(blockers) == 1:
2965 s = 'issue %s is'%s
2966 else:
2967 s = 'issues %s are'%s
2968
2969 # ok, see if we're trying to resolve
2970 if newvalues['status'] == resolved_id:
2971 raise ValueError, "This issue can't be resolved until %s resolved."%s
2972
2973 def resolveblockers(db, cl, nodeid, newvalues):
2974 ''' When we resolve an issue that's a blocker, remove it from the
2975 blockers list of the issue(s) it blocks.
2976 '''
2977 if not newvalues.has_key('status'):
2978 return
2979
2980 # get the resolved state ID
2981 resolved_id = db.status.lookup('resolved')
2982
2983 # interesting?
2984 if newvalues['status'] != resolved_id:
2985 return
2986
2987 # yes - find all the blocked issues, if any, and remove me from their
2988 # blockers list
2989 issues = cl.find(blockers=nodeid)
2990 for issueid in issues:
2991 blockers = cl.get(issueid, 'blockers')
2992 if nodeid in blockers:
2993 blockers.remove(nodeid)
2994 cl.set(issueid, blockers=blockers)
2995
2996
2997 def init(db):
2998 # might, in an obscure situation, happen in a create
2999 db.issue.audit('create', blockresolution)
3000 db.issue.audit('set', blockresolution)
3001
3002 # can only happen on a set
3003 db.issue.react('set', resolveblockers)
3004
3005 Put the above code in a file called "blockers.py" in your tracker's
3006 "detectors" directory.
3007
3008 4. Finally, and this is an optional step, modify the tracker web page URLs
3009 so they filter out issues with any blockers. You do this by adding an
3010 additional filter on "blockers" for the value "-1". For example, the
3011 existing "Show All" link in the "page" template (in the tracker's
3012 "html" directory) looks like this::
3013
3014 <a href="issue?:sort=-activity&:group=priority&:filter=status&:columns=id,activity,title,creator,assignedto,status&status=-1,1,2,3,4,5,6,7">Show All</a><br>
3015
3016 modify it to add the "blockers" info to the URL (note, both the
3017 ":filter" *and* "blockers" values must be specified)::
3018
3019 <a href="issue?:sort=-activity&:group=priority&:filter=status,blockers@blockers=-1&:columns=id,activity,title,creator,assignedto,status&status=-1,1,2,3,4,5,6,7">Show All</a><br>
3020
3021 That's it. You should now be able to se blockers on your issues. Note that
3022 if you want to know whether an issue has any other issues dependent on it
3023 (ie. it's in their blockers list) you can look at the journal history
3024 at the bottom of the issue page - look for a "link" event to another
3025 issue's "blockers" property.
3026
3027
2898 ------------------- 3028 -------------------
2899 3029
2900 Back to `Table of Contents`_ 3030 Back to `Table of Contents`_
2901 3031
2902 .. _`Table of Contents`: index.html 3032 .. _`Table of Contents`: index.html

Roundup Issue Tracker: http://roundup-tracker.org/