#!/usr/bin/python # Copyright 2011 Lars Wirzenius # # This program 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 3 of the License, or # (at your option) any later version. # # This program 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. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import cliapp import ConfigParser import debian.changelog import debian.deb822 import glob import logging import os import shutil import subprocess __version__ = '0.0' class Unperish(cliapp.Application): metafilename = 'project.meta' def add_settings(self): self.settings.boolean(['verbose', 'v'], 'print commands that are executed') self.settings.boolean(['no-act', 'dry-run', 'n'], 'don\'t run commands') self.settings.string(['build-area'], 'where should results go? (%default)', default='../build-area') self.settings.string(['basetgz'], 'pbuilder basetgz (%default)', default='/var/cache/pbuilder/base.tgz') self.settings.string(['upload-target'], 'generate debian/changelog entry for uploading ' 'to given target') def process_args(self, args): self.meta = self.create_meta() self.autofill_meta() self.read_meta() self.create_build_area() cmd_methods = self._subcommands() for arg in args: try: with open(self.join(self.dirname, 'debian', 'control')) as f: self.debian_control = debian.deb822.Deb822(f) except IOError: pass try: with open(self.join(self.dirname, 'debian', 'changelog')) as f: self.debian_changelog = debian.changelog.Changelog(f) except IOError: pass method = self._normalize_cmd(arg) if method in cmd_methods: if self.settings['verbose']: self.output.write('command: %s\n' % arg) if not self.settings['no-act']: getattr(self, method)([]) else: raise cliapp.AppException('unknown command %s' % arg) def create_build_area(self): if not os.path.exists(self.settings['build-area']): os.mkdir(self.settings['build-area']) @property def upstream_name(self): return self.meta.get('project', 'name') @property def upstream_version(self): return self.meta.get('project', 'version') @property def upstream_tarball(self): return '%s-%s.tar.gz' % (self.upstream_name, self.upstream_version) @property def debian_source_package(self): return self.debian_control['Source'] @property def debian_version(self): return self.debian_changelog.get_version() @property def debian_tarball(self): return '%s_%s.orig.tar.gz' % (self.debian_source_package, self.upstream_version) @property def dirname(self): return '%s-%s' % (self.upstream_name, self.upstream_version) def cmd_dump_meta(self, args): self.meta.write(self.output) def cmd_export(self, args): self.runcmd('bzr', 'export', self.join(self.dirname)) def cmd_debian_tarball(self, args): origtar = self.join(self.debian_tarball) self.runcmd('bzr', 'export', origtar) def cmd_dsc(self, args): if self.settings['upload-target']: self.add_debian_changelog_entry() self.runcmd('dpkg-source', '-b', self.dirname, cwd=self.settings['build-area']) def cmd_deb(self, args): pat = '%s_%s.dsc' % (self.debian_source_package, self.debian_version) dsc = glob.glob(self.join(pat))[0] argv = ['sudo', 'pbuilder', '--build', '--basetgz', self.settings['basetgz'], '--buildresult', self.settings['build-area'], '--logfile', self.join('pbuilder.log'), '--debbuildopts', '-sa', dsc] self.runcmd(*argv, cwd=self.settings['build-area']) def add_debian_changelog_entry(self): target = self.settings['upload-target'] self.runcmd('dch', '--force-distribution', '--local', target, '--distribution', target, 'Build for %s.' % target, cwd=self.join(self.dirname)) def create_meta(self): cp = ConfigParser.RawConfigParser() cp.add_section('project') cp.set('project', 'name', '') cp.set('project', 'version', '') return cp def autofill_meta(self): name = self.runcmd('python', 'setup.py', '--name').strip() if name: self.meta.set('project', 'name', name) version = self.runcmd('python', 'setup.py', '--version').strip() if version: self.meta.set('project', 'version', version) def read_meta(self): self.meta.read([self.metafilename]) def join(self, *components): components = (self.settings['build-area'],) + components return os.path.join(*components) def runcmd(self, *argv, **kwargs): logging.debug('runcmd: %s' % repr(argv)) if self.settings['verbose']: self.output.write('run: %s\n' % ' '.join(argv)) p = subprocess.Popen(argv, stdout=subprocess.PIPE, stderr=subprocess.PIPE, **kwargs) out, err = p.communicate() if p.returncode: raise cliapp.AppException('command failed: %s\n%s' % (argv, err)) return out if __name__ == '__main__': Unperish(version=__version__).run()