diff --git a/builder/app.py b/builder/app.py index d2f77bdb..2a28bbdf 100644 --- a/builder/app.py +++ b/builder/app.py @@ -1,3 +1,4 @@ +import sys import json import os import time @@ -33,6 +34,12 @@ class Builder(Application): config=True ) + source_ref = Unicode( + 'master', + allow_none=True, + config=True + ) + output_image_spec = Unicode( None, allow_none=True, @@ -52,6 +59,7 @@ class Builder(Application): aliases = Dict({ 'source': 'Builder.source_url', + 'ref': 'Builder.source_ref', 'output': 'Builder.output_image_spec', 'f': 'Builder.config_file', 'n': 'Builder.build_name' @@ -59,8 +67,19 @@ class Builder(Application): def fetch(self, url, ref, output_path): - for line in execute_cmd(['git', 'clone', '--depth', '1', url, output_path]): - self.log.info(line, extra=dict(phase='fetching')) + try: + for line in execute_cmd(['git', 'clone', url, output_path]): + self.log.info(line, extra=dict(phase='fetching')) + except subprocess.CalledProcessError: + self.log.error('Failed to clone repository!', extra=dict(phase='failed')) + sys.exit(1) + + try: + for line in execute_cmd(['git', '--git-dir', os.path.join(output_path, '.git'), 'checkout', ref]): + self.log.info(line, extra=dict(phase='fetching')) + except subprocess.CalledProcessError: + self.log.error('Failed to check out ref %s', ref, extra=dict(phase='failed')) + sys.exit(1) def initialize(self, *args, **kwargs): super().initialize(*args, **kwargs) @@ -104,7 +123,8 @@ class Builder(Application): bp.build(output_path, self.output_image_spec) break else: - raise Exception("No compatible builders found") + self.log.error('Could not figure out how to build this repository! Tell us?', extra=dict(phase='failed')) + sys.exit(1) # Build a progress setup for each layer, and only emit per-layer info every 1.5s layers = {} diff --git a/builder/detectors.py b/builder/detectors.py index b70a3023..7239a437 100644 --- a/builder/detectors.py +++ b/builder/detectors.py @@ -1,4 +1,5 @@ import os +import sys import subprocess import docker @@ -84,5 +85,9 @@ class PythonBuildPack(BuildPack): self.runtime_builder_map[self.runtime], output_image_spec ] - for line in execute_cmd(cmd): - self.log.info(line, extra=dict(phase='building', builder=self.name)) + try: + for line in execute_cmd(cmd): + self.log.info(line, extra=dict(phase='building', builder=self.name)) + except subprocess.CalledProcessError: + self.log.error('Failed to build image!', extra=dict(phase='failed')) + sys.exit(1) diff --git a/builder/utils.py b/builder/utils.py index 947e6c78..d1486b3d 100644 --- a/builder/utils.py +++ b/builder/utils.py @@ -4,6 +4,12 @@ def execute_cmd(cmd): """ Call given command, yielding output line by line """ - with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) as proc: + proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) + + try: for line in iter(proc.stdout.readline, ''): yield line.rstrip() + finally: + ret = proc.wait() + if ret != 0: + raise subprocess.CalledProcessError(ret, cmd)