Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow custom separators for append and prepend from profile #15957

Open
wants to merge 1 commit into
base: develop2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
48 changes: 34 additions & 14 deletions conan/tools/env/environment.py
@@ -1,5 +1,6 @@
import os
import textwrap
import re
from collections import OrderedDict
from contextlib import contextmanager

Expand Down Expand Up @@ -81,19 +82,20 @@ def __init__(self, name, value=None, separator=" ", path=False):
def dumps(self):
result = []
path = "(path)" if self._path else ""
custom_sep = "" if self._sep == " " else "(sep={})".format(self._sep)
if not self._values: # Empty means unset
result.append("{}=!".format(self._name))
elif _EnvVarPlaceHolder in self._values:
index = self._values.index(_EnvVarPlaceHolder)
for v in self._values[:index]:
result.append("{}=+{}{}".format(self._name, path, v))
result.append("{}=+{}{}{}".format(self._name, custom_sep, path, v))
for v in self._values[index+1:]:
result.append("{}+={}{}".format(self._name, path, v))
result.append("{}+={}{}{}".format(self._name, custom_sep, path, v))
else:
append = ""
for v in self._values:
result.append("{}{}={}{}".format(self._name, append, path, v))
append = "+"
append = "+{}".format(custom_sep)
return "\n".join(result)

def copy(self):
Expand Down Expand Up @@ -604,16 +606,38 @@ def dumps(self):
@staticmethod
def loads(text):
result = ProfileEnvironment()

operator_pattern_method_mapping = (
(r"\+=([\s]*)\(sep=([^\)]+)\)", "append"),
(r"=\+([\s]*)\(sep=([^\)]+)\)", "prepend"),
("+=", "append"),
("=+", "prepend"),
("=!", "unset"),
("=", "define"),
)

for line in text.splitlines():
line = line.strip()
if not line or line.startswith("#"):
continue
for op, method in (("+=", "append"), ("=+", "prepend"),
("=!", "unset"), ("=", "define")):
tokens = line.split(op, 1)
if len(tokens) != 2:
continue
pattern_name, value = tokens
for (op, method) in operator_pattern_method_mapping:
if "sep=" in op:
tokens = re.split(op, line)
if len(tokens) != 4:
continue
pattern_name, _, separator, value = tokens
keyword_args = {"separator": separator}
else:
tokens = line.split(op, 1)
if len(tokens) != 2:
continue
pattern_name, value = tokens
keyword_args = {}
if value.strip().startswith("(path)"):
value = value.strip()
value = value[6:]
method = method + "_path"

pattern_name = pattern_name.split(":", 1)
if len(pattern_name) == 2:
pattern, name = pattern_name
Expand All @@ -629,11 +653,7 @@ def loads(text):
if method == "unset":
env.unset(name)
else:
if value.strip().startswith("(path)"):
value = value.strip()
value = value[6:]
method = method + "_path"
getattr(env, method)(name, value)
getattr(env, method)(name, value, **keyword_args)

existing = result._environments.get(pattern)
if existing is None:
Expand Down
47 changes: 39 additions & 8 deletions conans/test/unittests/tools/env/test_env.py
Expand Up @@ -155,6 +155,11 @@ def test_profile():
# unset
MyPath4=!

# Custom append/prepend
MyCustomList=is;+something
MyCustomList=+(sep=;+)this
MyCustomList+=(sep=;+)weird

# PER-PACKAGE
mypkg*:MyVar2=MyValue2
""")
Expand All @@ -171,6 +176,7 @@ def test_profile():
assert env.get("MyVar3", "$MyVar3") == 'MyValue3 $MyVar3'
assert env.get("MyVar4") == ""
assert env.get("MyVar5") == ''
assert env.get("MyCustomList") == 'this;+is;+something;+weird'

env = profile_env.get_profile_env(RecipeReference.loads("mypkg1/1.0"))
env = env.vars(ConanFileMock())
Expand Down Expand Up @@ -356,29 +362,46 @@ def test_define(self):
def test_append(self):
myprofile = textwrap.dedent("""
# define
MyVar1+=MyValue1
MyPath1 +=(path)/my/path1
MyVar+=MyValue1
MyVar+=MyValue2
MyPath+=(path)/my/path1
MyPath += (path)/my/path2
MyList+=(sep=;)item1
MyList += (sep=;)item2
""")

env = ProfileEnvironment.loads(myprofile)
text = env.dumps()
assert text == textwrap.dedent("""\
MyVar1+=MyValue1
MyPath1+=(path)/my/path1
MyVar+=MyValue1
MyVar+=MyValue2
MyPath+=(path)/my/path1
MyPath+=(path)/my/path2
MyList+=(sep=;)item1
MyList+=(sep=;)item2
""")

def test_prepend(self):
myprofile = textwrap.dedent("""
# define
MyVar1=+MyValue1
MyPath1=+(path)/my/path1
MyVar=+MyValue1
MyVar=+MyValue2
MyPath =+ (path)/my/path1
MyPath=+(path)/my/path2
MyList =+ (sep=++)item1
MyList=+(sep=++)item2
""")

env = ProfileEnvironment.loads(myprofile)
text = env.dumps()
# XXX: This seems wrong?
assert text == textwrap.dedent("""\
MyVar1=+MyValue1
MyPath1=+(path)/my/path1
MyVar=+MyValue2
MyVar=+MyValue1
MyPath=+(path)/my/path2
MyPath=+(path)/my/path1
MyList=+(sep=++)item2
MyList=+(sep=++)item1
""")

def test_combined(self):
Expand All @@ -387,6 +410,8 @@ def test_combined(self):
MyVar1+=MyValue12
MyPath1=+(path)/my/path11
MyPath1+=(path)/my/path12
MyList1=+(sep=;)item11
MyList1+=(sep=;)item12
""")

env = ProfileEnvironment.loads(myprofile)
Expand All @@ -396,6 +421,8 @@ def test_combined(self):
MyVar1+=MyValue12
MyPath1=+(path)/my/path11
MyPath1+=(path)/my/path12
MyList1=+(sep=;)item11
MyList1+=(sep=;)item12
""")

def test_combined2(self):
Expand All @@ -404,6 +431,8 @@ def test_combined2(self):
MyVar1=+MyValue12
MyPath1+=(path)/my/path11
MyPath1=+(path)/my/path12
MyList1+=(sep=;)item11
MyList1=+(sep=;)item12
""")

env = ProfileEnvironment.loads(myprofile)
Expand All @@ -414,6 +443,8 @@ def test_combined2(self):
MyVar1+=MyValue11
MyPath1=+(path)/my/path12
MyPath1+=(path)/my/path11
MyList1=+(sep=;)item12
MyList1+=(sep=;)item11
""")


Expand Down