Mercurial > mozilla > hg > licenser
view licenser/licenses.py @ 18:c04a53145f19
interpolate the files, i hope
author | Jeff Hammel <jhammel@mozilla.com> |
---|---|
date | Thu, 24 Nov 2011 14:50:24 -0800 |
parents | 4566b3ac9838 |
children | 73e815e13914 |
line wrap: on
line source
# ***** BEGIN LICENSE BLOCK ***** # Version: MPL 1.1/GPL 2.0/LGPL 2.1 # # The contents of this file are subject to the Mozilla Public License Version # 1.1 (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # http://www.mozilla.org/MPL/ # # Software distributed under the License is distributed on an "AS IS" basis, # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License # for the specific language governing rights and limitations under the # License. # # The Original Code is mozilla.org code. # # The Initial Developer of the Original Code is # Mozilla.org. # Portions created by the Initial Developer are Copyright (C) 2010 # the Initial Developer. All Rights Reserved. # # Contributor(s): # Jeff Hammel <jhammel@mozilla.com> (Original author) # # Alternatively, the contents of this file may be used under the terms of # either of the GNU General Public License Version 2 or later (the "GPL"), # or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), # in which case the provisions of the GPL or the LGPL are applicable instead # of those above. If you wish to allow use of your version of this file only # under the terms of either the GPL or the LGPL, and not to allow others to # use your version of this file under the terms of the MPL, indicate your # decision by deleting the provisions above and replace them with the notice # and other provisions required by the GPL or the LGPL. If you do not delete # the provisions above, a recipient may use your version of this file under # the terms of any one of the MPL, the GPL or the LGPL. # # ***** END LICENSE BLOCK ***** import os import urllib2 from datetime import datetime from string import Template # types of comments class CommentedFile(object): extensions = set() @classmethod def match(cls, filename): basename, extension = os.path.splitext(os.path.basename(filename)) if extension in extensions: return cls(filename) def __init__(self, filename): self.filename = filename def isempty(self): return bool(file(self.filename).read().strip) def lines(self): if hasattr(self, '_lines'): return self._lines self._lines = file(self.filename).readlines() return self._lines class AsteriskCommentsFile(CommentedFile): extensions = set(['c']) def __call__(self, license): # open the file for writing raise NotImplementedError class HashCommentsFile(object): extensions = set(['py', 'sh']) def __call__(self, license): """interpolate the file""" if self.isempty(): return # you're done lines = self.lines() # open the file for writing f = file(self.filename, 'w') # print shebang if it exists if lines[0].startswith('#!'): shebang = lines.pop(0).strip() print >> f, shebang print >> f # print the license f.write(license) # print the rest of the file for line in lines: f.write(line) f.close() def isempty(self, path): """ determines if a file is empty; that is, contains only comments """ for line in self.lines(): line = line.strip() if line and line[0] != '#': return False return True filetypes = [HashCommentsFile, AsteriskCommentsFile] class License(object): """Abstract base class for a license""" variables = [] # required variables def __init__(self, filetypes=filetypes[:]): if self.template: if not os.path.isabs(self.template): self.template = os.path.join(os.path.dirname(__file__), 'licenses', self.template) assert os.path.exists(self.template) self.filetypes = filetypes def license(self): return file(self.template).read() def print_license(self): print self.license() def token(self): """a token indicative of the license, by default the first line""" return self.license.splitlines()[0].strip() def has_license(self, filename): """does the file already have a license?""" token = self.token() for line in file(filename).readlines(): if token in line: return True return False def __call__(self, directory, **kw): variables = self.obtain_variables(**kw) self.interpolate(directory, variables) def obtain_variables(self, **kw): for var in self.variables: if var not in kw: print 'Enter %s: ' % var, kw[var] = raw_input() self.pre(kw) return kw def pre(self, variables): """do anything that needs to be done with the variables before interpolation""" def filetype(self, _file): """determine the filetype for a given file""" for filetype in self.filetypes: match = filetype.match(_file) if match: return match def interpolate_file(self, _file, variables): # if the file is licensed, no need to proceed if self.has_license(filename): return # you're done # get the filetype filetype = self.filetype(_file) if not filetype: return # you're done # get the license # XXX should be cached license = self.license() license = Template(license).substitute(**variables) # add the license to the file filetype(license) def interpolate(self, directory, variables): for _file in self.files(directory): self.interpolate_file(_file, variables) def files(self, directory): files = set() for dirpath, _, filenames in os.walk(directory): for f in filenames: path = os.path.join(dirpath, f) return files class MPL(License): """Mozilla Public License""" template = 'MPL' # could be implicit here variables = [ 'author', 'email' ] url = 'http://www.mozilla.org/MPL/boilerplate-1.1/mpl-tri-license-txt' def license(self): if hasattr(self, '_license'): # return the cached copy return self._license # get the raw license raw = urllib2.urlopen(self.url).read() # now make it something not crazy lines = raw.splitlines() contributor_index = None for index, line in enumerate(lines): if line.startswith('The Original Code is'): lines[index] = 'The Original Code is mozilla.org code.' if line.startswith('_'): lines[index] = 'the Mozilla Foundation.' if '2___' in line: lines[index] = line.replace('2___', '${year}') if line.startswith('Contributor'): contributor_index = index assert contributor_index lines.insert(contributor_index+1, ' ${author} <${email}>') self._license = '\n'.join(lines) return self._license def pre(self, variables): variables['year'] = datetime.now().year