From 39786d4da7127bb1a0898da8c63ad77ec0adf8a3 Mon Sep 17 00:00:00 2001 From: Christophe Labouisse Date: Mon, 14 Sep 2015 15:02:15 +0200 Subject: [PATCH] Add new --pull option in build. Signed-off-by: Christophe Labouisse --- compose/cli/main.py | 4 ++- compose/project.py | 4 +-- compose/service.py | 4 +-- docs/reference/build.md | 1 + tests/integration/cli_test.py | 46 +++++++++++++++++++++++++++++++---- 5 files changed, 49 insertions(+), 10 deletions(-) diff --git a/compose/cli/main.py b/compose/cli/main.py index 61461ae7b..9b03ea676 100644 --- a/compose/cli/main.py +++ b/compose/cli/main.py @@ -153,9 +153,11 @@ class TopLevelCommand(Command): Options: --no-cache Do not use cache when building the image. + --pull Always attempt to pull a newer version of the image. """ no_cache = bool(options.get('--no-cache', False)) - project.build(service_names=options['SERVICE'], no_cache=no_cache) + pull = bool(options.get('--pull', False)) + project.build(service_names=options['SERVICE'], no_cache=no_cache, pull=pull) def help(self, project, options): """ diff --git a/compose/project.py b/compose/project.py index 9a6e98e01..f34cc0c34 100644 --- a/compose/project.py +++ b/compose/project.py @@ -257,10 +257,10 @@ class Project(object): for service in self.get_services(service_names): service.restart(**options) - def build(self, service_names=None, no_cache=False): + def build(self, service_names=None, no_cache=False, pull=False): for service in self.get_services(service_names): if service.can_be_built(): - service.build(no_cache) + service.build(no_cache, pull) else: log.info('%s uses an image, skipping' % service.name) diff --git a/compose/service.py b/compose/service.py index 7406ad80d..d74c310b9 100644 --- a/compose/service.py +++ b/compose/service.py @@ -700,7 +700,7 @@ class Service(object): security_opt=security_opt ) - def build(self, no_cache=False): + def build(self, no_cache=False, pull=False): log.info('Building %s' % self.name) path = self.options['build'] @@ -714,7 +714,7 @@ class Service(object): tag=self.image_name, stream=True, rm=True, - pull=False, + pull=pull, nocache=no_cache, dockerfile=self.options.get('dockerfile', None), ) diff --git a/docs/reference/build.md b/docs/reference/build.md index 77d87def4..c427199fe 100644 --- a/docs/reference/build.md +++ b/docs/reference/build.md @@ -16,6 +16,7 @@ Usage: build [options] [SERVICE...] Options: --no-cache Do not use cache when building the image. +--pull Always attempt to pull a newer version of the image. ``` Services are built once and then tagged as `project_service`, e.g., diff --git a/tests/integration/cli_test.py b/tests/integration/cli_test.py index 4a80d3369..9dadd0368 100644 --- a/tests/integration/cli_test.py +++ b/tests/integration/cli_test.py @@ -97,6 +97,19 @@ class CLITestCase(DockerClientTestCase): 'Pulling digest (busybox@' 'sha256:38a203e1986cf79639cfb9b2e1d6e773de84002feea2d4eb006b52004ee8502d)...') + @mock.patch('sys.stdout', new_callable=StringIO) + def test_build_plain(self, mock_stdout): + self.command.base_dir = 'tests/fixtures/simple-dockerfile' + self.command.dispatch(['build', 'simple'], None) + + mock_stdout.truncate(0) + cache_indicator = 'Using cache' + pull_indicator = 'Status: Image is up to date for busybox:latest' + self.command.dispatch(['build', 'simple'], None) + output = mock_stdout.getvalue() + self.assertIn(cache_indicator, output) + self.assertNotIn(pull_indicator, output) + @mock.patch('sys.stdout', new_callable=StringIO) def test_build_no_cache(self, mock_stdout): self.command.base_dir = 'tests/fixtures/simple-dockerfile' @@ -104,14 +117,37 @@ class CLITestCase(DockerClientTestCase): mock_stdout.truncate(0) cache_indicator = 'Using cache' - self.command.dispatch(['build', 'simple'], None) - output = mock_stdout.getvalue() - self.assertIn(cache_indicator, output) - - mock_stdout.truncate(0) + pull_indicator = 'Status: Image is up to date for busybox:latest' self.command.dispatch(['build', '--no-cache', 'simple'], None) output = mock_stdout.getvalue() self.assertNotIn(cache_indicator, output) + self.assertNotIn(pull_indicator, output) + + @mock.patch('sys.stdout', new_callable=StringIO) + def test_build_pull(self, mock_stdout): + self.command.base_dir = 'tests/fixtures/simple-dockerfile' + self.command.dispatch(['build', 'simple'], None) + + mock_stdout.truncate(0) + cache_indicator = 'Using cache' + pull_indicator = 'Status: Image is up to date for busybox:latest' + self.command.dispatch(['build', '--pull', 'simple'], None) + output = mock_stdout.getvalue() + self.assertIn(cache_indicator, output) + self.assertIn(pull_indicator, output) + + @mock.patch('sys.stdout', new_callable=StringIO) + def test_build_no_cache_pull(self, mock_stdout): + self.command.base_dir = 'tests/fixtures/simple-dockerfile' + self.command.dispatch(['build', 'simple'], None) + + mock_stdout.truncate(0) + cache_indicator = 'Using cache' + pull_indicator = 'Status: Image is up to date for busybox:latest' + self.command.dispatch(['build', '--no-cache', '--pull', 'simple'], None) + output = mock_stdout.getvalue() + self.assertNotIn(cache_indicator, output) + self.assertIn(pull_indicator, output) def test_up_detached(self): self.command.dispatch(['up', '-d'], None)