diff --git a/compose/cli/main.py b/compose/cli/main.py index 6391bd3ea..477b57b52 100644 --- a/compose/cli/main.py +++ b/compose/cli/main.py @@ -247,6 +247,11 @@ class TopLevelCommand(object): def project_dir(self): return self.toplevel_options.get('--project-directory') or '.' + @property + def toplevel_environment(self): + environment_file = self.toplevel_options.get('--env-file') + return Environment.from_env_file(self.project_dir, environment_file) + def build(self, options): """ Build or rebuild services. @@ -276,9 +281,7 @@ class TopLevelCommand(object): '--build-arg is only supported when services are specified for API version < 1.25.' ' Please use a Compose file version > 2.2 or specify which services to build.' ) - environment_file = options.get('--env-file') - environment = Environment.from_env_file(self.project_dir, environment_file) - build_args = resolve_build_args(build_args, environment) + build_args = resolve_build_args(build_args, self.toplevel_environment) self.project.build( service_names=options['SERVICE'], @@ -429,11 +432,8 @@ class TopLevelCommand(object): Compose file -t, --timeout TIMEOUT Specify a shutdown timeout in seconds. (default: 10) - --env-file PATH Specify an alternate environment file """ - environment_file = options.get('--env-file') - environment = Environment.from_env_file(self.project_dir, environment_file) - ignore_orphans = environment.get_boolean('COMPOSE_IGNORE_ORPHANS') + ignore_orphans = self.toplevel_environment.get_boolean('COMPOSE_IGNORE_ORPHANS') if ignore_orphans and options['--remove-orphans']: raise UserError("COMPOSE_IGNORE_ORPHANS and --remove-orphans cannot be combined.") @@ -489,11 +489,8 @@ class TopLevelCommand(object): -e, --env KEY=VAL Set environment variables (can be used multiple times, not supported in API < 1.25) -w, --workdir DIR Path to workdir directory for this command. - --env-file PATH Specify an alternate environment file """ - environment_file = options.get('--env-file') - environment = Environment.from_env_file(self.project_dir, environment_file) - use_cli = not environment.get_boolean('COMPOSE_INTERACTIVE_NO_CLI') + use_cli = not self.toplevel_environment.get_boolean('COMPOSE_INTERACTIVE_NO_CLI') index = int(options.get('--index')) service = self.project.get_service(options['SERVICE']) detach = options.get('--detach') @@ -516,7 +513,7 @@ class TopLevelCommand(object): if IS_WINDOWS_PLATFORM or use_cli and not detach: sys.exit(call_docker( build_exec_command(options, container.id, command), - self.toplevel_options, environment) + self.toplevel_options, self.toplevel_environment) ) create_exec_options = { @@ -890,7 +887,7 @@ class TopLevelCommand(object): container_options = build_one_off_container_options(options, detach, command) run_one_off_container( container_options, self.project, service, options, - self.toplevel_options, self.project_dir + self.toplevel_options, self.toplevel_environment ) def scale(self, options): @@ -1051,7 +1048,6 @@ class TopLevelCommand(object): container. Implies --abort-on-container-exit. --scale SERVICE=NUM Scale SERVICE to NUM instances. Overrides the `scale` setting in the Compose file if present. - --env-file PATH Specify an alternate environment file """ start_deps = not options['--no-deps'] always_recreate_deps = options['--always-recreate-deps'] @@ -1066,9 +1062,7 @@ class TopLevelCommand(object): if detached and (cascade_stop or exit_value_from): raise UserError("--abort-on-container-exit and -d cannot be combined.") - environment_file = options.get('--env-file') - environment = Environment.from_env_file(self.project_dir, environment_file) - ignore_orphans = environment.get_boolean('COMPOSE_IGNORE_ORPHANS') + ignore_orphans = self.toplevel_environment.get_boolean('COMPOSE_IGNORE_ORPHANS') if ignore_orphans and remove_orphans: raise UserError("COMPOSE_IGNORE_ORPHANS and --remove-orphans cannot be combined.") @@ -1331,7 +1325,7 @@ def build_one_off_container_options(options, detach, command): def run_one_off_container(container_options, project, service, options, toplevel_options, - project_dir='.'): + toplevel_environment): if not options['--no-deps']: deps = service.get_dependency_names() if deps: @@ -1360,9 +1354,8 @@ def run_one_off_container(container_options, project, service, options, toplevel if options['--rm']: project.client.remove_container(container.id, force=True, v=True) - environment_file = options.get('--env-file') - environment = Environment.from_env_file(project_dir, environment_file) - use_cli = not environment.get_boolean('COMPOSE_INTERACTIVE_NO_CLI') + use_cli = not toplevel_environment.get_boolean('COMPOSE_INTERACTIVE_NO_CLI') + signals.set_signal_handler_to_shutdown() signals.set_signal_handler_to_hang_up() try: @@ -1371,7 +1364,7 @@ def run_one_off_container(container_options, project, service, options, toplevel service.connect_container_to_networks(container, use_network_aliases) exit_code = call_docker( get_docker_start_call(container_options, container.id), - toplevel_options, environment + toplevel_options, toplevel_environment ) else: operation = RunOperation( diff --git a/compose/config/environment.py b/compose/config/environment.py index e72c88231..696356f32 100644 --- a/compose/config/environment.py +++ b/compose/config/environment.py @@ -26,7 +26,7 @@ def split_env(env): key = env if re.search(r'\s', key): raise ConfigurationError( - "environment variable name '{}' may not contains whitespace.".format(key) + "environment variable name '{}' may not contain whitespace.".format(key) ) return key, value diff --git a/contrib/completion/bash/docker-compose b/contrib/completion/bash/docker-compose index e9168b1b1..6dc47799d 100644 --- a/contrib/completion/bash/docker-compose +++ b/contrib/completion/bash/docker-compose @@ -184,6 +184,10 @@ _docker_compose_docker_compose() { _filedir -d return ;; + --env-file) + _filedir + return + ;; $(__docker_compose_to_extglob "$daemon_options_with_args") ) return ;; @@ -612,6 +616,7 @@ _docker_compose() { --tlsverify " local daemon_options_with_args=" + --env-file --file -f --host -H --project-directory diff --git a/contrib/completion/fish/docker-compose.fish b/contrib/completion/fish/docker-compose.fish index 69ecc5056..0566e16ae 100644 --- a/contrib/completion/fish/docker-compose.fish +++ b/contrib/completion/fish/docker-compose.fish @@ -12,6 +12,7 @@ end complete -c docker-compose -s f -l file -r -d 'Specify an alternate compose file' complete -c docker-compose -s p -l project-name -x -d 'Specify an alternate project name' +complete -c docker-compose -l env-file -r -d 'Specify an alternate environment file (default: .env)' complete -c docker-compose -l verbose -d 'Show more output' complete -c docker-compose -s H -l host -x -d 'Daemon socket to connect to' complete -c docker-compose -l tls -d 'Use TLS; implied by --tlsverify' diff --git a/contrib/completion/zsh/_docker-compose b/contrib/completion/zsh/_docker-compose index 808b068a3..faf405988 100755 --- a/contrib/completion/zsh/_docker-compose +++ b/contrib/completion/zsh/_docker-compose @@ -341,6 +341,7 @@ _docker-compose() { '(- :)'{-h,--help}'[Get help]' \ '*'{-f,--file}"[${file_description}]:file:_files -g '*.yml'" \ '(-p --project-name)'{-p,--project-name}'[Specify an alternate project name (default: directory name)]:project name:' \ + '--env-file[Specify an alternate environment file (default: .env)]:env-file:_files' \ "--compatibility[If set, Compose will attempt to convert keys in v3 files to their non-Swarm equivalent]" \ '(- :)'{-v,--version}'[Print version and exit]' \ '--verbose[Show more output]' \ @@ -359,6 +360,7 @@ _docker-compose() { local -a relevant_compose_flags relevant_compose_repeatable_flags relevant_docker_flags compose_options docker_options relevant_compose_flags=( + "--env-file" "--file" "-f" "--host" "-H" "--project-name" "-p"