Track abandon actions as reviews
Record of type 'mark' is created when reviewer abandons someone else's change requests. The stats on such marks is included into review stats Change-Id: I44955c72326c95bbf421ea47b177972e06aa6ca2 Closes-Bug: #1498769
This commit is contained in:
		| @@ -247,6 +247,9 @@ def mark_filter(result, record, param_id, context): | ||||
|     if record_type == 'Code-Review': | ||||
|         result_by_param['metric'] += 1 | ||||
|         value = record.value | ||||
|     elif record_type == 'Abandon': | ||||
|         result_by_param['metric'] += 1 | ||||
|         value = 'x' | ||||
|     elif record.type == 'Workflow': | ||||
|         if record.value == 1: | ||||
|             value = 'A' | ||||
| @@ -265,7 +268,7 @@ def mark_finalize(record): | ||||
|     positive = 0 | ||||
|     numeric = 0 | ||||
|     mark_distribution = [] | ||||
|     for key in [-2, -1, 1, 2, 'A']: | ||||
|     for key in [-2, -1, 1, 2, 'A', 'x']: | ||||
|         if key in record: | ||||
|             if key in [1, 2]: | ||||
|                 positive += record[key] | ||||
|   | ||||
| @@ -182,7 +182,7 @@ def get_activity(records, start_record, page_size, query_message=None): | ||||
|  | ||||
|  | ||||
| def get_contribution_summary(records): | ||||
|     marks = dict((m, 0) for m in [-2, -1, 0, 1, 2, 'A', 'WIP']) | ||||
|     marks = dict((m, 0) for m in [-2, -1, 0, 1, 2, 'A', 'WIP', 'x', 's']) | ||||
|     commit_count = 0 | ||||
|     loc = 0 | ||||
|     drafted_blueprint_count = 0 | ||||
| @@ -208,6 +208,10 @@ def get_contribution_summary(records): | ||||
|                     value = 'WIP' | ||||
|             elif record.type == 'Code-Review': | ||||
|                 value = record.value | ||||
|             elif record.type == 'Abandon': | ||||
|                 value = 'x' | ||||
|             elif record.type[:5] == 'Self-': | ||||
|                 value = 's' | ||||
|             marks[value] += 1 | ||||
|         elif record_type == 'email': | ||||
|             email_count += 1 | ||||
|   | ||||
| @@ -106,11 +106,13 @@ show_record_type=True, show_user_gravatar=True, gravatar_size=32, show_all=True) | ||||
|             <div>Change Id: <a href="${parent_url}" target="_blank">${review_id}</a></div> | ||||
|             <div style="color: {%if value > 0 %} green {%else%} blue {%/if%}"> | ||||
|                 {%if (type == "Workflow" && value == 1) %} | ||||
|                 Approved | ||||
|                 Approve | ||||
|                 {%elif (type == "Self-Workflow" && value == 1) %} | ||||
|                 Self-Approved | ||||
|                 Self-Approve | ||||
|                 {%elif (type == "Workflow" && value == -1) %} | ||||
|                 Work in progress | ||||
|                 {%elif (type == "Abandon" || type == "Self-Abandon") %} | ||||
|                 ${type} | ||||
|                 {%else%} | ||||
|                 ${type}: <span class="review_mark">${value}</span> | ||||
|                 {%/if%} | ||||
|   | ||||
| @@ -29,9 +29,14 @@ | ||||
|  | ||||
| <script id="contribution_template" type="text/x-jquery-tmpl"> | ||||
| {% raw %} | ||||
| <div>Total commits: <b>${commit_count}</b></div> | ||||
| <div>Total LOC: <b>${loc}</b></div> | ||||
| <div>Review stat (-2, -1, +1, +2, A): <b>${marks["-2"]}, ${marks["-1"]}, ${marks["1"]}, ${marks["2"]}, ${marks["A"]}</b></div> | ||||
| <div>Commits: <b>${commit_count}</b></div> | ||||
| <div>LOCs: <b>${loc}</b></div> | ||||
| <div>Do not merge (-2): <b>${marks["-2"]}</b> | ||||
| <div>Patch needs further work (-1): <b>${marks["-1"]}</b> | ||||
| <div>Looks good (+1): <b>${marks["1"]}</b> | ||||
| <div>Looks good for core (+2): <b>${marks["2"]}</b> | ||||
| <div>Approve: <b>${marks["A"]}</b> | ||||
| <div>Abandon: <b>${marks["x"]}</b> | ||||
| <div>Change Requests: <b>${change_request_count}</b> | ||||
|  {%if abandoned_change_requests_count > 0 %} | ||||
|    <span>(${abandoned_change_requests_count} of them abandoned)</span> | ||||
|   | ||||
| @@ -101,7 +101,7 @@ | ||||
|                 <th>#</th> | ||||
|                 <th>{% if show_ci %}Driver{% else %}Contributor{% endif %}</th> | ||||
|                 {% if show_review_ratio %} | ||||
|                     <th>-2|-1|+1|+2|A (+ ratio)</th> | ||||
|                     <th>-2|-1|+1|+2|A|x (+ ratio)</th> | ||||
|                 {% endif %} | ||||
|                 <th>{{ metric_label }}</th> | ||||
|                 {% if show_ci %} | ||||
|   | ||||
| @@ -23,7 +23,7 @@ | ||||
|         }); | ||||
|  | ||||
|         $(document).ready(function () { | ||||
|             var table_column_names = ["index", "link", "metric", "-2", "-1", "1", "2", "A", "positive_ratio", "disagreements", "disagreement_ratio", | ||||
|             var table_column_names = ["index", "link", "metric", "-2", "-1", "1", "2", "A", "x", "positive_ratio", "disagreements", "disagreement_ratio", | ||||
|                                       "review_ratio", "commit", "email"]; | ||||
|             var table_id = "review_stats_table"; | ||||
|  | ||||
| @@ -95,7 +95,7 @@ | ||||
|                             "aaData": tableData, | ||||
|                             "aoColumns": tableColumns, | ||||
|                             "aoColumnDefs": [ | ||||
|                                 { "sClass": "center", "aTargets": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13] }, | ||||
|                                 { "sClass": "center", "aTargets": [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] }, | ||||
|                                 { "sType": "ratio", "aTargets": [8, 10]} | ||||
|                             ] | ||||
|                         }); | ||||
| @@ -144,11 +144,12 @@ | ||||
|                 <th>#</th> | ||||
|                 <th>Engineer</th> | ||||
|                 <th>Reviews</th> | ||||
|                 <th>-2</th> | ||||
|                 <th>-1</th> | ||||
|                 <th>+1</th> | ||||
|                 <th>+2</th> | ||||
|                 <th>A</th> | ||||
|                 <th title="Do not merge (-2)">-2</th> | ||||
|                 <th title="Patch needs further work (-1)">-1</th> | ||||
|                 <th title="Looks good (+1)">+1</th> | ||||
|                 <th title="Looks good for core (+2)">+2</th> | ||||
|                 <th title="Approve">A</th> | ||||
|                 <th title="Abandon">x</th> | ||||
|                 <th>+ %</th> | ||||
|                 <th>Disagreements</th> | ||||
|                 <th>Ratio</th> | ||||
|   | ||||
| @@ -13,6 +13,8 @@ | ||||
| # See the License for the specific language governing permissions and | ||||
| # limitations under the License. | ||||
|  | ||||
| import itertools | ||||
|  | ||||
| from oslo_config import cfg | ||||
| from oslo_log import log as logging | ||||
| import psutil | ||||
| @@ -134,8 +136,12 @@ def _process_repo(repo, runtime_storage_inst, record_processor_inst, | ||||
|         last_retrieval_time = runtime_storage_inst.get_by_key(rcs_key) | ||||
|         current_retrieval_time = int(time.time()) | ||||
|  | ||||
|         review_iterator = rcs_inst.log(repo, branch, last_retrieval_time, | ||||
|                                        grab_comments=('ci' in repo)) | ||||
|         review_iterator = itertools.chain( | ||||
|             rcs_inst.log(repo, branch, last_retrieval_time, status='open'), | ||||
|             rcs_inst.log(repo, branch, last_retrieval_time, status='merged'), | ||||
|             rcs_inst.log(repo, branch, last_retrieval_time, status='abandoned', | ||||
|                          grab_comments=True), | ||||
|         ) | ||||
|         review_iterator_typed = _record_typer(review_iterator, 'review') | ||||
|  | ||||
|         processed_review_iterator = record_processor_inst.process( | ||||
|   | ||||
| @@ -428,6 +428,17 @@ class RecordProcessor(object): | ||||
|  | ||||
|                 yield self._make_mark_record(record, patch, approval) | ||||
|  | ||||
|         # check for abandon action | ||||
|         if record.get('status') == 'ABANDONED': | ||||
|             for comment in reversed(record.get('comments') or []): | ||||
|                 if comment['message'] == 'Abandoned': | ||||
|                     action = dict(type='Abandon', value=0) | ||||
|                     action['by'] = comment['reviewer'] | ||||
|                     action['grantedOn'] = comment['timestamp'] | ||||
|  | ||||
|                     yield self._make_mark_record( | ||||
|                         record, record['patchSets'][-1], action) | ||||
|  | ||||
|     def _guess_module(self, record): | ||||
|         subject = record['subject'].lower() | ||||
|         pos = len(subject) | ||||
| @@ -818,7 +829,7 @@ class RecordProcessor(object): | ||||
|  | ||||
|             patch_id = utils.get_patch_id(record['review_id'], record['patch']) | ||||
|             if record['user_id'] == patch_id_to_user_id.get(patch_id): | ||||
|                 if record['type'].find('Self-') < 0: | ||||
|                 if record['type'][:5] == 'Self-': | ||||
|                     record['type'] = 'Self-%s' % record['type'] | ||||
|                     yield record | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user
	 Ilya Shakhat
					Ilya Shakhat