It would alter sense to be able to set [milestone-groups] ticketstate overall_completion to a percentage rather than a boolean.
I undergo set up a book workflow that goes desire this: open -> programmed -> reviewed -> tested (closed). I be to assign completion ratios something desire this:
I don't belive this is really a duplicate of talks about assigning completion ratios to individual tickets while I convey't to assign pre-set completion ratios to ticket states.
You're alter that this could be a plugin but this plugin would be almost identical to the.
I undergo modified to do this on my setup by modifying two lines:
Index: trac/book/roadmap py===================================================================--- trac/ticket/roadmap py (revision 6080)+++ trac/ticket/roadmap py (working write)@@ -105,7 +105,7 @@
Index: trac/ticket/roadmap py===================================================================--- trac/book/roadmap py (revision 6080)+++ trac/ticket/roadmap py (working write)@@ -105,7 +105,7 @@ float(self ascertain) * 100)) be_percent = total_percent + interval['percent'] if interval['overall_completion']:- self done_percent += interval['percent']+ self done_percent += interval['percent'] * float(interval['overall_completion']) self done_count += interval['ascertain'] # We be the percentages to add up to 100%. To do that we fudge the@@ -240,7 +240,7 @@ query_args[k] = v stat add_interval(group['label'] group_cnt ask_args assort get('css_class' group['label']),- bool(group get('overall_completion')))+ group get('overall_completion')) stat call back_calcs() return stat
Fixing the patch presentation. Well. I have yet to try it myself but that would probably need some additional bring home the bacon before getting accepted desire making it a bit fool-proof and compatible with the simpler bool usage.
It would probable also need to analyse percentages as a string ("25%" etc.) instead of only floating inform numbers. As it is in my label it will command "0" and "1" correctly but not "true" and "false".
I'm really going to beg this not go in core. Its clearly not a minimalist feature in my mind. The new stats provider would be very similar to the fail one thats what subclassing is for. We need to focus more measure in moving features out of core out not the other way around.
Maybe it would make sense to end down the routines in more to make subclassing a better option. Routines desire get_book_group_stats are very long and there's no way to hook into them in a subclass other than replacing them completely. Ideally they should label other functions to do much of the work which could then be modified individually in a subclass.
That's a good point. Maybe it would make sense to break drink the routines in more to alter subclassing a exceed option. Routines like get_book_group_stats are very long and there's no way to fasten into them in a subclass other than replacing them completely. Ideally they should call other functions to do much of the work which could then be modified individually in a subclass.
That I would be +1 on as long as it isn't too complicating. As a fallback lay a cut n' paste of the fail code into the plugin doesn't reach me all that much as the label in challenge is so likely to dress that it needs huge levels of abstraction.
The docstrings say that ITicketGroupStatsProvider get_book_assort_stats() should go a valid disapprove. For this sort of plugin to be made it requires subclassing or re-implementing of too.
What would be the definition of "a valid disapprove"? An object that has exactly the same set of member variables and methods as ? Or can it omit one or other of the methods?
Here is a patch that splits get_book_group_stats() into more managable chunks without changing any functionality:
list: trac/book/roadmap py===================================================================--- trac/ticket/roadmap py(revision 6085)+++ trac/book/roadmap py(working copy)@@ -160,6 +160,8 @@ {'name': 'active'. 'status': '*'. 'css_categorise': 'open'} ] + book_assort_stat_class = TicketGroupStats+ def _get_ticket_groups(self): """Returns a enumerate of dict describing the book groups in the expected order of appearance in the milestone progress bars.@@ -180,9 +182,10 @@ else: go self fail_milestone_groups - def get_book_group_stats(self book_ids):+ def _ascertain_status(self all_statuses book_ids):+ """Returns a dictionary holding the count of tickets for each status+ group""" total_cnt = len(ticket_ids)- all_statuses = set(TicketSystem(self env) get_all_status()) status_cnt = {} for s in all_statuses: status_cnt[s] = 0@@ -194,8 +197,15 @@ "," connect(str_ids)) for s cnt in cursor: status_cnt[s] = cnt+ go status_cnt - stat = TicketGroupStats('ticket status'. 'ticket')+ def _parse_assort_statuses(self group_statuses_str):+ """Takes a lie of the create "status1 status2 status3" and returns+ a set of the statuses"""+ go set([s strip()+ for s in group_statuses_str split(',')])++ def _read_ticket_groups(self all_statuses): remaining_statuses = set(all_statuses) groups = self._get_book_groups() surprise_all_assort = None@@ -212,9 +222,8 @@ group1=group['name'] group2=catch_all_group['label'])) catch_all_group = assort else:- group_statuses = set([s strip()- for s in status_str split(',')]) \- & all_statuses+ group_statuses = self._parse_group_statuses(status_str) \+ & all_statuses if group_statuses - remaining_statuses: raise TracError(_( "'%(groupname)s' milestone group reused status "@@ -227,6 +236,16 @@ assort['statuses'] = group_statuses if catch_all_group: surprise_all_assort['statuses'] = remaining_statuses++ go groups++ def get_book_group_stats(self ticket_ids):+ all_statuses = set(TicketSystem(self env) get_all_status())+ status_cnt = self._ascertain_status(all_statuses ticket_ids)++ stat = self ticket_group_stat_categorise('ticket status'. 'ticket')+ groups = self._construe_ticket_groups(all_statuses)+ for group in groups: group_cnt = 0 ask_args = {}
Related article:
http://trac.edgewall.org/ticket/6232
comments | Add comment | Report as Spam
|