Skip to content

Commit

Permalink
preserve the explicit value None for attributes with a different defa…
Browse files Browse the repository at this point in the history
…ult (#8622)
  • Loading branch information
jgsogo committed Mar 10, 2021
1 parent e126605 commit 8c9cf2a
Show file tree
Hide file tree
Showing 3 changed files with 122 additions and 16 deletions.
7 changes: 5 additions & 2 deletions conans/model/scm.py
Expand Up @@ -38,7 +38,7 @@ def __init__(self, conanfile):
data = getattr(conanfile, "scm")
self.type = _get_dict_value(data, "type", string_types)
self.url = _get_dict_value(data, "url", string_types)
self.revision = _get_dict_value(data, "revision", string_types + (int, ),
self.revision = _get_dict_value(data, "revision", string_types + (int,),
disallowed_type=bool) # bool is subclass of integer
self.verify_ssl = _get_dict_value(data, "verify_ssl", bool, SCMData.VERIFY_SSL_DEFAULT)
self.username = _get_dict_value(data, "username", string_types)
Expand All @@ -65,11 +65,12 @@ def as_dict(self):
d = {"url": self.url, "revision": self.revision, "username": self.username,
"password": self.password, "type": self.type,
"subfolder": self.subfolder, "submodule": self.submodule}
d = {k: v for k, v in d.items() if v is not None}
# Preserve the value 'None' for those entries with not falsy default.
if self.shallow != self.SHALLOW_DEFAULT:
d.update({"shallow": self.shallow})
if self.verify_ssl != self.VERIFY_SSL_DEFAULT:
d.update({"verify_ssl": self.verify_ssl})
d = {k: v for k, v in d.items() if v is not None}
return d

def __repr__(self):
Expand All @@ -78,6 +79,8 @@ def __repr__(self):
def _kv_to_string(key, value):
if isinstance(value, bool):
return '"{}": {}'.format(key, value)
elif value is None:
return '"{}": None'.format(key)
else:
value_str = str(value).replace('"', r'\"')
return '"{}": "{}"'.format(key, value_str)
Expand Down
68 changes: 61 additions & 7 deletions conans/test/functional/scm/test_git_shallow.py
@@ -1,5 +1,5 @@
# coding=utf-8

import os
import textwrap
import unittest

Expand All @@ -8,13 +8,32 @@
from parameterized.parameterized import parameterized_class

from conans.model.ref import ConanFileReference
from conans.test.utils.tools import TestClient
from conans.paths import DATA_YML
from conans.test.utils.scm import create_local_git_repo
from conans.test.utils.tools import TestClient
from conans.util.files import load


@pytest.mark.parametrize("scm_to_conandata", [True, False])
def test_shallow_none_string(scm_to_conandata):
client = TestClient()
client.run("config set general.scm_to_conandata={}".format('1' if scm_to_conandata else '0'))
client.save({'conanfile.py': textwrap.dedent("""
from conans import ConanFile
class Recipe(ConanFile):
scm = {"type": "git", "url": "https://github.com/repo/library.git",
"revision": "123456", "shallow": 'None' }
""")})

client.run('export . name/version@', assert_error=True)
assert "ERROR: SCM value for 'shallow' must be of type 'bool' (found 'str')" in str(client.out)


@pytest.mark.tool_git
@parameterized_class([{"shallow": True}, {"shallow": False}, {"shallow": None}, {"shallow": "None"}])
@parameterized_class([{"shallow": True}, {"shallow": False},
{"shallow": None}, # No value written in the recipe
{"shallow": 'None'}]) # Explicit 'None' written in the recipe
class GitShallowTestCase(unittest.TestCase):
conanfile = textwrap.dedent("""
from conans import ConanFile
Expand All @@ -41,7 +60,20 @@ def _shallow_attrib_str(self):
shallow_attrib_str = '"shallow": {}'.format(self.shallow)
return shallow_attrib_str

def test_export(self):
def _check_info_values(self, client):
client.run("inspect {} -a scm".format(self.ref)) # Check we get a loadable conanfile.py
if self.shallow in [None]:
self.assertNotIn('shallow', str(client.out))
elif self.shallow in [True]: # This is the default value
not_appears = 'shallow' not in str(client.out)
value_explicit = 'shallow: True' in str(client.out)
self.assertTrue(not_appears or value_explicit)
elif self.shallow in ['None']:
self.assertIn('shallow: None', str(client.out))
else:
self.assertIn('shallow: False', str(client.out))

def test_export_scm_substituted(self):
# Check the shallow value is substituted with the proper value
client = TestClient()
files = {'conanfile.py': self.conanfile.format(shallow_attrib=self._shallow_attrib_str(),
Expand All @@ -52,12 +84,34 @@ def test_export(self):

client.run("export . {}".format(self.ref))
content = load(client.cache.package_layout(self.ref).conanfile())
if self.shallow in [None, True, "None"]:
if self.shallow in [None, True]:
self.assertNotIn("shallow", content)
elif self.shallow in ['None']:
self.assertIn('"shallow": None', content)
else:
self.assertIn('"shallow": False', content)

client.run("inspect {} -a scm".format(self.ref)) # Check we get a loadable conanfile.py
self._check_info_values(client)

def test_export_scm_to_conandata(self):
# Check the shallow value is stored and propagated with the proper value
client = TestClient()
client.run("config set general.scm_to_conandata=1")
files = {'conanfile.py': self.conanfile.format(shallow_attrib=self._shallow_attrib_str(),
url='auto', rev='auto')}
url, _ = create_local_git_repo(files=files)
client.run_command('git clone "{}" .'.format(url))

client.run("export . {}".format(self.ref))
content = load(os.path.join(client.cache.package_layout(self.ref).export(), DATA_YML))
if self.shallow in [None, True]:
self.assertNotIn('shallow', content)
elif self.shallow in ['None']:
self.assertIn('shallow: null', content)
else:
self.assertIn('shallow: false', content)

self._check_info_values(client)

@parameterized.expand([("c6cc15fa2f4b576bd", False), ("0.22.1", True)])
def test_remote_build(self, revision, shallow_works):
Expand All @@ -70,7 +124,7 @@ def test_remote_build(self, revision, shallow_works):

client.run("create . {}".format(self.ref))

if self.shallow in [None, True, "None"] and shallow_works:
if self.shallow in [None, True] and shallow_works:
self.assertIn(">>> describe-fails", client.out)
else:
self.assertIn(">>> tags: 0.22.1", client.out)
63 changes: 56 additions & 7 deletions conans/test/functional/scm/test_verify_ssl.py
@@ -1,20 +1,39 @@
# coding=utf-8

import os
import textwrap
import unittest

import pytest
from parameterized.parameterized import parameterized_class

from conans.model.ref import ConanFileReference
from conans.test.utils.tools import TestClient
from conans.paths import DATA_YML
from conans.test.utils.scm import create_local_git_repo
from conans.test.utils.tools import TestClient
from conans.util.files import load


@pytest.mark.parametrize("scm_to_conandata", [True, False])
def test_verify_ssl_none_string(scm_to_conandata):
client = TestClient()
client.run("config set general.scm_to_conandata={}".format('1' if scm_to_conandata else '0'))
client.save({'conanfile.py': textwrap.dedent("""
from conans import ConanFile
class Recipe(ConanFile):
scm = {"type": "git", "url": "https://github.com/repo/library.git",
"revision": "123456", "verify_ssl": 'None' }
""")})

client.run('export . name/version@', assert_error=True)
assert "ERROR: SCM value for 'verify_ssl' must be of type " \
"'bool' (found 'str')" in str(client.out)


@pytest.mark.tool_git
@parameterized_class([{"verify_ssl": True}, {"verify_ssl": False},
{"verify_ssl": None},{"verify_ssl": "None"}, ])
{"verify_ssl": None}, # No value written in the recipe
{"verify_ssl": 'None'}]) # Explicit 'None' written in the recipe
class GitVerifySSLTestCase(unittest.TestCase):
conanfile = textwrap.dedent("""
from conans import ConanFile
Expand All @@ -37,13 +56,43 @@ def setUp(self):
url, _ = create_local_git_repo(files=files, commits=4, tags=['v0', ])
self.client.run_command('git clone "{}" .'.format(url))

def test_export(self):
# Check the shallow value is substituted with the proper value
def _check_info_values(self, client):
client.run("inspect {} -a scm".format(self.ref)) # Check we get a loadable conanfile.py
if self.verify_ssl in [None]:
self.assertNotIn('verify_ssl', str(client.out))
elif self.verify_ssl in [True]: # This is the default value
not_appears = 'verify_ssl' not in str(client.out)
value_explicit = 'verify_ssl: True' in str(client.out)
self.assertTrue(not_appears or value_explicit)
elif self.verify_ssl in ['None']:
self.assertIn('verify_ssl: None', str(client.out))
else:
self.assertIn('verify_ssl: False', str(client.out))

def test_export_scm_substituted(self):
# Check the verify_ssl value is substituted with the proper value
self.client.run("config set general.scm_to_conandata=0")
self.client.run("export . {}".format(self.ref))
content = load(self.client.cache.package_layout(self.ref).conanfile())
if self.verify_ssl in [None, True, "None"]:
if self.verify_ssl in [None, True]:
self.assertNotIn("verify_ssl", content)
elif self.verify_ssl in ['None']:
self.assertIn('"verify_ssl": None', content)
else:
self.assertIn('"verify_ssl": False', content)

self.client.run("inspect {} -a scm".format(self.ref)) # Check we get a loadable conanfile.py
self._check_info_values(self.client)

def test_export_scm_to_conandata(self):
# Check the verify_ssl value is stored and propagated with the proper value
self.client.run("config set general.scm_to_conandata=1")
self.client.run("export . {}".format(self.ref))
content = load(os.path.join(self.client.cache.package_layout(self.ref).export(), DATA_YML))
if self.verify_ssl in [None, True]:
self.assertNotIn('verify_ssl', content)
elif self.verify_ssl in ['None']:
self.assertIn('verify_ssl: null', content)
else:
self.assertIn('verify_ssl: false', content)

self._check_info_values(self.client)

0 comments on commit 8c9cf2a

Please sign in to comment.