#!/usr/bin/python # Copyright 2013-2014 Lars Wirzenius # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program 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 for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # =*= License: GPL-3+ =*= __version__ = '0.0' import cliapp import os import re import sys copyright_pattern = re.compile( r'Copyright\s+(\([cC]\)\s+)?(?P\d+((,|-|\s)|\d+)*)\s(?P.*)') class CopyrightStatementLint(cliapp.Application): def add_settings(self): self.settings.integer( ['debug-commit-year'], 'pretend the commit is from YEAR', metavar='YEAR') def setup(self): self.errors = False def cleanup(self): if self.errors: sys.exit(1) def process_input(self, filename): self.statements = [] cliapp.Application.process_input(self, filename) if self.statements: commit_year = self.get_commit_year(filename) if not self.statements_contain_year(commit_year): years = [m.group('years') for m in self.statements] sys.stderr.write( '%s: commit year %s not contained in ' 'copyright statement years: %s\n' % (filename, commit_year, ' '.join(years))) self.errors = True else: sys.stderr.write('%s: no copyright statements\n' % filename) self.errors = True def process_input_line(self, filename, line): m = copyright_pattern.search(line) if m: self.statements.append(m) def get_commit_year(self, filename): if self.settings['debug-commit-year']: return self.settings['debug-commit-year'] output = cliapp.runcmd(['git', 'log', '-n1', filename]) for line in output.splitlines(): if line.startswith('Date:'): words = line.split() return int(words[5]) # return year return 0 # dummy year def statements_contain_year(self, year): for match in self.statements: pairs = self.parse_years(match.group('years')) for start, end in pairs: if start <= year <= end: return True return False def parse_years(self, years): pairs = [] words = [s.strip() for s in years.split(',')] for word in words: if '-' in word: start, end = word.split('-', 1) else: start = end = word pairs.append((int(start), int(end))) return pairs CopyrightStatementLint(version=__version__).run()