Source code for ecs_files_composer.envsubst

#  -*- coding: utf-8 -*-
# SPDX-License-Identifier: MPL-2.0
# Copyright 2020-2021 John Mille <>

Module to do a better env variables handling.

import os
import re

ENV_VAR_REGEXP = r"(?<!\\)\$(\w+|\{(?!AWS::)([^}]*)\})"
SPECIAL_INTERPOLATION = r"(?<!\\)(\$(\{(((?!AWS::)[^}]+)(\:[+-=]{1}))([^}]+)\}))"
IF_ESCAPED = r"(?<!\\)"
IF_DEFINED = r":+"
IF_LITTERAL = re.compile("(\$(\{\![^}]+\}))")

[docs]def expandvars(path, default=None, skip_escaped=True, enable_litteral=True): """ Expand environment variables of form $var and ${var}. If parameter 'skip_escaped' is True, all escaped variable references (i.e. preceded by backslashes) are skipped. Unknown variables are set to 'default'. If 'default' is None, they are left unchanged. """ def replace_var(match): if IF_LITTERAL.match( and enable_litteral: return re.sub(r"\!", "", IF_LITTERAL.match( if re.match(SPECIAL_INTERPOLATION, groups = re.findall(SPECIAL_INTERPOLATION, if groups[0][-2] == IF_UNDEFINED: return os.environ.get(groups[0][-3]) or expandvars( groups[0][-1], default, skip_escaped ) elif groups[0][-2] == IF_DEFINED: return expandvars(groups[0][-1]) return os.environ.get( or, if default is None else default, ) re_string = (IF_ESCAPED if skip_escaped else "") + r"\$(\w+|\{(?!AWS::)([^}]*)\})" return re.sub(re_string, replace_var, path)