瀏覽代碼

Merge pull request #6800 from KlaasH/revise-env-file-option

Make '--env-file' option top-level only and fix failure with subcommands
Djordje Lukic 6 年之前
父節點
當前提交
7a7c9ff67a

+ 15 - 22
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(

+ 1 - 1
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
 

+ 5 - 0
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

+ 1 - 0
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'

+ 2 - 0
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"