diff --git a/ognibuild/buildsystem.py b/ognibuild/buildsystem.py index 31e8b41..e963db3 100644 --- a/ognibuild/buildsystem.py +++ b/ognibuild/buildsystem.py @@ -18,10 +18,11 @@ import logging +import re import os from . import shebang_binary -from .apt import AptManager +from .apt import AptManager, UnidentifiedError from .fix_build import run_with_build_fixer @@ -160,6 +161,148 @@ class PyProject(BuildSystem): raise AssertionError('no supported section in pyproject.toml') +class SetupCfg(BuildSystem): + + def dist(self): + apt = AptManager(self.session) + apt.install(['python3-pep517', 'python3-pip']) + self.session.check_call(['python3', '-m', 'pep517.build', '-s', '.']) + + +class NpmPackage(BuildSystem): + + def dist(self): + apt = AptManager(self.session) + apt.install(['npm']) + run_with_build_fixer(self.session, ['npm', 'pack']) + + +class Waf(BuildSystem): + + def dist(self): + apt = AptManager(self.session) + apt.install(['python3']) + run_with_build_fixer(self.session, ['./waf', 'dist']) + + +class Gem(BuildSystem): + + def dist(self): + apt = AptManager(self.session) + apt.install(['gem2deb']) + gemfiles = [name for name in os.listdir('.') if name.endswith('.gem')] + if len(gemfiles) > 1: + logging.warning('More than one gemfile. Trying the first?') + run_with_build_fixer(self.session, ['gem2tgz', gemfiles[0]]) + + +class DistInkt(BuildSystem): + + def dist(self): + apt = AptManager(self.session) + apt.install(['libdist-inkt-perl']) + with open('dist.ini', 'rb') as f: + for line in f: + if not line.startswith(b';;'): + continue + try: + (key, value) = line[2:].split(b'=', 1) + except ValueError: + continue + if (key.strip() == b'class' and + value.strip().startswith(b"'Dist::Inkt")): + logging.info( + 'Found Dist::Inkt section in dist.ini, ' + 'assuming distinkt.') + # TODO(jelmer): install via apt if possible + self.session.check_call( + ['cpan', 'install', value.decode().strip("'")], + user='root') + run_with_build_fixer(self.session, ['distinkt-dist']) + return + # Default to invoking Dist::Zilla + logging.info('Found dist.ini, assuming dist-zilla.') + apt.install(['libdist-zilla-perl']) + run_with_build_fixer(self.session, ['dzil', 'build', '--in', '..']) + + +class Make(BuildSystem): + + def setup(self): + apt = AptManager(self.session) + if os.path.exists('Makefile.PL') and not os.path.exists('Makefile'): + apt.install(['perl']) + run_with_build_fixer(self.session, ['perl', 'Makefile.PL']) + + if not os.path.exists('Makefile') and not os.path.exists('configure'): + if os.path.exists('autogen.sh'): + if shebang_binary('autogen.sh') is None: + run_with_build_fixer( + self.session, ['/bin/sh', './autogen.sh']) + try: + run_with_build_fixer( + self.session, ['./autogen.sh']) + except UnidentifiedError as e: + if ("Gnulib not yet bootstrapped; " + "run ./bootstrap instead.\n" in e.lines): + run_with_build_fixer(self.session, ["./bootstrap"]) + run_with_build_fixer(self.session, ['./autogen.sh']) + else: + raise + + elif (os.path.exists('configure.ac') or + os.path.exists('configure.in')): + apt.install([ + 'autoconf', 'automake', 'gettext', 'libtool', + 'gnu-standards']) + run_with_build_fixer(self.session, ['autoreconf', '-i']) + + if not os.path.exists('Makefile') and os.path.exists('configure'): + self.session.check_call(['./configure']) + + def dist(self): + self.setup() + apt = AptManager(self.session) + apt.install(['make']) + try: + run_with_build_fixer(self.session, ['make', 'dist']) + except UnidentifiedError as e: + if ("make: *** No rule to make target 'dist'. Stop.\n" + in e.lines): + pass + elif ("make[1]: *** No rule to make target 'dist'. Stop.\n" + in e.lines): + pass + elif ("Reconfigure the source tree " + "(via './config' or 'perl Configure'), please.\n" + ) in e.lines: + run_with_build_fixer(self.session, ['./config']) + run_with_build_fixer(self.session, ['make', 'dist']) + elif ( + "Please try running 'make manifest' and then run " + "'make dist' again.\n" in e.lines): + run_with_build_fixer(self.session, ['make', 'manifest']) + run_with_build_fixer(self.session, ['make', 'dist']) + elif "Please run ./configure first\n" in e.lines: + run_with_build_fixer(self.session, ['./configure']) + run_with_build_fixer(self.session, ['make', 'dist']) + elif any([re.match( + r'Makefile:[0-9]+: \*\*\* Missing \'Make.inc\' ' + r'Run \'./configure \[options\]\' and retry. Stop.\n', + line) for line in e.lines]): + run_with_build_fixer(self.session, ['./configure']) + run_with_build_fixer(self.session, ['make', 'dist']) + elif any([re.match( + r'Problem opening MANIFEST: No such file or directory ' + r'at .* line [0-9]+\.', line) for line in e.lines]): + run_with_build_fixer(self.session, ['make', 'manifest']) + run_with_build_fixer(self.session, ['make', 'dist']) + else: + raise + else: + return + + def detect_buildsystems(session): """Detect build systems.""" if os.path.exists('package.xml'): @@ -173,3 +316,27 @@ def detect_buildsystems(session): if os.path.exists('pyproject.toml'): logging.info('Found pyproject.toml, assuming python project.') yield PyProject(session) + + if os.path.exists('setup.cfg'): + logging.info('Found setup.cfg, assuming python project.') + yield SetupCfg(session) + + if os.path.exists('package.json'): + logging.info('Found package.json, assuming node package.') + yield NpmPackage(session) + + if os.path.exists('waf'): + logging.info('Found waf, assuming waf package.') + yield Waf(session) + + gemfiles = [name for name in os.listdir('.') if name.endswith('.gem')] + if gemfiles: + yield Gem(session) + + if os.path.exists('dist.ini') and not os.path.exists('Makefile.PL'): + yield DistInkt(session) + + if any([os.path.exists(p) for p in [ + 'Makefile', 'Makefile.PL', 'autogen.sh', 'configure.ac', + 'configure.in']]): + yield Make(session) diff --git a/ognibuild/dist.py b/ognibuild/dist.py index dcab9b1..247f5c1 100644 --- a/ognibuild/dist.py +++ b/ognibuild/dist.py @@ -82,122 +82,6 @@ def run_dist(session): buildsystem.dist() return - if os.path.exists('setup.cfg'): - logging.info('Found setup.cfg, assuming python project.') - apt.install(['python3-pep517', 'python3-pip']) - session.check_call(['python3', '-m', 'pep517.build', '-s', '.']) - return - - if os.path.exists('dist.ini') and not os.path.exists('Makefile.PL'): - apt.install(['libdist-inkt-perl']) - with open('dist.ini', 'rb') as f: - for line in f: - if not line.startswith(b';;'): - continue - try: - (key, value) = line[2:].split(b'=', 1) - except ValueError: - continue - if (key.strip() == b'class' and - value.strip().startswith(b"'Dist::Inkt")): - logging.info( - 'Found Dist::Inkt section in dist.ini, ' - 'assuming distinkt.') - # TODO(jelmer): install via apt if possible - session.check_call( - ['cpan', 'install', value.decode().strip("'")], - user='root') - run_with_build_fixer(session, ['distinkt-dist']) - return - # Default to invoking Dist::Zilla - logging.info('Found dist.ini, assuming dist-zilla.') - apt.install(['libdist-zilla-perl']) - run_with_build_fixer(session, ['dzil', 'build', '--in', '..']) - return - - if os.path.exists('package.json'): - apt.install(['npm']) - run_with_build_fixer(session, ['npm', 'pack']) - return - - gemfiles = [name for name in os.listdir('.') if name.endswith('.gem')] - if gemfiles: - apt.install(['gem2deb']) - if len(gemfiles) > 1: - logging.warning('More than one gemfile. Trying the first?') - run_with_build_fixer(session, ['gem2tgz', gemfiles[0]]) - return - - if os.path.exists('waf'): - apt.install(['python3']) - run_with_build_fixer(session, ['./waf', 'dist']) - return - - if os.path.exists('Makefile.PL') and not os.path.exists('Makefile'): - apt.install(['perl']) - run_with_build_fixer(session, ['perl', 'Makefile.PL']) - - if not os.path.exists('Makefile') and not os.path.exists('configure'): - if os.path.exists('autogen.sh'): - if shebang_binary('autogen.sh') is None: - run_with_build_fixer(session, ['/bin/sh', './autogen.sh']) - try: - run_with_build_fixer(session, ['./autogen.sh']) - except UnidentifiedError as e: - if ("Gnulib not yet bootstrapped; " - "run ./bootstrap instead.\n" in e.lines): - run_with_build_fixer(session, ["./bootstrap"]) - run_with_build_fixer(session, ['./autogen.sh']) - else: - raise - - elif os.path.exists('configure.ac') or os.path.exists('configure.in'): - apt.install([ - 'autoconf', 'automake', 'gettext', 'libtool', 'gnu-standards']) - run_with_build_fixer(session, ['autoreconf', '-i']) - - if not os.path.exists('Makefile') and os.path.exists('configure'): - session.check_call(['./configure']) - - if os.path.exists('Makefile'): - apt.install(['make']) - try: - run_with_build_fixer(session, ['make', 'dist']) - except UnidentifiedError as e: - if "make: *** No rule to make target 'dist'. Stop.\n" in e.lines: - pass - elif ("make[1]: *** No rule to make target 'dist'. Stop.\n" - in e.lines): - pass - elif ("Reconfigure the source tree " - "(via './config' or 'perl Configure'), please.\n" - ) in e.lines: - run_with_build_fixer(session, ['./config']) - run_with_build_fixer(session, ['make', 'dist']) - elif ( - "Please try running 'make manifest' and then run " - "'make dist' again.\n" in e.lines): - run_with_build_fixer(session, ['make', 'manifest']) - run_with_build_fixer(session, ['make', 'dist']) - elif "Please run ./configure first\n" in e.lines: - run_with_build_fixer(session, ['./configure']) - run_with_build_fixer(session, ['make', 'dist']) - elif any([re.match( - r'Makefile:[0-9]+: \*\*\* Missing \'Make.inc\' ' - r'Run \'./configure \[options\]\' and retry. Stop.\n', - line) for line in e.lines]): - run_with_build_fixer(session, ['./configure']) - run_with_build_fixer(session, ['make', 'dist']) - elif any([re.match( - r'Problem opening MANIFEST: No such file or directory ' - r'at .* line [0-9]+\.', line) for line in e.lines]): - run_with_build_fixer(session, ['make', 'manifest']) - run_with_build_fixer(session, ['make', 'dist']) - else: - raise - else: - return - raise NoBuildToolsFound()