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':
 | 
					    if record_type == 'Code-Review':
 | 
				
			||||||
        result_by_param['metric'] += 1
 | 
					        result_by_param['metric'] += 1
 | 
				
			||||||
        value = record.value
 | 
					        value = record.value
 | 
				
			||||||
 | 
					    elif record_type == 'Abandon':
 | 
				
			||||||
 | 
					        result_by_param['metric'] += 1
 | 
				
			||||||
 | 
					        value = 'x'
 | 
				
			||||||
    elif record.type == 'Workflow':
 | 
					    elif record.type == 'Workflow':
 | 
				
			||||||
        if record.value == 1:
 | 
					        if record.value == 1:
 | 
				
			||||||
            value = 'A'
 | 
					            value = 'A'
 | 
				
			||||||
@@ -265,7 +268,7 @@ def mark_finalize(record):
 | 
				
			|||||||
    positive = 0
 | 
					    positive = 0
 | 
				
			||||||
    numeric = 0
 | 
					    numeric = 0
 | 
				
			||||||
    mark_distribution = []
 | 
					    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 record:
 | 
				
			||||||
            if key in [1, 2]:
 | 
					            if key in [1, 2]:
 | 
				
			||||||
                positive += record[key]
 | 
					                positive += record[key]
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -182,7 +182,7 @@ def get_activity(records, start_record, page_size, query_message=None):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def get_contribution_summary(records):
 | 
					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
 | 
					    commit_count = 0
 | 
				
			||||||
    loc = 0
 | 
					    loc = 0
 | 
				
			||||||
    drafted_blueprint_count = 0
 | 
					    drafted_blueprint_count = 0
 | 
				
			||||||
@@ -208,6 +208,10 @@ def get_contribution_summary(records):
 | 
				
			|||||||
                    value = 'WIP'
 | 
					                    value = 'WIP'
 | 
				
			||||||
            elif record.type == 'Code-Review':
 | 
					            elif record.type == 'Code-Review':
 | 
				
			||||||
                value = record.value
 | 
					                value = record.value
 | 
				
			||||||
 | 
					            elif record.type == 'Abandon':
 | 
				
			||||||
 | 
					                value = 'x'
 | 
				
			||||||
 | 
					            elif record.type[:5] == 'Self-':
 | 
				
			||||||
 | 
					                value = 's'
 | 
				
			||||||
            marks[value] += 1
 | 
					            marks[value] += 1
 | 
				
			||||||
        elif record_type == 'email':
 | 
					        elif record_type == 'email':
 | 
				
			||||||
            email_count += 1
 | 
					            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>Change Id: <a href="${parent_url}" target="_blank">${review_id}</a></div>
 | 
				
			||||||
            <div style="color: {%if value > 0 %} green {%else%} blue {%/if%}">
 | 
					            <div style="color: {%if value > 0 %} green {%else%} blue {%/if%}">
 | 
				
			||||||
                {%if (type == "Workflow" && value == 1) %}
 | 
					                {%if (type == "Workflow" && value == 1) %}
 | 
				
			||||||
                Approved
 | 
					                Approve
 | 
				
			||||||
                {%elif (type == "Self-Workflow" && value == 1) %}
 | 
					                {%elif (type == "Self-Workflow" && value == 1) %}
 | 
				
			||||||
                Self-Approved
 | 
					                Self-Approve
 | 
				
			||||||
                {%elif (type == "Workflow" && value == -1) %}
 | 
					                {%elif (type == "Workflow" && value == -1) %}
 | 
				
			||||||
                Work in progress
 | 
					                Work in progress
 | 
				
			||||||
 | 
					                {%elif (type == "Abandon" || type == "Self-Abandon") %}
 | 
				
			||||||
 | 
					                ${type}
 | 
				
			||||||
                {%else%}
 | 
					                {%else%}
 | 
				
			||||||
                ${type}: <span class="review_mark">${value}</span>
 | 
					                ${type}: <span class="review_mark">${value}</span>
 | 
				
			||||||
                {%/if%}
 | 
					                {%/if%}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,9 +29,14 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
<script id="contribution_template" type="text/x-jquery-tmpl">
 | 
					<script id="contribution_template" type="text/x-jquery-tmpl">
 | 
				
			||||||
{% raw %}
 | 
					{% raw %}
 | 
				
			||||||
<div>Total commits: <b>${commit_count}</b></div>
 | 
					<div>Commits: <b>${commit_count}</b></div>
 | 
				
			||||||
<div>Total LOC: <b>${loc}</b></div>
 | 
					<div>LOCs: <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>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>
 | 
					<div>Change Requests: <b>${change_request_count}</b>
 | 
				
			||||||
 {%if abandoned_change_requests_count > 0 %}
 | 
					 {%if abandoned_change_requests_count > 0 %}
 | 
				
			||||||
   <span>(${abandoned_change_requests_count} of them abandoned)</span>
 | 
					   <span>(${abandoned_change_requests_count} of them abandoned)</span>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -101,7 +101,7 @@
 | 
				
			|||||||
                <th>#</th>
 | 
					                <th>#</th>
 | 
				
			||||||
                <th>{% if show_ci %}Driver{% else %}Contributor{% endif %}</th>
 | 
					                <th>{% if show_ci %}Driver{% else %}Contributor{% endif %}</th>
 | 
				
			||||||
                {% if show_review_ratio %}
 | 
					                {% if show_review_ratio %}
 | 
				
			||||||
                    <th>-2|-1|+1|+2|A (+ ratio)</th>
 | 
					                    <th>-2|-1|+1|+2|A|x (+ ratio)</th>
 | 
				
			||||||
                {% endif %}
 | 
					                {% endif %}
 | 
				
			||||||
                <th>{{ metric_label }}</th>
 | 
					                <th>{{ metric_label }}</th>
 | 
				
			||||||
                {% if show_ci %}
 | 
					                {% if show_ci %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -23,7 +23,7 @@
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        $(document).ready(function () {
 | 
					        $(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"];
 | 
					                                      "review_ratio", "commit", "email"];
 | 
				
			||||||
            var table_id = "review_stats_table";
 | 
					            var table_id = "review_stats_table";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -95,7 +95,7 @@
 | 
				
			|||||||
                            "aaData": tableData,
 | 
					                            "aaData": tableData,
 | 
				
			||||||
                            "aoColumns": tableColumns,
 | 
					                            "aoColumns": tableColumns,
 | 
				
			||||||
                            "aoColumnDefs": [
 | 
					                            "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]}
 | 
					                                { "sType": "ratio", "aTargets": [8, 10]}
 | 
				
			||||||
                            ]
 | 
					                            ]
 | 
				
			||||||
                        });
 | 
					                        });
 | 
				
			||||||
@@ -144,11 +144,12 @@
 | 
				
			|||||||
                <th>#</th>
 | 
					                <th>#</th>
 | 
				
			||||||
                <th>Engineer</th>
 | 
					                <th>Engineer</th>
 | 
				
			||||||
                <th>Reviews</th>
 | 
					                <th>Reviews</th>
 | 
				
			||||||
                <th>-2</th>
 | 
					                <th title="Do not merge (-2)">-2</th>
 | 
				
			||||||
                <th>-1</th>
 | 
					                <th title="Patch needs further work (-1)">-1</th>
 | 
				
			||||||
                <th>+1</th>
 | 
					                <th title="Looks good (+1)">+1</th>
 | 
				
			||||||
                <th>+2</th>
 | 
					                <th title="Looks good for core (+2)">+2</th>
 | 
				
			||||||
                <th>A</th>
 | 
					                <th title="Approve">A</th>
 | 
				
			||||||
 | 
					                <th title="Abandon">x</th>
 | 
				
			||||||
                <th>+ %</th>
 | 
					                <th>+ %</th>
 | 
				
			||||||
                <th>Disagreements</th>
 | 
					                <th>Disagreements</th>
 | 
				
			||||||
                <th>Ratio</th>
 | 
					                <th>Ratio</th>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,6 +13,8 @@
 | 
				
			|||||||
# See the License for the specific language governing permissions and
 | 
					# See the License for the specific language governing permissions and
 | 
				
			||||||
# limitations under the License.
 | 
					# limitations under the License.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import itertools
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from oslo_config import cfg
 | 
					from oslo_config import cfg
 | 
				
			||||||
from oslo_log import log as logging
 | 
					from oslo_log import log as logging
 | 
				
			||||||
import psutil
 | 
					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)
 | 
					        last_retrieval_time = runtime_storage_inst.get_by_key(rcs_key)
 | 
				
			||||||
        current_retrieval_time = int(time.time())
 | 
					        current_retrieval_time = int(time.time())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        review_iterator = rcs_inst.log(repo, branch, last_retrieval_time,
 | 
					        review_iterator = itertools.chain(
 | 
				
			||||||
                                       grab_comments=('ci' in repo))
 | 
					            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')
 | 
					        review_iterator_typed = _record_typer(review_iterator, 'review')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        processed_review_iterator = record_processor_inst.process(
 | 
					        processed_review_iterator = record_processor_inst.process(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -428,6 +428,17 @@ class RecordProcessor(object):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                yield self._make_mark_record(record, patch, approval)
 | 
					                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):
 | 
					    def _guess_module(self, record):
 | 
				
			||||||
        subject = record['subject'].lower()
 | 
					        subject = record['subject'].lower()
 | 
				
			||||||
        pos = len(subject)
 | 
					        pos = len(subject)
 | 
				
			||||||
@@ -818,7 +829,7 @@ class RecordProcessor(object):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            patch_id = utils.get_patch_id(record['review_id'], record['patch'])
 | 
					            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['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']
 | 
					                    record['type'] = 'Self-%s' % record['type']
 | 
				
			||||||
                    yield record
 | 
					                    yield record
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user