blob: f304692506054bd6976358113c8eec634a26bab8 [file] [log] [blame]
#!/usr/bin/env python3
# -*- coding: utf-8 -*-"
#
# Copyright 2020 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Find missing stable and backported mainline fix patches in chromeos."""
from __future__ import print_function
import MySQLdb
import common
DEFAULT_MERGED_REASON = 'Fix merged into linux chrome'
def get_fixes_table_primary_key(db, fixes_table, fix_change_id):
"""Retrieves the primary keys from a fixes table using changeid."""
c = db.cursor(MySQLdb.cursors.DictCursor)
q = """SELECT kernel_sha, fixedby_upstream_sha
FROM {fixes_table}
WHERE fix_change_id = %s""".format(fixes_table=fixes_table)
c.execute(q, [fix_change_id])
row = c.fetchone()
return (row['kernel_sha'], row['fixedby_upstream_sha'])
def get_fix_status_and_changeid(db, fixes_table, kernel_sha, fixedby_upstream_sha):
"""Get branch, fix_change_id, initial_status and status for a unique row in fixes table."""
c = db.cursor(MySQLdb.cursors.DictCursor)
q = """SELECT branch, fix_change_id, initial_status, status
FROM {fixes_table}
WHERE kernel_sha = %s
AND fixedby_upstream_sha = %s""".format(fixes_table=fixes_table)
c.execute(q, [kernel_sha, fixedby_upstream_sha])
row = c.fetchone()
return row
def update_change_abandoned(db, fixes_table, kernel_sha, fixedby_upstream_sha, reason=None):
"""Updates fixes_table unique fix row to indicate fix cl has been abandoned.
Function will only abandon rows in the table which have status OPEN or CONFLICT.
"""
c = db.cursor()
q = """UPDATE {fixes_table}
SET status = 'ABANDONED', close_time = %s, reason = %s
WHERE kernel_sha = %s
AND fixedby_upstream_sha = %s
AND (status = 'OPEN' OR status = 'CONFLICT')""".format(fixes_table=fixes_table)
close_time = common.get_current_time()
c.execute(q, [close_time, reason, kernel_sha, fixedby_upstream_sha])
db.commit()
def update_change_restored(db, fixes_table, kernel_sha, fixedby_upstream_sha, reason=None):
"""Updates fixes_table unique fix row to indicate fix cl has been reopened."""
row = get_fix_status_and_changeid(db, fixes_table, kernel_sha, fixedby_upstream_sha)
status = 'OPEN' if row['fix_change_id'] else row['initial_status']
c = db.cursor()
q = """UPDATE {fixes_table}
SET status = %s, close_time = %s, reason = %s
WHERE kernel_sha = %s
AND fixedby_upstream_sha = %s
AND status = 'ABANDONED'""".format(fixes_table=fixes_table)
close_time = None
c.execute(q, [status, close_time, reason, kernel_sha, fixedby_upstream_sha])
db.commit()
def update_change_merged(db, fixes_table, kernel_sha, fixedby_upstream_sha,
reason=DEFAULT_MERGED_REASON):
"""Updates fixes_table unique fix row to indicate fix cl has been merged."""
c = db.cursor()
q = """UPDATE {fixes_table}
SET status = 'MERGED', close_time = %s, reason = %s
WHERE kernel_sha = %s
AND fixedby_upstream_sha = %s""".format(fixes_table=fixes_table)
close_time = common.get_current_time()
c.execute(q, [close_time, reason, kernel_sha, fixedby_upstream_sha])
db.commit()
def update_change_status(db, fixes_table, fix_change_id, status):
"""Updates fixes_table with the latest status from Gerrit API.
This is done to synchronize CL's that are
abandoned/restored on Gerrit with our database state
"""
kernel_sha, fixedby_upstream_sha = get_fixes_table_primary_key(db, fixes_table, fix_change_id)
if status == common.Status.OPEN:
update_change_restored(db, fixes_table, kernel_sha, fixedby_upstream_sha)
elif status == common.Status.ABANDONED:
update_change_abandoned(db, fixes_table, kernel_sha, fixedby_upstream_sha)
elif status == common.Status.MERGED:
update_change_merged(db, fixes_table, kernel_sha, fixedby_upstream_sha)
else:
raise ValueError('Change should be either OPEN, ABANDONED, or MERGED')
def update_conflict_to_open(db, fixes_table, kernel_sha, fixedby_upstream_sha, fix_change_id):
"""Updates fixes_table to represent an open change that previously resulted in conflict."""
c = db.cursor()
reason = 'Patch applies cleanly after originally conflicting.'
q = """UPDATE {fixes_table}
SET status = 'OPEN', fix_change_id = %s, reason = %s
WHERE kernel_sha = %s
AND fixedby_upstream_sha = %s""".format(fixes_table=fixes_table)
c.execute(q, [fix_change_id, reason, kernel_sha, fixedby_upstream_sha])
db.commit()