mirror of https://github.com/docker/compose.git
Fix project_dir to take first file in account
The order of precedence is: - '--project-directory' option - first file directory in '--file' option - current directory Signed-off-by: Ulysses Souza <ulyssessouza@gmail.com>
This commit is contained in:
parent
6f3f696bd1
commit
e0edc908b5
|
@ -35,7 +35,7 @@ SILENT_COMMANDS = {
|
||||||
|
|
||||||
def project_from_options(project_dir, options, additional_options=None):
|
def project_from_options(project_dir, options, additional_options=None):
|
||||||
additional_options = additional_options or {}
|
additional_options = additional_options or {}
|
||||||
override_dir = options.get('--project-directory')
|
override_dir = get_project_dir(options)
|
||||||
environment_file = options.get('--env-file')
|
environment_file = options.get('--env-file')
|
||||||
environment = Environment.from_env_file(override_dir or project_dir, environment_file)
|
environment = Environment.from_env_file(override_dir or project_dir, environment_file)
|
||||||
environment.silent = options.get('COMMAND', None) in SILENT_COMMANDS
|
environment.silent = options.get('COMMAND', None) in SILENT_COMMANDS
|
||||||
|
@ -59,7 +59,7 @@ def project_from_options(project_dir, options, additional_options=None):
|
||||||
|
|
||||||
return get_project(
|
return get_project(
|
||||||
project_dir,
|
project_dir,
|
||||||
get_config_path_from_options(project_dir, options, environment),
|
get_config_path_from_options(options, environment),
|
||||||
project_name=options.get('--project-name'),
|
project_name=options.get('--project-name'),
|
||||||
verbose=options.get('--verbose'),
|
verbose=options.get('--verbose'),
|
||||||
context=context,
|
context=context,
|
||||||
|
@ -87,21 +87,29 @@ def set_parallel_limit(environment):
|
||||||
parallel.GlobalLimit.set_global_limit(parallel_limit)
|
parallel.GlobalLimit.set_global_limit(parallel_limit)
|
||||||
|
|
||||||
|
|
||||||
|
def get_project_dir(options):
|
||||||
|
override_dir = None
|
||||||
|
files = get_config_path_from_options(options, os.environ)
|
||||||
|
if files:
|
||||||
|
if files[0] == '-':
|
||||||
|
return '.'
|
||||||
|
override_dir = os.path.dirname(files[0])
|
||||||
|
return options.get('--project-directory') or override_dir
|
||||||
|
|
||||||
|
|
||||||
def get_config_from_options(base_dir, options, additional_options=None):
|
def get_config_from_options(base_dir, options, additional_options=None):
|
||||||
additional_options = additional_options or {}
|
additional_options = additional_options or {}
|
||||||
override_dir = options.get('--project-directory')
|
override_dir = get_project_dir(options)
|
||||||
environment_file = options.get('--env-file')
|
environment_file = options.get('--env-file')
|
||||||
environment = Environment.from_env_file(override_dir or base_dir, environment_file)
|
environment = Environment.from_env_file(override_dir or base_dir, environment_file)
|
||||||
config_path = get_config_path_from_options(
|
config_path = get_config_path_from_options(options, environment)
|
||||||
base_dir, options, environment
|
|
||||||
)
|
|
||||||
return config.load(
|
return config.load(
|
||||||
config.find(base_dir, config_path, environment, override_dir),
|
config.find(base_dir, config_path, environment, override_dir),
|
||||||
not additional_options.get('--no-interpolate')
|
not additional_options.get('--no-interpolate')
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_config_path_from_options(base_dir, options, environment):
|
def get_config_path_from_options(options, environment):
|
||||||
def unicode_paths(paths):
|
def unicode_paths(paths):
|
||||||
return [p.decode('utf-8') if isinstance(p, bytes) else p for p in paths]
|
return [p.decode('utf-8') if isinstance(p, bytes) else p for p in paths]
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,7 @@ from ..service import ImageType
|
||||||
from ..service import NeedsBuildError
|
from ..service import NeedsBuildError
|
||||||
from ..service import OperationFailedError
|
from ..service import OperationFailedError
|
||||||
from .command import get_config_from_options
|
from .command import get_config_from_options
|
||||||
|
from .command import get_project_dir
|
||||||
from .command import project_from_options
|
from .command import project_from_options
|
||||||
from .docopt_command import DocoptDispatcher
|
from .docopt_command import DocoptDispatcher
|
||||||
from .docopt_command import get_handler
|
from .docopt_command import get_handler
|
||||||
|
@ -245,7 +246,7 @@ class TopLevelCommand:
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def project_dir(self):
|
def project_dir(self):
|
||||||
return self.toplevel_options.get('--project-directory') or '.'
|
return get_project_dir(self.toplevel_options)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def toplevel_environment(self):
|
def toplevel_environment(self):
|
||||||
|
@ -431,6 +432,7 @@ class TopLevelCommand:
|
||||||
Options:
|
Options:
|
||||||
--json Output events as a stream of json objects
|
--json Output events as a stream of json objects
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def format_event(event):
|
def format_event(event):
|
||||||
attributes = ["%s=%s" % item for item in event['attributes'].items()]
|
attributes = ["%s=%s" % item for item in event['attributes'].items()]
|
||||||
return ("{time} {type} {action} {id} ({attrs})").format(
|
return ("{time} {type} {action} {id} ({attrs})").format(
|
||||||
|
|
|
@ -14,49 +14,41 @@ class TestGetConfigPathFromOptions:
|
||||||
paths = ['one.yml', 'two.yml']
|
paths = ['one.yml', 'two.yml']
|
||||||
opts = {'--file': paths}
|
opts = {'--file': paths}
|
||||||
environment = Environment.from_env_file('.')
|
environment = Environment.from_env_file('.')
|
||||||
assert get_config_path_from_options('.', opts, environment) == paths
|
assert get_config_path_from_options(opts, environment) == paths
|
||||||
|
|
||||||
def test_single_path_from_env(self):
|
def test_single_path_from_env(self):
|
||||||
with mock.patch.dict(os.environ):
|
with mock.patch.dict(os.environ):
|
||||||
os.environ['COMPOSE_FILE'] = 'one.yml'
|
os.environ['COMPOSE_FILE'] = 'one.yml'
|
||||||
environment = Environment.from_env_file('.')
|
environment = Environment.from_env_file('.')
|
||||||
assert get_config_path_from_options('.', {}, environment) == ['one.yml']
|
assert get_config_path_from_options({}, environment) == ['one.yml']
|
||||||
|
|
||||||
@pytest.mark.skipif(IS_WINDOWS_PLATFORM, reason='posix separator')
|
@pytest.mark.skipif(IS_WINDOWS_PLATFORM, reason='posix separator')
|
||||||
def test_multiple_path_from_env(self):
|
def test_multiple_path_from_env(self):
|
||||||
with mock.patch.dict(os.environ):
|
with mock.patch.dict(os.environ):
|
||||||
os.environ['COMPOSE_FILE'] = 'one.yml:two.yml'
|
os.environ['COMPOSE_FILE'] = 'one.yml:two.yml'
|
||||||
environment = Environment.from_env_file('.')
|
environment = Environment.from_env_file('.')
|
||||||
assert get_config_path_from_options(
|
assert get_config_path_from_options({}, environment) == ['one.yml', 'two.yml']
|
||||||
'.', {}, environment
|
|
||||||
) == ['one.yml', 'two.yml']
|
|
||||||
|
|
||||||
@pytest.mark.skipif(not IS_WINDOWS_PLATFORM, reason='windows separator')
|
@pytest.mark.skipif(not IS_WINDOWS_PLATFORM, reason='windows separator')
|
||||||
def test_multiple_path_from_env_windows(self):
|
def test_multiple_path_from_env_windows(self):
|
||||||
with mock.patch.dict(os.environ):
|
with mock.patch.dict(os.environ):
|
||||||
os.environ['COMPOSE_FILE'] = 'one.yml;two.yml'
|
os.environ['COMPOSE_FILE'] = 'one.yml;two.yml'
|
||||||
environment = Environment.from_env_file('.')
|
environment = Environment.from_env_file('.')
|
||||||
assert get_config_path_from_options(
|
assert get_config_path_from_options({}, environment) == ['one.yml', 'two.yml']
|
||||||
'.', {}, environment
|
|
||||||
) == ['one.yml', 'two.yml']
|
|
||||||
|
|
||||||
def test_multiple_path_from_env_custom_separator(self):
|
def test_multiple_path_from_env_custom_separator(self):
|
||||||
with mock.patch.dict(os.environ):
|
with mock.patch.dict(os.environ):
|
||||||
os.environ['COMPOSE_PATH_SEPARATOR'] = '^'
|
os.environ['COMPOSE_PATH_SEPARATOR'] = '^'
|
||||||
os.environ['COMPOSE_FILE'] = 'c:\\one.yml^.\\semi;colon.yml'
|
os.environ['COMPOSE_FILE'] = 'c:\\one.yml^.\\semi;colon.yml'
|
||||||
environment = Environment.from_env_file('.')
|
environment = Environment.from_env_file('.')
|
||||||
assert get_config_path_from_options(
|
assert get_config_path_from_options({}, environment) == ['c:\\one.yml', '.\\semi;colon.yml']
|
||||||
'.', {}, environment
|
|
||||||
) == ['c:\\one.yml', '.\\semi;colon.yml']
|
|
||||||
|
|
||||||
def test_no_path(self):
|
def test_no_path(self):
|
||||||
environment = Environment.from_env_file('.')
|
environment = Environment.from_env_file('.')
|
||||||
assert not get_config_path_from_options('.', {}, environment)
|
assert not get_config_path_from_options({}, environment)
|
||||||
|
|
||||||
def test_unicode_path_from_options(self):
|
def test_unicode_path_from_options(self):
|
||||||
paths = [b'\xe5\xb0\xb1\xe5\x90\x83\xe9\xa5\xad/docker-compose.yml']
|
paths = [b'\xe5\xb0\xb1\xe5\x90\x83\xe9\xa5\xad/docker-compose.yml']
|
||||||
opts = {'--file': paths}
|
opts = {'--file': paths}
|
||||||
environment = Environment.from_env_file('.')
|
environment = Environment.from_env_file('.')
|
||||||
assert get_config_path_from_options(
|
assert get_config_path_from_options(opts, environment) == ['就吃饭/docker-compose.yml']
|
||||||
'.', opts, environment
|
|
||||||
) == ['就吃饭/docker-compose.yml']
|
|
||||||
|
|
Loading…
Reference in New Issue