summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xunperish143
1 files changed, 122 insertions, 21 deletions
diff --git a/unperish b/unperish
index ebe3f61..133b2df 100755
--- a/unperish
+++ b/unperish
@@ -27,10 +27,61 @@ import shutil
import subprocess
import tempfile
-
__version__ = '0.0'
+class VcsOps(object):
+
+ '''Abstract base class for VCS dependent operations.'''
+
+ def __init__(self, app):
+ self.app = app
+
+ def one_of_ours(self):
+ '''Is this project using our VCS?'''
+ raise NotImplemented()
+
+ def uncommitted_changes(self):
+ '''Does the project have uncommitted changes?'''
+ raise NotImplemented()
+
+ def export_tarball(self, filename):
+ '''Export the sources into an uncompressed tarball.'''
+ raise NotImplemented()
+
+
+class BzrOps(VcsOps):
+
+ def one_of_ours(self):
+ return os.path.isdir('.bzr')
+
+ def uncommitted_changes(self):
+ out = self.app.runcmd(['bzr', 'status', '--short'])
+ return [line.split()[1] for line in out.splitlines()]
+
+ def export_tarball(self, filename):
+ prefix, ext = os.path.splitext(filename)
+ root = os.path.basename(prefix)
+ self.app.runcmd(['bzr', 'export', '--format=tar', '--root=%s' % root,
+ filename])
+
+
+class GitOps(VcsOps):
+
+ def one_of_ours(self):
+ return os.path.isdir('.git')
+
+ def uncommitted_changes(self):
+ out = self.app.runcmd(['git', 'status', '--short'])
+ return [line.split()[1] for line in out.splitlines()]
+
+ def export_tarball(self, filename):
+ prefix, ext = os.path.splitext(filename)
+ root = os.path.basename(prefix)
+ self.app.runcmd(['git', 'archive', '--prefix=%s/' % root,
+ '--output=%s' % filename, 'HEAD'])
+
+
class Unperish(cliapp.Application):
def add_settings(self):
@@ -80,6 +131,7 @@ class Unperish(cliapp.Application):
def process_args(self, args):
self.deduce_unset_settings()
+ self.deduce_vcs()
self.create_build_area()
self.already = set()
@@ -120,6 +172,19 @@ class Unperish(cliapp.Application):
if not self.settings[name]:
self.settings[name] = table[name]()
+ def deduce_vcs(self):
+ classes = [
+ BzrOps,
+ GitOps,
+ ]
+
+ for klass in classes:
+ obj = klass(self)
+ if obj.one_of_ours():
+ self.vcs = obj
+ return
+ raise cliapp.AppException('Do not know this VCS, if any.')
+
def create_build_area(self):
if not os.path.exists(self.settings['build-area']):
os.mkdir(self.settings['build-area'])
@@ -197,9 +262,10 @@ class Unperish(cliapp.Application):
'''Check that all changes have been committed.'''
if not self.settings['use-uncommitted']:
- out = self.runcmd(['bzr', 'status'])
- if out:
- raise cliapp.AppException('Uncommitted changes:\n\n%s' % out)
+ changes = self.vcs.uncommitted_changes()
+ if changes:
+ raise cliapp.AppException('Uncommitted changes:\n%s' %
+ '\n'.join(changes))
def cmd_dget(self, args):
'''Retrieve a Debian source package (.dsc and other files).
@@ -216,30 +282,63 @@ class Unperish(cliapp.Application):
self.runcmd(['dget', '--download-only', self.settings['dsc']],
cwd=self.settings['build-area'])
+ def cmd_export_upstream_tarball(self, args):
+ '''Export upstream sources as a compressed tarball.
+
+ The tarball won't include debian/ directory, if any.
+
+ '''
+ self.run_subcommand('committed')
+ tarball = self.join(self.upstream_tarball)
+ if not self.already_exists(tarball):
+ tempdir = tempfile.mkdtemp()
+
+ dirname = '%s-%s' % (self.upstream_name, self.upstream_version)
+ temp_tar = os.path.join(tempdir, dirname + '.tar')
+ self.vcs.export_tarball(temp_tar)
+ self.runcmd(['tar', '-xf', dirname + '.tar'], cwd=tempdir)
+
+ if self.settings['use-uncommitted']:
+ for name in self.vcs.uncommitted_changes():
+ shutil.copy2(name, self.join(tempdir, dirname, name))
+
+ debian_dir = os.path.join(tempdir, dirname, 'debian')
+ if os.path.exists(debian_dir):
+ shutil.rmtree(debian_dir)
+
+ self.runcmd(['tar', '-caf', tarball, dirname], cwd=tempdir)
+
+ shutil.rmtree(tempdir)
+
def cmd_export(self, args):
- '''Export unpacked source directory to build area.'''
+ '''Export unpacked source directory to build area.
+
+ This will include the debian/ directory, too.
+
+ '''
self.run_subcommand('committed')
- if not self.already_exists(self.join(self.dirname)):
- self.runcmd(['bzr', 'export', self.join(self.dirname)])
+ dirname = self.join(self.dirname)
+ if not self.already_exists(dirname):
+ temp_tar = os.path.join(dirname + '.tar')
+ self.vcs.export_tarball(temp_tar)
+ self.runcmd(['tar', '-xf', dirname + '.tar'],
+ cwd=self.settings['build-area'])
+ os.remove(temp_tar)
+
if self.settings['use-uncommitted']:
- out = self.runcmd(['bzr', 'status', '--versioned', '--short'])
- for line in out.splitlines():
- status, name = line.split()
- target = self.join(self.dirname, name)
- shutil.copy2(name, target)
+ for name in self.vcs.uncommitted_changes():
+ shutil.copy2(name, self.join(dirname, name))
+
+ if not self.already_exists(self.join(self.dirname)):
+ self.runcmd(['tar', '-xf', self.join(self.upstream_tarball)],
+ cwd=self.settings['build-area'])
def cmd_debian_tarball(self, args):
'''Generate Debian tarball (.orig.tar.gz) in build area.'''
- self.run_subcommand('committed')
+ self.run_subcommand('export-upstream-tarball')
origtar = self.join(self.debian_tarball)
if not self.already_exists(origtar):
- tempdir = tempfile.mkdtemp()
- exported = os.path.join(tempdir, os.path.basename(self.dirname))
- self.runcmd(['bzr', 'export', exported])
- shutil.rmtree(os.path.join(exported, 'debian'))
- self.runcmd(['tar', '-C', tempdir, '-czf', origtar,
- os.path.basename(exported)])
- shutil.rmtree(tempdir)
+ os.link(self.join(self.upstream_tarball), origtar)
def cmd_dsc(self, args):
'''Create Debian source package (.dsc) in build area.'''
@@ -252,6 +351,7 @@ class Unperish(cliapp.Application):
def cmd_deb(self, args):
'''Build Debian binary packages (.deb) in build area.'''
+ self.run_subcommand('dsc')
self.run_subcommand('export')
targets = {}
@@ -392,7 +492,8 @@ class Unperish(cliapp.Application):
cwd=self.join(self.dirname))
def join(self, *components):
- components = (self.settings['build-area'],) + components
+ area = os.path.abspath(self.settings['build-area'])
+ components = (area,) + components
return os.path.join(*components)
def runcmd(self, argv, *args, **kwargs):