diff --git a/compose/cli/command.py b/compose/cli/command.py index 2f38fe5af4c..6517107d2f9 100644 --- a/compose/cli/command.py +++ b/compose/cli/command.py @@ -39,8 +39,12 @@ def project_from_options(project_dir, options, additional_options={}): override_dir = options.get('--project-directory') - environment_file = options.get('--env-file') - environment = Environment.from_env_file(override_dir or project_dir, environment_file) + skip_environment_file = options.get('--skip-env-file') or os.getenv("COMPOSE_SKIP_ENV_FILE") + if skip_environment_file: + environment = Environment.from_nothing() + else: + environment_file = options.get('--env-file') + environment = Environment.from_env_file(override_dir or project_dir, environment_file) environment.silent = options.get('COMMAND', None) in SILENT_COMMANDS set_parallel_limit(environment) @@ -79,8 +83,12 @@ def set_parallel_limit(environment): def get_config_from_options(base_dir, options, additional_options={}): override_dir = options.get('--project-directory') - environment_file = options.get('--env-file') - environment = Environment.from_env_file(override_dir or base_dir, environment_file) + skip_environment_file = options.get('--skip-env-file') or os.getenv("COMPOSE_SKIP_ENV_FILE") + if skip_environment_file: + environment = Environment.from_nothing() + else: + environment_file = options.get('--env-file') + environment = Environment.from_env_file(override_dir or base_dir, environment_file) config_path = get_config_path_from_options( base_dir, options, environment ) diff --git a/compose/cli/main.py b/compose/cli/main.py index 477b57b52ef..cb49f859890 100644 --- a/compose/cli/main.py +++ b/compose/cli/main.py @@ -6,6 +6,7 @@ import functools import json import logging +import os import pipes import re import subprocess @@ -209,6 +210,8 @@ class TopLevelCommand(object): --compatibility If set, Compose will attempt to convert keys in v3 files to their non-Swarm equivalent --env-file PATH Specify an alternate environment file + --skip-env-file Skip loading an environment file + (You can also specify this flag by setting COMPOSE_SKIP_ENV_FILE=1) Commands: build Build or rebuild services @@ -249,8 +252,14 @@ def project_dir(self): @property def toplevel_environment(self): - environment_file = self.toplevel_options.get('--env-file') - return Environment.from_env_file(self.project_dir, environment_file) + skip_environment_file = self.toplevel_options.get('--skip-env-file') \ + or os.getenv("COMPOSE_SKIP_ENV_FILE") + if skip_environment_file: + environment = Environment.from_nothing() + else: + environment_file = self.toplevel_options.get('--env-file') + environment = Environment.from_env_file(self.project_dir, environment_file) + return environment def build(self, options): """ diff --git a/compose/config/environment.py b/compose/config/environment.py index 696356f3246..d1638e5c099 100644 --- a/compose/config/environment.py +++ b/compose/config/environment.py @@ -58,6 +58,12 @@ def __init__(self, *args, **kwargs): self.missing_keys = [] self.silent = False + @classmethod + def from_nothing(cls): + instance = cls() + instance.update(os.environ) + return instance + @classmethod def from_env_file(cls, base_dir, env_file=None): def _initialize(): diff --git a/tests/acceptance/cli_test.py b/tests/acceptance/cli_test.py index 77b46c2790f..b67340cdc36 100644 --- a/tests/acceptance/cli_test.py +++ b/tests/acceptance/cli_test.py @@ -45,12 +45,13 @@ BUILD_PULL_TEXT = 'Status: Image is up to date for busybox:1.27.2' -def start_process(base_dir, options): +def start_process(base_dir, options, env=None): proc = subprocess.Popen( ['docker-compose'] + options, stdout=subprocess.PIPE, stderr=subprocess.PIPE, - cwd=base_dir) + cwd=base_dir, + env=env) print("Running process: %s" % proc.pid) return proc @@ -64,9 +65,9 @@ def wait_on_process(proc, returncode=0): return ProcessResult(stdout.decode('utf-8'), stderr.decode('utf-8')) -def dispatch(base_dir, options, project_options=None, returncode=0): +def dispatch(base_dir, options, project_options=None, returncode=0, env=None): project_options = project_options or [] - proc = start_process(base_dir, project_options + options) + proc = start_process(base_dir, project_options + options, env=env) return wait_on_process(proc, returncode=returncode) diff --git a/tests/fixtures/env-file-skip/.env b/tests/fixtures/env-file-skip/.env new file mode 100644 index 00000000000..76bcc018229 --- /dev/null +++ b/tests/fixtures/env-file-skip/.env @@ -0,0 +1 @@ +VAR2=VAL2 diff --git a/tests/fixtures/env-file-skip/docker-compose.yml b/tests/fixtures/env-file-skip/docker-compose.yml new file mode 100644 index 00000000000..b1043e4b1f4 --- /dev/null +++ b/tests/fixtures/env-file-skip/docker-compose.yml @@ -0,0 +1,9 @@ +version: '3' +services: + show_env: + image: alpine:latest + environment: + VAR1: VAL1 + VAR2: $VAR2 + command: + env diff --git a/tests/integration/environment_test.py b/tests/integration/environment_test.py index 671e65318a6..bbf18b7ae5f 100644 --- a/tests/integration/environment_test.py +++ b/tests/integration/environment_test.py @@ -1,6 +1,7 @@ from __future__ import absolute_import from __future__ import unicode_literals +import os import tempfile from ddt import data @@ -68,3 +69,20 @@ def test_env_file_override(self): assert "WHEREAMI=override" in containers[0].get('Config.Env') assert "DEFAULT_CONF_LOADED=true" in containers[0].get('Config.Env') dispatch(base_dir, ['--env-file', '.env.override', 'down'], None) + + +class EnvironmentSkipFileTest(DockerClientTestCase): + def test_env_file_skip(self): + base_dir = 'tests/fixtures/env-file-skip' + + result = dispatch(base_dir, ['up']) + assert "VAR1=VAL1" in result.stdout + assert "VAR2=VAL2" in result.stdout + + result = dispatch(base_dir, ['--skip-env-file', 'up']) + assert "VAR1=VAL1" in result.stdout + assert "VAR2=VAL2" not in result.stdout + + result = dispatch(base_dir, ['up'], env=dict(os.environ, COMPOSE_SKIP_ENV_FILE="1")) + assert "VAR1=VAL1" in result.stdout + assert "VAR2=VAL2" not in result.stdout