< prev index next >

./jcheck.py

Print this page
rev 113 : Allow start=YYYY-MM-DD in .jcheck/conf; older changesets are not checked


  27 # Quick configuration: Add the following to your ~/.hgrc:
  28 #
  29 #   [extensions]
  30 #   jcheck = /path/to/jcheck.py
  31 #
  32 #   # Omit these lines if you use Mercurial Queues
  33 #   [hooks]
  34 #   pretxnchangegroup.jcheck = python:jcheck.hook
  35 #   pretxncommit.jcheck = python:jcheck.hook
  36 #
  37 #   # Include this if you use the (deprecated) Mercurial "fetch" extension
  38 #   [defaults]
  39 #   fetch = -m Merge
  40 #
  41 # For more information: http://openjdk.java.net/projects/code-tools/jcheck/
  42 
  43 _version = "@VERSION@"
  44 _date = "@DATE@"
  45 
  46 import sys, os, re, urllib, urllib2

  47 from mercurial.node import *
  48 from mercurial import cmdutil, patch, util, context, templater
  49 
  50 Pass = False
  51 Fail = True
  52 
  53 def datestr(ctx):
  54     # Mercurial 0.9.5 and earlier append a time zone; strip it.
  55     return util.datestr(ctx.date(), format="%Y-%m-%d %H:%M")[:16]
  56 
  57 def oneline(ctx):
  58     return ("%5d:%s  %-12s  %s  %s\n"
  59             % (ctx.rev(), short(ctx.node()), ctx.user(), datestr(ctx),
  60                ctx.description().splitlines()[0]))
  61 





  62 def is_merge(repo, rev):
  63     return not (-1 in repo.changelog.parentrevs(rev))
  64 
  65 _matchall = getattr(cmdutil, 'matchall', None)
  66 if not _matchall:
  67     try:
  68         from mercurial import scmutil
  69         _matchall = scmutil.matchall
  70     except ImportError:
  71         pass
  72 
  73 def repocompat(repo):
  74     # Modern mercurial versions use len(repo) and repo[cset_id]; enable those
  75     # operations with older versions.
  76     t = type(repo)
  77     if not getattr(t, '__len__', None):
  78         def repolen(self):
  79             return self.changelog.count()
  80         setattr(t, '__len__', repolen)
  81     if not getattr(t, '__getitem__', None):


 475         self.conf = load_conf(repo.root)
 476         self.whitespace_lax = lax and not strict
 477         if self.conf.get("whitespace") == "lax":
 478             self.whitespace_lax = True
 479         self.comments_lax = lax and not strict
 480         if self.conf.get("comments") == "lax":
 481             self.comments_lax = True
 482         self.tags_lax = lax and not strict
 483         if self.conf.get("tags") == "lax":
 484             self.tags_lax = True
 485         self.bugids_allow_dups = self.conf.get("bugids") == "dup"
 486         self.bugids_lax = lax and not strict
 487         if self.conf.get("bugids") == "lax":
 488             self.bugids_lax = True
 489         self.bugids_ignore = False
 490         if self.conf.get("bugids") == "ignore":
 491             self.bugids_ignore = True
 492         if not self.bugids_ignore:
 493             # only identify bug ids if we are going to use them
 494             self.repo_bugids = repo_bugids(ui, repo)







 495         self.blacklist = dict.fromkeys(changeset_blacklist)
 496         self.read_blacklist(blacklist_file)
 497         # hg < 1.0 does not have localrepo.tagtype()
 498         self.tagtype = getattr(self.repo, 'tagtype', lambda k: 'global')
 499 
 500     def read_blacklist(self, fname):
 501         if not os.path.exists(fname):
 502             return
 503         self.ui.debug('Reading blacklist file %s\n' % fname)
 504         f = open(fname)
 505         for line in f:
 506             # Any comment after the changeset hash becomes the dictionary value.
 507             l = [s.strip() for s in line.split('#', 1)]
 508             if l and l[0]:
 509                 self.blacklist[l[0]] = len(l) == 2 and l[1] or None
 510         f.close()
 511 
 512     def summarize(self, ctx):
 513         self.ui.status("\n")
 514         self.ui.status("> Changeset: %d:%s\n" % (ctx.rev(), short(ctx.node())))


 618             fx = ctx.filectx(f)
 619             if normext_re.match(f) and not self.whitespace_lax:
 620                 data = fx.data()
 621                 if "\t" in data or "\r" in data or " \n" in data:
 622                     m = badwhite_re.search(data)
 623                     if m:
 624                         ln = data.count("\n", 0, m.start()) + 1
 625                         self.error(ctx, "%s:%d: %s" % (f, ln, badwhite_what(m)))
 626             ## check_file_header(self, fx, data)
 627             flags = fx.manifest().flags(f)
 628             if 'x' in flags:
 629                 self.error(ctx, "%s: Executable files not permitted" % f)
 630             if 'l' in flags:
 631                 self.error(ctx, "%s: Symbolic links not permitted" % f)
 632 
 633     def c_03_hash(self, ctx):
 634         hash = hex(ctx.node())
 635         if hash in self.blacklist:
 636             self.error(ctx, "Blacklisted changeset: " + hash)
 637 








 638     def check(self, node):
 639         self.summarized = False
 640         self.cs_bugids = [ ]
 641         self.cs_author = None
 642         self.cs_reviewers = [ ]
 643         self.cs_contributor = None
 644         ctx = context.changectx(self.repo, node)
 645         self.ui.note(oneline(ctx))
 646         if not self.strict and hex(node) in changeset_whitelist:
 647             self.ui.note("%s in whitelist; skipping\n" % hex(node))
 648             return Pass




 649         for c in self.checks:
 650             cf = checker.__dict__[c]
 651             cf(self, ctx)
 652         return self.rv
 653 
 654     def check_repo(self):
 655 
 656         if not self.tags_lax:
 657             ts = self.repo.tags().keys()
 658             ignoredtypes = ['local']
 659             for t in ts:
 660                 if not tag_re.match(t) and not self.tagtype(t) in ignoredtypes:
 661                     self.error(None,
 662                                "Illegal tag name: %s" % t)
 663 
 664         bs = self.repo.branchmap()
 665         if len(bs) > 1:
 666             bs = bs.copy()
 667             del bs["default"]
 668             self.error(None,




  27 # Quick configuration: Add the following to your ~/.hgrc:
  28 #
  29 #   [extensions]
  30 #   jcheck = /path/to/jcheck.py
  31 #
  32 #   # Omit these lines if you use Mercurial Queues
  33 #   [hooks]
  34 #   pretxnchangegroup.jcheck = python:jcheck.hook
  35 #   pretxncommit.jcheck = python:jcheck.hook
  36 #
  37 #   # Include this if you use the (deprecated) Mercurial "fetch" extension
  38 #   [defaults]
  39 #   fetch = -m Merge
  40 #
  41 # For more information: http://openjdk.java.net/projects/code-tools/jcheck/
  42 
  43 _version = "@VERSION@"
  44 _date = "@DATE@"
  45 
  46 import sys, os, re, urllib, urllib2
  47 from datetime import date
  48 from mercurial.node import *
  49 from mercurial import cmdutil, patch, util, context, templater
  50 
  51 Pass = False
  52 Fail = True
  53 
  54 def datestr(ctx):
  55     # Mercurial 0.9.5 and earlier append a time zone; strip it.
  56     return util.datestr(ctx.date(), format="%Y-%m-%d %H:%M")[:16]
  57 
  58 def oneline(ctx):
  59     return ("%5d:%s  %-12s  %s  %s\n"
  60             % (ctx.rev(), short(ctx.node()), ctx.user(), datestr(ctx),
  61                ctx.description().splitlines()[0]))
  62 
  63 # Take a date string of the form YYYY-MM-DD and return a date
  64 def todate(dstr):
  65     darr = dstr.split('-')
  66     return date(int(darr[0]), int(darr[1]), int(darr[2]))
  67 
  68 def is_merge(repo, rev):
  69     return not (-1 in repo.changelog.parentrevs(rev))
  70 
  71 _matchall = getattr(cmdutil, 'matchall', None)
  72 if not _matchall:
  73     try:
  74         from mercurial import scmutil
  75         _matchall = scmutil.matchall
  76     except ImportError:
  77         pass
  78 
  79 def repocompat(repo):
  80     # Modern mercurial versions use len(repo) and repo[cset_id]; enable those
  81     # operations with older versions.
  82     t = type(repo)
  83     if not getattr(t, '__len__', None):
  84         def repolen(self):
  85             return self.changelog.count()
  86         setattr(t, '__len__', repolen)
  87     if not getattr(t, '__getitem__', None):


 481         self.conf = load_conf(repo.root)
 482         self.whitespace_lax = lax and not strict
 483         if self.conf.get("whitespace") == "lax":
 484             self.whitespace_lax = True
 485         self.comments_lax = lax and not strict
 486         if self.conf.get("comments") == "lax":
 487             self.comments_lax = True
 488         self.tags_lax = lax and not strict
 489         if self.conf.get("tags") == "lax":
 490             self.tags_lax = True
 491         self.bugids_allow_dups = self.conf.get("bugids") == "dup"
 492         self.bugids_lax = lax and not strict
 493         if self.conf.get("bugids") == "lax":
 494             self.bugids_lax = True
 495         self.bugids_ignore = False
 496         if self.conf.get("bugids") == "ignore":
 497             self.bugids_ignore = True
 498         if not self.bugids_ignore:
 499             # only identify bug ids if we are going to use them
 500             self.repo_bugids = repo_bugids(ui, repo)
 501         self.use_start = False
 502         self.startdate = None
 503         startstr = self.conf.get("start")
 504         if startstr != None:
 505             self.use_start = True
 506             self.startdate = todate(startstr)
 507         ui.debug("self.use_start = %s, self.startdate = %s\n" % (self.use_start, self.startdate))
 508         self.blacklist = dict.fromkeys(changeset_blacklist)
 509         self.read_blacklist(blacklist_file)
 510         # hg < 1.0 does not have localrepo.tagtype()
 511         self.tagtype = getattr(self.repo, 'tagtype', lambda k: 'global')
 512 
 513     def read_blacklist(self, fname):
 514         if not os.path.exists(fname):
 515             return
 516         self.ui.debug('Reading blacklist file %s\n' % fname)
 517         f = open(fname)
 518         for line in f:
 519             # Any comment after the changeset hash becomes the dictionary value.
 520             l = [s.strip() for s in line.split('#', 1)]
 521             if l and l[0]:
 522                 self.blacklist[l[0]] = len(l) == 2 and l[1] or None
 523         f.close()
 524 
 525     def summarize(self, ctx):
 526         self.ui.status("\n")
 527         self.ui.status("> Changeset: %d:%s\n" % (ctx.rev(), short(ctx.node())))


 631             fx = ctx.filectx(f)
 632             if normext_re.match(f) and not self.whitespace_lax:
 633                 data = fx.data()
 634                 if "\t" in data or "\r" in data or " \n" in data:
 635                     m = badwhite_re.search(data)
 636                     if m:
 637                         ln = data.count("\n", 0, m.start()) + 1
 638                         self.error(ctx, "%s:%d: %s" % (f, ln, badwhite_what(m)))
 639             ## check_file_header(self, fx, data)
 640             flags = fx.manifest().flags(f)
 641             if 'x' in flags:
 642                 self.error(ctx, "%s: Executable files not permitted" % f)
 643             if 'l' in flags:
 644                 self.error(ctx, "%s: Symbolic links not permitted" % f)
 645 
 646     def c_03_hash(self, ctx):
 647         hash = hex(ctx.node())
 648         if hash in self.blacklist:
 649             self.error(ctx, "Blacklisted changeset: " + hash)
 650 
 651     def before_start(self, ctx):
 652         if not self.use_start:
 653             return False
 654         csdatestr = datestr(ctx).split()[0]
 655         csdate = todate(csdatestr)
 656         self.ui.debug("startdate = %s, cs date = %s\n" % (self.startdate, csdate))
 657         return csdate < self.startdate
 658 
 659     def check(self, node):
 660         self.summarized = False
 661         self.cs_bugids = [ ]
 662         self.cs_author = None
 663         self.cs_reviewers = [ ]
 664         self.cs_contributor = None
 665         ctx = context.changectx(self.repo, node)
 666         self.ui.note(oneline(ctx))
 667         if not self.strict and hex(node) in changeset_whitelist:
 668             self.ui.note("%s in whitelist; skipping\n" % hex(node))
 669             return Pass
 670         if self.before_start(ctx):
 671             # Before start date; only do blacklist check
 672             self.c_03_hash(ctx);
 673             return self.rv
 674         for c in self.checks:
 675             cf = checker.__dict__[c]
 676             cf(self, ctx)
 677         return self.rv
 678 
 679     def check_repo(self):
 680 
 681         if not self.tags_lax:
 682             ts = self.repo.tags().keys()
 683             ignoredtypes = ['local']
 684             for t in ts:
 685                 if not tag_re.match(t) and not self.tagtype(t) in ignoredtypes:
 686                     self.error(None,
 687                                "Illegal tag name: %s" % t)
 688 
 689         bs = self.repo.branchmap()
 690         if len(bs) > 1:
 691             bs = bs.copy()
 692             del bs["default"]
 693             self.error(None,


< prev index next >