Skip to content

Commit

Permalink
Better profiles parsing and error controlled (conan-io#608)
Browse files Browse the repository at this point in the history
  • Loading branch information
lasote authored and memsharded committed Oct 26, 2016
1 parent 0669f40 commit e8a554f
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 29 deletions.
8 changes: 7 additions & 1 deletion conans/client/client_cache.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from conans.paths import SimplePaths
from genericpath import isdir
from conans.model.profile import Profile
from conans.errors import ConanException

CONAN_CONF = 'conan.conf'
CONAN_SETTINGS = "settings.yml"
Expand Down Expand Up @@ -156,7 +157,12 @@ def profile_path(self, name):
return os.path.join(self.profiles_path, name)

def load_profile(self, name):
text = load(self.profile_path(name))
try:
text = load(self.profile_path(name))
except Exception:
current_profiles = ", ".join(self.current_profiles()) or "[]"
raise ConanException("Specified profile '%s' doesn't exist.\nExisting profiles: "
"%s" % (name, current_profiles))
return Profile.loads(text)

def current_profiles(self):
Expand Down
5 changes: 1 addition & 4 deletions conans/client/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,10 +220,7 @@ def _read_profile(self, profile_name):
return profile
except ConanException as exc:
raise ConanException("Error reading '%s' profile: %s" % (profile_name, exc))
except Exception:
current_profiles = ", ".join(self._client_cache.current_profiles()) or "[]"
raise ConanException("Specified profile '%s' doesn't exist.\nExisting profiles: "
"%s" % (profile_name, current_profiles))

return None

def _mix_settings_and_profile(self, settings, profile):
Expand Down
65 changes: 41 additions & 24 deletions conans/model/profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,18 @@
from conans.errors import ConanException


def _clean_value(value):
'''Strip a value and remove the quotes. EX:
key="value " => str('value')
'''
value = value.strip()
if value.startswith('"') and value.endswith('"') and value != '"':
value = value[1:-1]
if value.startswith("'") and value.endswith("'") and value != "'":
value = value[1:-1]
return value


class Profile(object):
'''A profile contains a set of setting (with values), environment variables
and scopes'''
Expand All @@ -17,30 +29,35 @@ def __init__(self):

@staticmethod
def loads(text):
obj = Profile()
doc = ConfigParser(text, allowed_fields=["settings", "env", "scopes"])

for setting in doc.settings.splitlines():
setting = setting.strip()
if setting and not setting.startswith("#"):
if "=" not in setting:
raise ConanException("Invalid setting line '%s'" % setting)
name, value = setting.split("=")
obj.settings[name.strip()] = value.strip()

if doc.scopes:
obj.scopes = Scopes.from_list(doc.scopes.splitlines())

for env in doc.env.splitlines():
env = env.strip()
if env and not env.startswith("#"):
if "=" not in env:
raise ConanException("Invalid env line '%s'" % env)
varname, value = env.split("=")
obj.env[varname.strip()] = value.strip()

obj._order()
return obj
try:
obj = Profile()
doc = ConfigParser(text, allowed_fields=["settings", "env", "scopes"])

for setting in doc.settings.splitlines():
setting = setting.strip()
if setting and not setting.startswith("#"):
if "=" not in setting:
raise ConanException("Invalid setting line '%s'" % setting)
name, value = setting.split("=", 1)
obj.settings[name.strip()] = _clean_value(value)

if doc.scopes:
obj.scopes = Scopes.from_list(doc.scopes.splitlines())

for env in doc.env.splitlines():
env = env.strip()
if env and not env.startswith("#"):
if "=" not in env:
raise ConanException("Invalid env line '%s'" % env)
varname, value = env.split("=", 1)
obj.env[varname.strip()] = _clean_value(value)

obj._order()
return obj
except ConanException:
raise
except Exception as exc:
raise ConanException("Error parsing the profile text file: %s" % str(exc))

def dumps(self):
self._order() # gets in order the settings
Expand Down
30 changes: 30 additions & 0 deletions conans/test/model/profile_test.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import unittest
from conans.model.profile import Profile
from conans.errors import ConanException


class ProfileTest(unittest.TestCase):
Expand Down Expand Up @@ -37,6 +38,35 @@ def profile_test(self):
self.assertEquals(dict(new_profile.scopes)["p1"]["conaning"], '1')
self.assertEquals(dict(new_profile.scopes)["p2"]["testing"], '2')

def profile_loads_test(self):
prof = '''[env]
CXX_FLAGS="-DAAA=0"
[settings]
'''
new_profile = Profile.loads(prof)
self.assertEquals(new_profile.env["CXX_FLAGS"], "-DAAA=0")

prof = '''[env]
CXX_FLAGS='-DAAA=0'
[settings]
'''
new_profile = Profile.loads(prof)
self.assertEquals(new_profile.env["CXX_FLAGS"], "-DAAA=0")

prof = '''[env]
CXX_FLAGS=-DAAA=0
[settings]
'''
new_profile = Profile.loads(prof)
self.assertEquals(new_profile.env["CXX_FLAGS"], "-DAAA=0")

prof = '''[env]
CXX_FLAGS="-DAAA=0
[settings]
'''
new_profile = Profile.loads(prof)
self.assertEquals(new_profile.env["CXX_FLAGS"], "\"-DAAA=0")

def profile_dump_order_test(self):
# Settings
profile = Profile()
Expand Down

0 comments on commit e8a554f

Please sign in to comment.