Add support for build arguments

Allows 'build' configuration option to be specified as an
object and adds support for build args.

Signed-off-by: Garrett Heel <garrettheel@gmail.com>
This commit is contained in:
Garrett Heel 2015-12-11 15:19:51 -08:00 committed by Joffrey F
commit 9cfa71ceee
9 changed files with 297 additions and 49 deletions

View file

@ -12,6 +12,7 @@ import py
import pytest
from compose.config import config
from compose.config.config import resolve_build_args
from compose.config.config import resolve_environment
from compose.config.errors import ConfigurationError
from compose.config.types import VolumeSpec
@ -284,7 +285,7 @@ class ConfigTest(unittest.TestCase):
expected = [
{
'name': 'web',
'build': os.path.abspath('/'),
'build': {'context': os.path.abspath('/')},
'volumes': [VolumeSpec.parse('/home/user/project:/code')],
'links': ['db'],
},
@ -414,6 +415,59 @@ class ConfigTest(unittest.TestCase):
assert services[1]['name'] == 'db'
assert services[2]['name'] == 'web'
def test_config_build_configuration(self):
service = config.load(
build_config_details(
{'web': {
'build': '.',
'dockerfile': 'Dockerfile-alt'
}},
'tests/fixtures/extends',
'filename.yml'
)
).services
self.assertTrue('context' in service[0]['build'])
self.assertEqual(service[0]['build']['dockerfile'], 'Dockerfile-alt')
def test_config_build_configuration_v2(self):
service = config.load(
build_config_details(
{
'version': 2,
'services': {
'web': {
'build': '.',
'dockerfile': 'Dockerfile-alt'
}
}
},
'tests/fixtures/extends',
'filename.yml'
)
).services
self.assertTrue('context' in service[0]['build'])
self.assertEqual(service[0]['build']['dockerfile'], 'Dockerfile-alt')
service = config.load(
build_config_details(
{
'version': 2,
'services': {
'web': {
'build': {
'context': '.',
'dockerfile': 'Dockerfile-alt'
}
}
}
},
'tests/fixtures/extends',
'filename.yml'
)
).services
self.assertTrue('context' in service[0]['build'])
self.assertEqual(service[0]['build']['dockerfile'], 'Dockerfile-alt')
def test_load_with_multiple_files_v2(self):
base_file = config.ConfigFile(
'base.yaml',
@ -445,7 +499,7 @@ class ConfigTest(unittest.TestCase):
expected = [
{
'name': 'web',
'build': os.path.abspath('/'),
'build': {'context': os.path.abspath('/')},
'image': 'example/web',
'volumes': [VolumeSpec.parse('/home/user/project:/code')],
},
@ -1157,7 +1211,7 @@ class BuildOrImageMergeTest(unittest.TestCase):
self.assertEqual(
config.merge_service_dicts({'image': 'redis'}, {'build': '.'}, V1),
{'build': '.'},
{'build': '.'}
)
@ -1388,6 +1442,24 @@ class EnvTest(unittest.TestCase):
},
)
@mock.patch.dict(os.environ)
def test_resolve_build_args(self):
os.environ['env_arg'] = 'value2'
build = {
'context': '.',
'args': {
'arg1': 'value1',
'empty_arg': '',
'env_arg': None,
'no_env': None
}
}
self.assertEqual(
resolve_build_args(build),
{'arg1': 'value1', 'empty_arg': '', 'env_arg': 'value2', 'no_env': ''},
)
@pytest.mark.xfail(IS_WINDOWS_PLATFORM, reason='paths use slash')
@mock.patch.dict(os.environ)
def test_resolve_path(self):
@ -1873,7 +1945,7 @@ class BuildPathTest(unittest.TestCase):
def test_from_file(self):
service_dict = load_from_filename('tests/fixtures/build-path/docker-compose.yml')
self.assertEquals(service_dict, [{'name': 'foo', 'build': self.abs_context_path}])
self.assertEquals(service_dict, [{'name': 'foo', 'build': {'context': self.abs_context_path}}])
def test_valid_url_in_build_path(self):
valid_urls = [
@ -1888,7 +1960,7 @@ class BuildPathTest(unittest.TestCase):
service_dict = config.load(build_config_details({
'validurl': {'build': valid_url},
}, '.', None)).services
assert service_dict[0]['build'] == valid_url
assert service_dict[0]['build'] == {'context': valid_url}
def test_invalid_url_in_build_path(self):
invalid_urls = [

View file

@ -355,7 +355,7 @@ class ServiceTest(unittest.TestCase):
self.assertEqual(parse_repository_tag("url:5000/repo@sha256:digest"), ("url:5000/repo", "sha256:digest", "@"))
def test_create_container_with_build(self):
service = Service('foo', client=self.mock_client, build='.')
service = Service('foo', client=self.mock_client, build={'context': '.'})
self.mock_client.inspect_image.side_effect = [
NoSuchImageError,
{'Id': 'abc123'},
@ -374,17 +374,18 @@ class ServiceTest(unittest.TestCase):
forcerm=False,
nocache=False,
rm=True,
buildargs=None,
)
def test_create_container_no_build(self):
service = Service('foo', client=self.mock_client, build='.')
service = Service('foo', client=self.mock_client, build={'context': '.'})
self.mock_client.inspect_image.return_value = {'Id': 'abc123'}
service.create_container(do_build=False)
self.assertFalse(self.mock_client.build.called)
def test_create_container_no_build_but_needs_build(self):
service = Service('foo', client=self.mock_client, build='.')
service = Service('foo', client=self.mock_client, build={'context': '.'})
self.mock_client.inspect_image.side_effect = NoSuchImageError
with self.assertRaises(NeedsBuildError):
service.create_container(do_build=False)
@ -394,7 +395,7 @@ class ServiceTest(unittest.TestCase):
b'{"stream": "Successfully built 12345"}',
]
service = Service('foo', client=self.mock_client, build='.')
service = Service('foo', client=self.mock_client, build={'context': '.'})
service.build()
self.assertEqual(self.mock_client.build.call_count, 1)