# HG changeset patch # User simonis # Date 1431009677 -7200 # Thu May 07 16:41:17 2015 +0200 # Node ID b8c0abd952b93a6dfc2e357fd0b3e8301e04c1ec # Parent 196ab0ad64ad1940fd906bcd6d095c77b6465fed 7901298: jcheck should check that every file ends with exactly one newline Summary: also remove trailing whitespace and ^L characters from jcheck.py because apparently jcheck.py itself isn't checked by jcheck diff --git a/jcheck.py b/jcheck.py --- a/jcheck.py +++ b/jcheck.py @@ -1,21 +1,21 @@ # # Copyright (c) 2007, 2012, Oracle and/or its affiliates. All rights reserved. # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. -# +# # This code is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License version 2 only, as # published by the Free Software Foundation. -# +# # This code is distributed in the hope that it will be useful, but WITHOUT # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License # version 2 for more details (a copy is included in the LICENSE file that # accompanied this code). -# +# # You should have received a copy of the GNU General Public License version # 2 along with this work; if not, write to the Free Software Foundation, # Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. -# +# # Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA # or visit www.oracle.com if you need additional information or have any # questions. @@ -53,7 +53,7 @@ def datestr(ctx): # Mercurial 0.9.5 and earlier append a time zone; strip it. return util.datestr(ctx.date(), format="%Y-%m-%d %H:%M")[:16] - + def oneline(ctx): return ("%5d:%s %-12s %s %s\n" % (ctx.rev(), short(ctx.node()), ctx.user(), datestr(ctx), @@ -86,7 +86,6 @@ if not getattr(t, 'branchmap', None): setattr(t, 'branchmap', t.branchtags) - # Configuration-file parsing def load_conf(root): @@ -113,7 +112,6 @@ raise util.Abort("%s: Missing property: %s" % (fn, pn)) return cf - # Author validation author_cache = { } ## Should really cache more permanently @@ -137,10 +135,10 @@ author_cache[an] = True return True - # Whitespace and comment validation -badwhite_re = re.compile("(\t)|([ \t]$)|\r", re.MULTILINE) +badwhite_comment_re = re.compile("(\t)|([ \t]$)|(\r)", re.MULTILINE) +badwhite_with_eof_re = re.compile("(\t)|([ \t]$)|(\r)|([^\n]\Z)|(\n\n+\Z)", re.MULTILINE) normext_re = re.compile(".*\.(java|c|h|cpp|hpp)$") tag_desc_re = re.compile("Added tag [^ ]+ for changeset [0-9a-f]{12}") @@ -151,7 +149,11 @@ return "Tab character" if m.group(2): return "Trailing whitespace" - return "Carriage return (^M)" + if m.group(3): + return "Carriage return (^M)" + if m.group(4): + return "No newline (\\n) at the end of file" + return "More than one newline (\\n) at the end of file" base_addr_pat = "[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}" addr_pat = ("(" + base_addr_pat + ")" @@ -226,7 +228,7 @@ b = int(m.group(1)) if not b in bugids: bugids[b] = ctx.rev() - + # Should cache this, eventually bugids = { } # bugid -> rev opts = { 'rev' : ['0:tip'] } @@ -248,7 +250,6 @@ ui.debug("Bugids: %s\n" % bugids) return bugids - # Black/white lists ## The black/white lists should really be in the database @@ -362,7 +363,6 @@ # Path to file containing additional blacklisted changesets blacklist_file = '/oj/db/hg/blacklist' - # Checker class @@ -389,6 +389,24 @@ if self.conf.get("comments") == "lax": self.comments_lax = True self.tags_lax = lax and not strict + # Test if we should check for a correct EOF (i.e. files end with exatly one '\n') + # This behaviour is controlled by the 'check_eof' attribute in the conf file. + # -1 means to not check for EOF at all. + # 0 means to potentially check all the changes for a correct EOF. + # any other positive number is interpreted as the revision number or change- + # set ID from which on jcheck should start checking for a correct EOF. + # If the 'check_eof' attribute is missing, '-1' (i.e. no EOF check) will be assumed. + if self.conf.has_key("check_eof"): + check_eof_cs = self.conf.get("check_eof") + if not check_eof_cs.startswith("-"): + try: + self.check_eof = repo[check_eof_cs].rev() + except: + self.check_eof = -1 + else: + self.check_eof = -1 + else: + self.check_eof = -1 if self.conf.get("tags") == "lax": self.tags_lax = True self.bugids_allow_dups = self.conf.get("bugids") == "dup" @@ -446,7 +464,7 @@ self.cs_author = ctx.user() def c_01_comment(self, ctx): - m = badwhite_re.search(ctx.description()) + m = badwhite_comment_re.search(ctx.description()) if m: ln = ctx.description().count("\n", 0, m.start()) + 1 self.error(ctx, "%s in comment (line %d)" % (badwhite_what(m), ln)) @@ -518,6 +536,10 @@ files = modified + added if self.ui.debugflag: self.ui.debug("Checking files: %s\n" % ", ".join(files)) + if self.check_eof != -1 and ctx.rev() >= self.check_eof: + badwhite_re = badwhite_with_eof_re + else: + badwhite_re = badwhite_comment_re for f in files: if ctx.rev() == 0: ## This is loathsome