new_contents: #!/usr/bin/env python
  # -*- coding: utf-8 -*-
  """
      make-release
      ~~~~~~~~~~~~
  
      Helper script that performs a release.  Does pretty much everything
      automatically for us.
  
      :copyright: (c) 2011 by Armin Ronacher.
      :license: BSD, see LICENSE for more details.
  """
  import sys
  import os
  import re
  from datetime import datetime, date
  from subprocess import Popen, PIPE
  
  _date_clean_re = re.compile(r'(\d+)(st|nd|rd|th)')
  
  
  def installed_libraries():
      return set(Popen(['pip', 'freeze'], stdout=PIPE).communicate()[0].splitlines())
  
  
  def has_library_installed(library):
      return library + '==' in installed_libraries()
  
  
  def parse_changelog():
      with open('CHANGES') as f:
          lineiter = iter(f)
          for line in lineiter:
              match = re.search('^Version\s+(.*)', line.strip())
  
              if match is None:
                  continue
  
              version = match.group(1).strip()
  
              if lineiter.next().count('-') != len(line.strip()):
                  fail('Invalid hyphen count below version line: %s', line.strip())
  
              while 1:
                  released = lineiter.next().strip()
                  if released:
                      break
  
              match = re.search(r'Released (\w+\s+\d+\w+\s+\d+)', released)
  
              if match is None:
                  fail('Could not find release date in version %s' % version)
  
              datestr = parse_date(match.group(1).strip())
  
              return version, datestr
  
  
  def bump_version(version):
      try:
          parts = map(int, version.split('.'))
      except ValueError:
          fail('Current version is not numeric')
      parts[-1] += 1
      return '.'.join(map(str, parts))
  
  
  def parse_date(string):
      string = _date_clean_re.sub(r'\1', string)
      return datetime.strptime(string, '%B %d %Y')
  
  
  def set_filename_version(filename, version_number, pattern):
      changed = []
  
      def inject_version(match):
          before, old, after = match.groups()
          changed.append(True)
          return before + version_number + after
  
      with open(filename) as f:
          contents = re.sub(r"^(\s*%s\s*=\s*')(.+?)(')(?sm)" % pattern,
                            inject_version, f.read())
  
      if not changed:
          fail('Could not find %s in %s', pattern, filename)
  
      with open(filename, 'w') as f:
          f.write(contents)
  
  
  def set_init_version(version):
      info('Setting __init__.py version to %s', version)
      set_filename_version('flask_principal/__init__.py', version, '__version__')
  
  
  def set_setup_version(version):
      info('Setting setup.py version to %s', version)
      set_filename_version('setup.py', version, 'version')
  
  
  def set_docs_version(version):
      info('Setting docs/conf.py version to %s', version)
      set_filename_version('docs/conf.py', version, 'version')
  
  
  def build_and_upload():
      Popen([sys.executable, 'setup.py', 'sdist', 'build_sphinx', 'upload', 'upload_sphinx']).wait()
  
  
  def fail(message, *args):
      print >> sys.stderr, 'Error:', message % args
      sys.exit(1)
  
  
  def info(message, *args):
      print >> sys.stderr, message % args
  
  
  def get_git_tags():
      return set(Popen(['git', 'tag'], stdout=PIPE).communicate()[0].splitlines())
  
  
  def git_is_clean():
      return Popen(['git', 'diff', '--quiet']).wait() == 0
  
  
  def make_git_commit(message, *args):
      message = message % args
      Popen(['git', 'commit', '-am', message]).wait()
  
  
  def make_git_tag(tag):
      info('Tagging "%s"', tag)
      Popen(['git', 'tag', '-a', tag, '-m', '%s release' % tag]).wait()
      Popen(['git', 'push', '--tags']).wait()
  
  
  def update_version(version):
      for f in [set_init_version, set_setup_version, set_docs_version]:
          f(version)
  
  
  def get_branches():
      return set(Popen(['git', 'branch'], stdout=PIPE).communicate()[0].splitlines())
  
  
  def branch_is(branch):
      return '* ' + branch in get_branches()
  
  
  def main():
      os.chdir(os.path.join(os.path.dirname(__file__), '..'))
  
      rv = parse_changelog()
  
      if rv is None:
          fail('Could not parse changelog')
  
      version, release_date = rv
  
      tags = get_git_tags()
  
      if version in tags:
          fail('Version "%s" is already tagged', version)
      if release_date.date() != date.today():
          fail('Release date is not today')
  
      if not branch_is('master'):
          fail('You are not on the master branch')
  
      if not git_is_clean():
          fail('You have uncommitted changes in git')
  
      for lib in ['Sphinx', 'Sphinx-PyPI-upload']:
          if not has_library_installed(lib):
              fail('Build requires that %s be installed', lib)
  
      info('Releasing %s (release date %s)',
           version, release_date.strftime('%d/%m/%Y'))
  
      update_version(version)
      make_git_commit('Bump version number to %s', version)
      make_git_tag(version)
      build_and_upload()
  
  
  if __name__ == '__main__':
      main()
  
subject: Add release script