doc:config: use :file: to markup filenames.
[be.git] / release.py
index 23ac47649f0ce76b05baefc148d0897e592264fd..1dee068edac95cc00cc4e8b2132a52240563c526 100755 (executable)
@@ -1,30 +1,32 @@
 #!/usr/bin/python
 #
-# Copyright (C) 2009-2010 W. Trevor King <wking@drexel.edu>
+# Copyright (C) 2009-2012 Chris Ball <cjb@laptop.org>
+#                         W. Trevor King <wking@tremily.us>
 #
 # This file is part of Bugs Everywhere.
 #
-# Bugs Everywhere 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 2 of the License, or (at your
-# option) any later version.
+# Bugs Everywhere 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 2 of the License, or (at your option) any
+# later version.
 #
 # Bugs Everywhere 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.
+# 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 Bugs Everywhere.  If not, see <http://www.gnu.org/licenses/>.
+# You should have received a copy of the GNU General Public License along with
+# Bugs Everywhere.  If not, see <http://www.gnu.org/licenses/>.
 
+import codecs
+import optparse
 import os
 import os.path
 import shutil
 import string
 import sys
 
-from libbe.util.subproc import Pipe, invoke
-from update_copyright import update_authors, update_files
+from libbe.util.subproc import invoke
 
 
 INITIAL_COMMIT = '1bf1ec598b436f41ff27094eddf0b28c797e359d'
@@ -66,7 +68,7 @@ def pending_changes():
 
 def set_release_version(tag):
     print "set libbe.version._VERSION = '%s'" % tag
-    invoke(['sed', '-i', "s/^*_VERSION *=.*/_VERSION = '%s'/" % tag,
+    invoke(['sed', '-i', "s/^[# ]*_VERSION *=.*/_VERSION = '%s'/" % tag,
             os.path.join('libbe', 'version.py')])
 
 def remove_makefile_libbe_version_dependencies(filename):
@@ -80,15 +82,16 @@ def commit(commit_message):
 
 def tag(tag):
     print 'tag current revision', tag
-    invoke(['git', 'tag', tag])
+    invoke(['git', 'tag', '-s', '-m', 'version {}'.format(tag), tag])
 
 def export(target_dir):
     if not target_dir.endswith(os.path.sep):
         target_dir += os.path.sep
     print 'export current revision to', target_dir
-    p = Pipe([['git', 'archive', '--prefix', target_dir, 'HEAD'],
-              ['tar', '-xv']])
-    assert p.status == 0, p.statuses
+    status,stdout,stderr = invoke(
+        ['git', 'archive', '--prefix', target_dir, 'HEAD'],
+        unicode_output=False)
+    status,stdout,stderr = invoke(['tar', '-xv'], stdin=stdout)
 
 def make_version():
     print 'generate libbe/_version.py'
@@ -101,9 +104,12 @@ def make_changelog(filename, tag):
     by hand is just too slow.
     """
     print 'generate ChangeLog file', filename, 'up to tag', tag
-    invoke(['git', 'log', '--no-merges',
-            '%s..%s' % (INITIAL_COMMIT, tag)],
-           stdout=open(filename, 'w')),
+    status,stdout,stderr = invoke(
+        ['git', 'log', '--no-merges', '{}..{}'.format(INITIAL_COMMIT, tag)])
+    with codecs.open(filename, 'w', 'utf-8') as f:
+        for line in stdout.splitlines():
+            f.write(line.rstrip())
+            f.write(u'\n')
 
 def set_vcs_name(be_dir, vcs_name='None'):
     """Exported directory is not a git repository, so set vcs_name to
@@ -119,6 +125,11 @@ def set_vcs_name(be_dir, vcs_name='None'):
             invoke(['sed', '-i', "s/^vcs_name:.*/vcs_name: %s/" % vcs_name,
                     filename])
 
+def make_id_cache():
+    """Generate .be/id-cache so users won't need to.
+    """
+    invoke([sys.executable, './be', 'list'])
+
 def create_tarball(tag):
     release_name='be-%s' % tag
     export_dir = release_name
@@ -130,6 +141,10 @@ def create_tarball(tag):
     shutil.copy(os.path.join('libbe', '_version.py'),
                 os.path.join(export_dir, 'libbe', '_version.py'))
     make_changelog(os.path.join(export_dir, 'ChangeLog'), tag)
+    make_id_cache()
+    print 'copy .be/id-cache to %s/.be/id-cache' % export_dir
+    shutil.copy(os.path.join('.be', 'id-cache'),
+                os.path.join(export_dir, '.be', 'id-cache'))
     set_vcs_name(os.path.join(export_dir, '.be'))
     tarball_file = '%s.tar.gz' % release_name
     print 'create tarball', tarball_file
@@ -141,8 +156,7 @@ def test():
     import doctest
     doctest.testmod() 
 
-if __name__ == '__main__':
-    import optparse
+def main(*args, **kwargs):
     usage = """%prog [options] TAG
 
 Create a git tag and a release tarball from the current revision.
@@ -156,7 +170,7 @@ If you don't like what got committed, you can undo the release with
     p = optparse.OptionParser(usage)
     p.add_option('--test', dest='test', default=False,
                  action='store_true', help='Run internal tests and exit')
-    options,args = p.parse_args()
+    options,args = p.parse_args(*args, **kwargs)
 
     if options.test == True:
         test()
@@ -171,8 +185,19 @@ If you don't like what got committed, you can undo the release with
         sys.exit(1)
     set_release_version(_tag)
     print "Update copyright information..."
-    update_authors()
-    update_files()
+    env = dict(os.environ)
+    pythonpath = os.path.abspath('update-copyright')
+    if 'PYTHONPATH' in env:
+        env['PYTHONPATH'] = '{}:{}'.format(pythonpath, env['PYTHONPATH'])
+    else:
+        env['PYTHONPATH'] = pythonpath
+    status,stdout,stderr = invoke([
+            os.path.join('update-copyright', 'bin', 'update-copyright.py')],
+            env=env)
     commit("Bumped to version %s" % _tag)
     tag(_tag)
     create_tarball(_tag)
+
+
+if __name__ == '__main__':
+    main()