From e3b9abffeb8c49682cd62bf7b93cc0ef5bf8546a Mon Sep 17 00:00:00 2001 From: Lars Wirzenius Date: Sun, 1 Jan 2012 19:05:50 +0000 Subject: add git support --- unperish | 143 +++++++++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 122 insertions(+), 21 deletions(-) (limited to 'unperish') 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): -- cgit v1.2.1