Comments.py revision cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#! /usr/bin/python
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# CDDL HEADER START
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# The contents of this file are subject to the terms of the
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# Common Development and Distribution License (the "License").
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# You may not use this file except in compliance with the License.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# or http://www.opensolaris.org/os/licensing.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# See the License for the specific language governing permissions
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# and limitations under the License.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# When distributing Covered Code, include this CDDL HEADER in each
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# If applicable, add the following below this CDDL HEADER, with the
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# fields enclosed by brackets "[]" replaced with your own identifying
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# information: Portions Copyright [yyyy] [name of copyright owner]
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# CDDL HEADER END
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# Use is subject to license terms.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# ident "%Z%%M% %I% %E% SMI"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# Check delta comments:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# - Have the correct form.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# - Have a synopsis matching that of the CR or ARC case.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# - Appear only once.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsonimport re, sys
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsonfrom onbld.Checks.DbLookups import BugDB, ARC
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsonarcre = re.compile(r'^([A-Z][A-Z]*ARC[/ \t][12]\d{3}/\d{3}) (.*)$')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsonbugre = re.compile(r'^(\d{7}) (.*)$')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef isARC(comment):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return arcre.match(comment)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef isBug(comment):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return bugre.match(comment)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# Translate any acceptable case number format into "<ARC> <YEAR>/<NUM>"
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson# format.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson#
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef normalize_arc(caseid):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return re.sub(r'^([A-Z][A-Z]*ARC)[/ \t]', '\\1 ', caseid)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelsondef comchk(comments, check_db=True, output=sys.stderr):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson bugnospcre = re.compile(r'^(\d{7})([^ ].*)')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ignorere = re.compile(r'^(Contributed by .*|backout \d{7})')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson errors = { 'bugnospc': [],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'mutant': [],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'dup': [],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'nomatch': [],
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson 'nonexistent': [] }
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson bugs = {}
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson arcs = {}
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ret = blanks = 0
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for com in comments:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # Ignore valid comments we can't check
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if ignorere.search(com):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson continue
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if not com or com.isspace():
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson blanks += 1
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson continue
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson match = bugre.search(com)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if match:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if match.group(1) not in bugs:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson bugs[match.group(1)] = []
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson bugs[match.group(1)].append(match.group(2))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson continue
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson #
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # Bugs missing a space after the ID are still bugs
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # for the purposes of the duplicate ID and synopsis
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # checks.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson #
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson match = bugnospcre.search(com)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if match:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if match.group(1) not in bugs:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson bugs[match.group(1)] = []
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson bugs[match.group(1)].append(match.group(2))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson errors['bugnospc'].append(com)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson continue
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # ARC case
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson match = arcre.search(com)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if match:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson case = normalize_arc(match.group(1))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if case not in arcs: arcs[case] = []
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson arcs[case].append(match.group(2))
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson continue
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # Anything else is bogus
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson errors['mutant'].append(com)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if len(bugs) > 0 and check_db:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson bugdb = BugDB()
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson results = bugdb.lookup(bugs.keys())
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for crid, insts in bugs.iteritems():
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if len(insts) > 1:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson errors['dup'].append(crid)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if not check_db:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson continue
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if crid not in results:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson errors['nonexistent'].append(crid)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson continue
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for entered in insts:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson synopsis = results[crid]["synopsis"]
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if not re.search(re.escape(synopsis) +
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson r'( \([^)]+\))?$', entered):
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson errors['nomatch'].append([crid, synopsis,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson entered])
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for case, insts in arcs.iteritems():
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if len(insts) > 1:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson errors['dup'].append(case)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if not check_db:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson continue
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson com, id = case.split(' ')
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson arc = ARC(com, id)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if not arc.valid():
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson errors['nonexistent'].append(case)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson continue
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson #
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # The opensolaris.org ARC interfaces only give us the
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # first 40 characters of the case name, so we must limit
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # our checking similarly.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson #
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # We first try a direct match between the actual case name
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # and the entered comment. If that fails we remove a possible
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson # trailing (fix nit)-type comment, and re-try.
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson #
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for entered in insts:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if entered[0:40] == arc.name():
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson continue
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson else:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson dbcom = re.sub(r' \([^)]+\)$', '', entered)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if dbcom[0:40] != arc.name():
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson errors['nomatch'].append([case,
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson arc.name(),
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson entered])
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if blanks:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson output.write("WARNING: Blank line(s) in comments\n")
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ret = 1
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if errors['dup']:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ret = 1
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson output.write("These IDs appear more than once in your "
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson "comments:\n")
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for err in errors['dup']:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson output.write(" %s\n" % err)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if errors['bugnospc']:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ret = 1
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson output.write("These bugs are missing a single space following "
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson "the ID:\n")
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for com in errors['bugnospc']:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson output.write(" %s\n" % com)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if errors['mutant']:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ret = 1
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson output.write("These comments are neither bug nor ARC case:\n")
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for com in errors['mutant']:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson output.write(" %s\n" % com)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if errors['nonexistent']:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ret = 1
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson output.write("These bugs/ARC cases were not found in the "
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson "databases:\n")
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for id in errors['nonexistent']:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson output.write(" %s\n" % id)
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson if errors['nomatch']:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson ret = 1
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson output.write("These bugs/ARC case synopsis/names don't match "
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson "the database entries:\n")
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson for err in errors['nomatch']:
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson output.write("Synopsis/name of %s is wrong:\n" % err[0])
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson output.write(" should be: '%s'\n" % err[1])
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson output.write(" is: '%s'\n" % err[2])
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson
cdf0c1d55d9b3b6beaf994835440dfb01aef5cf0mjnelson return ret