def test_strict_parsing():
    importlib.reload(expandvars)

    with pytest.raises(
        expandvars.ExpandvarsException, match="FOO: parameter null or not set"
    ) as e:
        expandvars.expandvars("${FOO:?}")
    assert isinstance(e.value, expandvars.ParameterNullOrNotSet)

    with pytest.raises(
        expandvars.ExpandvarsException, match="FOO: parameter null or not set"
    ) as e:
        expandvars.expandvars("${FOO?}")
    assert isinstance(e.value, expandvars.ParameterNullOrNotSet)

    with pytest.raises(expandvars.ExpandvarsException, match="FOO: custom error") as e:
        expandvars.expandvars("${FOO:?custom error}")
    assert isinstance(e.value, expandvars.ParameterNullOrNotSet)

    with pytest.raises(expandvars.ExpandvarsException, match="FOO: custom error") as e:
        expandvars.expandvars("${FOO?custom error}")
    assert isinstance(e.value, expandvars.ParameterNullOrNotSet)

    env.update({"FOO": "foo"})

    assert expandvars.expandvars("${FOO:?custom err}") == "foo"
    assert expandvars.expandvars("${FOO?custom err}:bar") == "foo:bar"
示例#2
0
def test_expandvars_get_default():
    importlib.reload(expandvars)

    assert expandvars.expandvars("${FOO-default}") == "default"
    assert expandvars.expandvars("${FOO:-default}") == "default"
    assert expandvars.expandvars("${FOO:-}") == ""
    assert expandvars.expandvars("${FOO:-foo}:${FOO-bar}") == "foo:bar"
def test_expandvars_indirection():
    importlib.reload(expandvars)

    assert expandvars.expandvars("${!FOO}:${FOO}") == "foo:X"
    assert expandvars.expandvars("${!FOO-default}") == "foo"
    assert expandvars.expandvars("${!BAR-default}") == "default"
    assert expandvars.expandvars("${!X-default}") == "default"
示例#4
0
def expandvars_dict(settings: t.Dict[str, str]) -> t.Dict[str, t.Any]:
    """Expand strings or variables from the environment into equivalent python literals or strings.

    >>> from pyramid_heroku import expandvars_dict
    >>> from pprint import pprint
    >>> from unittest import mock
    >>> import os
    >>> with mock.patch.dict(os.environ,{'STRING':'text', 'BOOL': 'true', 'INT':'1', 'NESTED':'nested_${STRING}'}):
    ...    pprint(expandvars_dict({
    ...        "bool": "true",
    ...        "default_bool": "${FOO:-false}",
    ...        "default_int": "${FOO:-2}",
    ...        "default_string": "${FOO:-bar}",
    ...        "env_bool": "${BOOL:-foo}",
    ...        "env_int": "${INT:-foo}",
    ...        "env_string": "${STRING:-foo}",
    ...        "int": "1",
    ...        "must_be_set": "${STRING:? error: STRING must be set!}",
    ...        "nested": "${NESTED:-foo}",
    ...        "string": "foo",
    ...    }))
    {'bool': True,
     'default_bool': False,
     'default_int': 2,
     'default_string': 'bar',
     'env_bool': True,
     'env_int': 1,
     'env_string': 'text',
     'int': 1,
     'must_be_set': 'text',
     'nested': 'nested_text',
     'string': 'foo'}
    """
    return {k: safe_eval(expandvars(expandvars(v))) for k, v in settings.items()}
示例#5
0
def test_invalid_length_err():
    importlib.reload(expandvars)

    with pytest.raises(expandvars.ExpandvarsException,
                       match="FOO: -3: substring expression < 0") as e:
        expandvars.expandvars("${FOO:1:-3}")
    assert isinstance(e.value, expandvars.NegativeSubStringExpression)
def test_offset():
    importlib.reload(expandvars)

    assert expandvars.expandvars("${FOO:3}") == "nbigfoobar"
    assert expandvars.expandvars("${FOO: 4 }") == "bigfoobar"
    assert expandvars.expandvars("${FOO:30}") == ""
    assert expandvars.expandvars("${FOO:0}") == "damnbigfoobar"
    assert expandvars.expandvars("${FOO:-3}:bar") == "damnbigfoobar:bar"
示例#7
0
def test_offset():
    os.environ.update({"FOO": "damnbigfoobar"})

    assert expandvars("${FOO:3}") == "nbigfoobar"
    assert expandvars("${FOO: 4}") == "bigfoobar"
    assert expandvars("${FOO:30}") == ""
    assert expandvars("${FOO:0}") == "damnbigfoobar"
    assert expandvars("${FOO:foo}") == "damnbigfoobar"
示例#8
0
def test_expandvars_substitute():
    if "BAR" in os.environ:
        del os.environ["BAR"]
    os.environ.update({"FOO": "bar"})

    assert expandvars("${FOO:+foo}") == "foo"
    assert expandvars("${BAR:+foo}") == ""
    assert expandvars("${BAR:+}") == ""
def test_missing_escapped_character():
    importlib.reload(expandvars)

    with pytest.raises(expandvars.ExpandvarsException) as e:
        expandvars.expandvars("$FOO\\")

    assert str(e.value) == "$FOO\\: missing escaped character"
    assert isinstance(e.value, expandvars.MissingExcapedChar)
示例#10
0
def test_strict_parsing_recover_null():
    importlib.reload(expandvars)

    assert expandvars.expandvars("${FOO:?}:${BAR?}") == "foo:bar"
    assert expandvars.expandvars("${FOO:?custom err}:${BAR?custom err}") == "foo:bar"

    assert expandvars.expandvars("$FOO$BAR", nounset=True) == "foobar"
    assert expandvars.expandvars("${FOO}:${BAR}", nounset=True) == "foo:bar"
示例#11
0
def resolve_element(element: str) -> str:
    if re.search("(\$\{).+(\})", element):  # noqa: W605
        return expandvars(element, nounset=True)
    elif element.startswith("$"):
        try:
            return expandvars(element, nounset=True)
        except UnboundVariable:
            return element
    else:
        return element
示例#12
0
def test_brace_never_closed_err():
    os.environ.update({"FOO": "damnbigfoobar"})

    with pytest.raises(ValueError) as e:
        expandvars("${FOO:")
    assert str(e.value) == "${FOO:: '{' was never closed."

    with pytest.raises(ValueError) as e:
        expandvars("${FOO}${BAR")
    assert str(e.value) == "${BAR: '{' was never closed."
示例#13
0
def resolve_element(element: str) -> str:
    if element.startswith("${") & element.endswith("}"):
        return expandvars(element, nounset=True)
    elif element.startswith("$"):
        try:
            return expandvars(element, nounset=True)
        except UnboundVariable:
            return element
    else:
        return element
示例#14
0
def test_expandvars_update_default():
    if "FOO" in os.environ:
        del os.environ["FOO"]

    assert expandvars("${FOO:=}") == ""

    del os.environ["FOO"]

    assert expandvars("${FOO:=default}") == "default"
    assert os.environ.get("FOO") == "default"
    assert expandvars("${FOO:=ignoreme}") == "default"
def test_bad_substitution_err():
    importlib.reload(expandvars)

    with pytest.raises(expandvars.ExpandvarsException) as e:
        expandvars.expandvars("${FOO:}") == ""
    assert str(e.value) == "${FOO:}: bad substitution"
    assert isinstance(e.value, expandvars.BadSubstitution)

    with pytest.raises(expandvars.ExpandvarsException) as e:
        expandvars.expandvars("${}") == ""
    assert str(e.value) == "${}: bad substitution"
    assert isinstance(e.value, expandvars.BadSubstitution)
示例#16
0
def test_offset_length():
    os.environ.update({"FOO": "damnbigfoobar"})

    assert expandvars("${FOO:4:3}") == "big"
    assert expandvars("${FOO: 7:6}") == "foobar"
    assert expandvars("${FOO:7: 100}") == "foobar"
    assert expandvars("${FOO:0:100}") == "damnbigfoobar"
    assert expandvars("${FOO:70:10}") == ""
    assert expandvars("${FOO:1:0}") == ""
    assert expandvars("${FOO:0:}") == ""
    assert expandvars("${FOO:0:foo}") == ""
    assert expandvars("${FOO::}") == ""
    assert expandvars("${FOO::5}") == "damnb"
def test_offset_length():
    importlib.reload(expandvars)

    assert expandvars.expandvars("${FOO:4:3}") == "big"
    assert expandvars.expandvars("${FOO: 7:6 }") == "foobar"
    assert expandvars.expandvars("${FOO:7: 100 }") == "foobar"
    assert expandvars.expandvars("${FOO:0:100}") == "damnbigfoobar"
    assert expandvars.expandvars("${FOO:70:10}") == ""
    assert expandvars.expandvars("${FOO:1:0}") == ""
    assert expandvars.expandvars("${FOO:0:}") == ""
    assert expandvars.expandvars("${FOO::}") == ""
    assert expandvars.expandvars("${FOO::5}") == "damnb"
    assert expandvars.expandvars("${FOO:-3:1}:bar") == "damnbigfoobar:bar"
示例#18
0
def test_strict_parsing():
    if "FOO" in os.environ:
        del os.environ["FOO"]

    with pytest.raises(ValueError) as e:
        expandvars("${FOO:?}")
    assert str(e.value) == "FOO: parameter null or not set"

    with pytest.raises(ValueError) as e:
        expandvars("${FOO:?custom error}")
    assert str(e.value) == "FOO: custom error"

    os.environ.update({"FOO": "foo"})

    assert expandvars("${FOO:?custom err}") == "foo"
示例#19
0
def get_environ_keys(*args, **kwargs):
    from expandvars import expandvars

    k = kwargs.get('key')
    v = kwargs.get('value')
    assert (k is not None) and (
        v is not None), 'Problem with kwargs -> {}, k={}, v={}'.format(
            kwargs, k, v)
    __logger__ = kwargs.get('logger')
    if (k == '__LITERALS__'):
        _v = eval(v)
        if (isinstance(_v, list)):
            for item in _v:
                env_literals.append(item)
        else:
            env_literals.append(_v)
    if (isinstance(v, str)):
        v = expandvars(v) if (k not in env_literals) else v
        v = __escape(v) if (k in __env__.get('__ESCAPED__', [])) else v
    ignoring = __env__.get('IGNORING', [])
    environ = kwargs.get('environ', None)
    if (isinstance(environ, dict)):
        environ[k] = v
    if (k not in ignoring):
        __env__[k] = v
    if (__logger__):
        __logger__.info('\t{} -> {}'.format(k, environ.get(k)))
    return tuple([k, v])
示例#20
0
def from_string(text, cwd="./"):
    # expand environment variables
    protected = (text.replace("$/", "~INCLUDE~").replace(
        "$.", "~REFERENCE~").replace("$self.", "~SELFREF~"))
    parsed = (expandvars(protected).replace("~INCLUDE~", "$/").replace(
        "~REFERENCE~", "$.").replace("~SELFREF~", "$self."))
    config = yaml.load(parsed, lambda stream: Loader(stream, cwd))

    # process includes
    for key, include in config.pop("includes", {}).items():
        if not isinstance(include, dict):
            raise ValueError(
                f"Include '{key}' must be a mapping. {type(include)} given.")

        for k, v in include.items():
            if k not in ["mixins", "components"
                         ] and not k.startswith("components:"):
                continue

            if k not in config:
                config[k] = v
                continue

            config[k].extend(v)

    return config
示例#21
0
def test_expandvars_option_nounset():
    importlib.reload(expandvars)

    assert expandvars.expandvars("$FOO") == ""

    with pytest.raises(expandvars.ExpandvarsException,
                       match="FOO: unbound variable") as e:
        expandvars.expandvars("$FOO", nounset=True)

    assert isinstance(e.value, expandvars.UnboundVariable)

    with pytest.raises(expandvars.ExpandvarsException,
                       match="FOO: unbound variable") as e:
        expandvars.expandvars("${FOO}", nounset=True)

    assert isinstance(e.value, expandvars.UnboundVariable)
示例#22
0
def run(spec_file):
    if not os.path.exists(spec_file):
        raise RunTimeError("Spec file not found: %s" % spec_file)

    root_dir = os.path.dirname(spec_file)

    with open(spec_file) as f:
        spec_file_str = expandvars(f.read(), nounset=True)

        global_spec = yaml.load(StringIO(spec_file_str),
                                Loader=yaml.FullLoader)
        is_strict = global_spec.get("settings", {}).get("is_strict", True)

        require_variables(global_spec.get("required_variables", []))

        for output_filename, spec in global_spec["outputs"].items():
            memo = dict(os.environ)
            compile_files(root_dir, global_spec.get("global_dependencies", []),
                          is_strict)
            compile_files(root_dir, spec.get("dependencies", []), is_strict)
            try:
                content = compile_files(root_dir, spec["targets"], is_strict)
            finally:
                os.environ.clear()
                os.environ.update(memo)
            with open(output_filename, 'w') as f:
                f.write(content)
示例#23
0
def test_invalid_operand_err():
    os.environ = {"FOO": "damnbigfoobar"}
    oprnds = "@#$%^&*()_'\"\\"

    for o in oprnds:
        with pytest.raises(ValueError) as e:
            expandvars("${{FOO:{}}}".format(o))
        assert str(e.value) == (
            "{}: syntax error: operand expected (error token is {})").format(
                o, repr(o))

        with pytest.raises(ValueError) as e:
            expandvars("${{FOO:0:{}}}".format(o))
        assert str(e.value) == (
            "{}: syntax error: operand expected (error token is {})").format(
                o, repr(o))
def test_escape():
    importlib.reload(expandvars)

    assert expandvars.expandvars("\\$FOO\\$BAR") == "$FOO$BAR"
    assert expandvars.expandvars("\\\\$FOO") == "\\foo"
    assert expandvars.expandvars("$FOO\\$BAR") == "foo$BAR"
    assert expandvars.expandvars("\\$FOO$BAR") == "$FOObar"
    assert expandvars.expandvars("$FOO" "\\" "\\" "\\" "$BAR") == ("foo" "\\" "$BAR")
    assert expandvars.expandvars("$FOO\\$") == "foo$"
    assert expandvars.expandvars("$\\FOO") == "$\\FOO"
    assert expandvars.expandvars("$\\$FOO") == "$$FOO"
    assert expandvars.expandvars("\\$FOO") == "$FOO"
    assert (
        expandvars.expandvars("D:\\\\some\\windows\\path")
        == "D:\\\\some\\windows\\path"
    )
示例#25
0
def test_expandvars_option_nounset_with_strict():
    importlib.reload(expandvars)

    with pytest.raises(expandvars.ExpandvarsException,
                       match="FOO: parameter null or not set") as e:
        assert expandvars.expandvars("${FOO:?}", nounset=True)

    assert isinstance(e.value, expandvars.ParameterNullOrNotSet)
def test_expandvars_substitute():
    importlib.reload(expandvars)

    assert expandvars.expandvars("${FOO:+foo}") == "foo"
    assert expandvars.expandvars("${FOO+foo}") == "foo"
    assert expandvars.expandvars("${BAR:+foo}") == ""
    assert expandvars.expandvars("${BAR+foo}") == ""
    assert expandvars.expandvars("${BAR:+}") == ""
    assert expandvars.expandvars("${BAR+}") == ""
    assert expandvars.expandvars("${BUZ:+foo}") == "foo"
    assert expandvars.expandvars("${BUZ+foo}:bar") == "foo:bar"
示例#27
0
def test_escape():
    os.environ.update({"FOO": "foo", "BAR": "bar"})

    assert expandvars("\\$FOO\\$BAR") == "$FOO$BAR"
    assert expandvars("$FOO\\$BAR") == "foo$BAR"
    assert expandvars("\\$FOO$BAR") == "$FOObar"
    assert expandvars("$FOO" "\\" "\\" "\\" "$BAR") == ("foo" "\\" "\\" "$BAR")
    assert expandvars("$FOO\\$") == "foo$"
    assert expandvars("$\\FOO") == "$\\FOO"
    assert expandvars("\\$FOO") == "$FOO"
    assert expandvars("D:\\some\\windows\\path") == "D:\\some\\windows\\path"
示例#28
0
def test_invalid_operand_err():
    importlib.reload(expandvars)

    oprnds = "@#$%^&*()_'\""

    for o in oprnds:
        with pytest.raises(expandvars.ExpandvarsException) as e:
            expandvars.expandvars("${{FOO:0:{0}}}".format(o))
        assert str(e.value) == ("FOO: operand expected (error token is {0})").format(
            repr(o)
        )
        assert isinstance(e.value, expandvars.OperandExpected)

        with pytest.raises(expandvars.ExpandvarsException) as e:
            expandvars.expandvars("${{FOO:{0}:{0}}}".format(o))
        assert str(e.value) == ("FOO: operand expected (error token is {0})").format(
            repr(o)
        )
        assert isinstance(e.value, expandvars.OperandExpected)
示例#29
0
    def __init__(self,
                 default=None,
                 help=None,
                 dtype=None,
                 metavar='\b',
                 env=None,
                 nounset=False,
                 **kwargs):
        """
        The proto object. The env attribute allows one to set the environment variable
        from which this proto reads value from.

        :param default:
        :param help:
        :param dtype:
        :param metavar:
        :param env: the environment variable for the default value -- in the next version could be set
             automatically from the prefix of the class.
        :param nonset: default to False, when true raises error for env var that are not set.
        :param kwargs:
        """
        from termcolor import colored
        if default and not dtype:
            dtype = type(default)
        # only apply dtype to ENV, and when dtype is not None.
        if env:
            if nounset or env in os.environ:
                default = os.environ[env]
            elif "$" in env:
                default = expandvars(env, nounset=nounset)
            if dtype:
                default = dtype(default)

        default_str = str([default])[1:-1]
        if len(default_str) > 45:
            default_str = default_str[:42] + "..."
        default_str = default_str.replace('%', '%%')
        help_str = colored(
            f"\t<{'any' if dtype is None else dtype.__name__}> ", "blue")
        if env and env in os.environ:
            help_str += colored("$" + env, 'magenta') + '='
        if default_str:
            help_str += colored(default_str, 'cyan') + " "
        if help:
            # todo: handle multi-line help strings. Parse and remove indent.
            if len(help_str + help) > 60:
                help_str += '\n' + help
            else:
                help_str += help

        super().__init__(default=default,
                         help=help_str,
                         dtype=dtype,
                         metavar=metavar,
                         **kwargs)
示例#30
0
 def onecmd(self, line):
     line = expandvars(line.strip())
     cmd_args = shlex.split(line)
     if len(cmd_args) == 0:
         return
     cmd = cmd_args[0]
     self.lastcmd = line
     if hasattr(self, 'do_' + cmd):
         return getattr(self, 'do_' + cmd)(cmd_args[1:])
     else:
         return self.default(cmd_args, line)