From 935e84743def6b24cc7f4c5efd3c15c290e6145f Mon Sep 17 00:00:00 2001 From: Uilian Ries Date: Fri, 1 Nov 2019 08:18:58 -0300 Subject: [PATCH 1/3] #123 Custom attributes must be protected Signed-off-by: Uilian Ries --- hooks/conan-center.py | 19 ++++++++++-- .../conan-center/test_conan-center.py | 30 +++++++++++++++++++ 2 files changed, 47 insertions(+), 2 deletions(-) diff --git a/hooks/conan-center.py b/hooks/conan-center.py index 6de08159..b583c13c 100644 --- a/hooks/conan-center.py +++ b/hooks/conan-center.py @@ -7,7 +7,7 @@ import yaml from logging import WARNING, ERROR, INFO, DEBUG, NOTSET -from conans import tools, Settings +from conans import tools, Settings, ConanFile kb_errors = {"KB-H001": "DEPRECATED GLOBAL CPPSTD", "KB-H002": "REFERENCE LOWERCASE", @@ -37,7 +37,9 @@ "KB-H028": "CMAKE MINIMUM VERSION", "KB-H029": "TEST PACKAGE - RUN ENVIRONMENT", "KB-H030": "CONANDATA.YML FORMAT", - "KB-H031": "CONANDATA.YML REDUCE"} + "KB-H031": "CONANDATA.YML REDUCE", + "KB-H034": "CUSTOM ATTRIBUTES", + } class _HooksOutputErrorCollector(object): @@ -318,6 +320,19 @@ def _not_allowed_entries(info, allowed_entries): "conandata.yml" % (entries, version)) return + @run_test("KB-H034", output) + def test(out): + mock = ConanFile(conanfile.output, None) + valid_attrs = [attr for attr in dir(mock) if not callable(attr)] + ['conan_data', 'python_requires'] + current_attrs = [attr for attr in dir(conanfile) if not callable(attr)] + invalid_attrs = [] + for attr in current_attrs: + if not attr.startswith("_") and attr not in valid_attrs: + invalid_attrs.append(attr) + if invalid_attrs: + out.error("Custom attributes must be declared as protected. " \ + "The follow attributes are invalid: '{}'".format("', '".join(invalid_attrs))) + @raise_if_error_output def post_export(output, conanfile, conanfile_path, reference, **kwargs): diff --git a/tests/test_hooks/conan-center/test_conan-center.py b/tests/test_hooks/conan-center/test_conan-center.py index d02d54ca..812f3ece 100644 --- a/tests/test_hooks/conan-center/test_conan-center.py +++ b/tests/test_hooks/conan-center/test_conan-center.py @@ -88,6 +88,7 @@ def test_conanfile(self): self.assertIn("ERROR: [CONAN CENTER INDEX URL (KB-H027)] The attribute 'url' should " \ "point to: https://github.com/conan-io/conan-center-index", output) self.assertIn("[CMAKE MINIMUM VERSION (KB-H028)] OK", output) + self.assertIn("[CUSTOM ATTRIBUTES (KB-H034)] OK", output) def test_conanfile_header_only(self): tools.save('conanfile.py', content=self.conanfile_header_only) @@ -109,6 +110,7 @@ def test_conanfile_header_only(self): "recipe", output) self.assertIn("[META LINES (KB-H025)] OK", output) self.assertIn("[CMAKE MINIMUM VERSION (KB-H028)] OK", output) + self.assertIn("[CUSTOM ATTRIBUTES (KB-H034)] OK", output) def test_conanfile_header_only_with_settings(self): tools.save('conanfile.py', content=self.conanfile_header_only_with_settings) @@ -129,6 +131,7 @@ def test_conanfile_header_only_with_settings(self): "recipe", output) self.assertIn("[META LINES (KB-H025)] OK", output) self.assertIn("[CMAKE MINIMUM VERSION (KB-H028)] OK", output) + self.assertIn("[CUSTOM ATTRIBUTES (KB-H034)] OK", output) def test_conanfile_installer(self): tools.save('conanfile.py', content=self.conanfile_installer) @@ -397,3 +400,30 @@ def test_cmake_minimum_version(self): self.assertIn("ERROR: [CMAKE MINIMUM VERSION (KB-H028)] The CMake file '%s' must contain a " "minimum version declared (e.g. cmake_minimum_required(VERSION 3.1.2))" % path, output) + + def test_invalid_recipe_attributes(self): + conanfile = textwrap.dedent("""\ + from conans import ConanFile + + class AConan(ConanFile): + url = "fake_url.com" + license = "fake_license" + description = "whatever" + homepage = "homepage.com" + topics = ("fake_topic", "another_fake_topic") + exports_sources = "header.h" + options = {"foo": [True, False], "bar": [True, False]} + default_options = {"foo": False, "bar": True} + _source_subfolder = "source_subfolder" + _build_subfolder = "build_subfolder" + foobar = "package" + package_subfolder = "package" + + def package(self): + self.copy("*", dst="include") + """) + tools.save('conanfile.py', content=conanfile) + output = self.conan(['create', '.', 'name/version@user/test']) + self.assertIn("ERROR: [CUSTOM ATTRIBUTES (KB-H034)] Custom attributes must be declared " \ + "as protected. The follow attributes are invalid: 'foobar', " \ + "'package_subfolder'", output) From 754b2ef578129f36a2030748cf59c12f30fef21a Mon Sep 17 00:00:00 2001 From: Uilian Ries Date: Fri, 1 Nov 2019 09:54:39 -0300 Subject: [PATCH 2/3] #123 Update KB number to 35 Signed-off-by: Uilian Ries --- hooks/conan-center.py | 4 ++-- tests/test_hooks/conan-center/test_conan-center.py | 8 ++++---- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/hooks/conan-center.py b/hooks/conan-center.py index b583c13c..3dbcfb68 100644 --- a/hooks/conan-center.py +++ b/hooks/conan-center.py @@ -38,7 +38,7 @@ "KB-H029": "TEST PACKAGE - RUN ENVIRONMENT", "KB-H030": "CONANDATA.YML FORMAT", "KB-H031": "CONANDATA.YML REDUCE", - "KB-H034": "CUSTOM ATTRIBUTES", + "KB-H035": "CUSTOM ATTRIBUTES", } @@ -320,7 +320,7 @@ def _not_allowed_entries(info, allowed_entries): "conandata.yml" % (entries, version)) return - @run_test("KB-H034", output) + @run_test("KB-H035", output) def test(out): mock = ConanFile(conanfile.output, None) valid_attrs = [attr for attr in dir(mock) if not callable(attr)] + ['conan_data', 'python_requires'] diff --git a/tests/test_hooks/conan-center/test_conan-center.py b/tests/test_hooks/conan-center/test_conan-center.py index 812f3ece..4b4e0319 100644 --- a/tests/test_hooks/conan-center/test_conan-center.py +++ b/tests/test_hooks/conan-center/test_conan-center.py @@ -88,7 +88,7 @@ def test_conanfile(self): self.assertIn("ERROR: [CONAN CENTER INDEX URL (KB-H027)] The attribute 'url' should " \ "point to: https://github.com/conan-io/conan-center-index", output) self.assertIn("[CMAKE MINIMUM VERSION (KB-H028)] OK", output) - self.assertIn("[CUSTOM ATTRIBUTES (KB-H034)] OK", output) + self.assertIn("[CUSTOM ATTRIBUTES (KB-H035)] OK", output) def test_conanfile_header_only(self): tools.save('conanfile.py', content=self.conanfile_header_only) @@ -110,7 +110,7 @@ def test_conanfile_header_only(self): "recipe", output) self.assertIn("[META LINES (KB-H025)] OK", output) self.assertIn("[CMAKE MINIMUM VERSION (KB-H028)] OK", output) - self.assertIn("[CUSTOM ATTRIBUTES (KB-H034)] OK", output) + self.assertIn("[CUSTOM ATTRIBUTES (KB-H035)] OK", output) def test_conanfile_header_only_with_settings(self): tools.save('conanfile.py', content=self.conanfile_header_only_with_settings) @@ -131,7 +131,7 @@ def test_conanfile_header_only_with_settings(self): "recipe", output) self.assertIn("[META LINES (KB-H025)] OK", output) self.assertIn("[CMAKE MINIMUM VERSION (KB-H028)] OK", output) - self.assertIn("[CUSTOM ATTRIBUTES (KB-H034)] OK", output) + self.assertIn("[CUSTOM ATTRIBUTES (KB-H035)] OK", output) def test_conanfile_installer(self): tools.save('conanfile.py', content=self.conanfile_installer) @@ -424,6 +424,6 @@ def package(self): """) tools.save('conanfile.py', content=conanfile) output = self.conan(['create', '.', 'name/version@user/test']) - self.assertIn("ERROR: [CUSTOM ATTRIBUTES (KB-H034)] Custom attributes must be declared " \ + self.assertIn("ERROR: [CUSTOM ATTRIBUTES (KB-H035)] Custom attributes must be declared " \ "as protected. The follow attributes are invalid: 'foobar', " \ "'package_subfolder'", output) From e96ab92e7294acabd25ca40f8f6768856525ed6d Mon Sep 17 00:00:00 2001 From: Uilian Ries Date: Fri, 1 Nov 2019 15:33:43 -0300 Subject: [PATCH 3/3] #123 Dont accept private members Signed-off-by: Uilian Ries --- hooks/conan-center.py | 2 +- .../test_hooks/conan-center/test_conan-center.py | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/hooks/conan-center.py b/hooks/conan-center.py index 3dbcfb68..60c617cf 100644 --- a/hooks/conan-center.py +++ b/hooks/conan-center.py @@ -325,7 +325,7 @@ def test(out): mock = ConanFile(conanfile.output, None) valid_attrs = [attr for attr in dir(mock) if not callable(attr)] + ['conan_data', 'python_requires'] current_attrs = [attr for attr in dir(conanfile) if not callable(attr)] - invalid_attrs = [] + invalid_attrs = re.findall(r"(__.*)\s?=", conanfile_content, re.MULTILINE) for attr in current_attrs: if not attr.startswith("_") and attr not in valid_attrs: invalid_attrs.append(attr) diff --git a/tests/test_hooks/conan-center/test_conan-center.py b/tests/test_hooks/conan-center/test_conan-center.py index 4b4e0319..b7dcf481 100644 --- a/tests/test_hooks/conan-center/test_conan-center.py +++ b/tests/test_hooks/conan-center/test_conan-center.py @@ -416,14 +416,23 @@ class AConan(ConanFile): default_options = {"foo": False, "bar": True} _source_subfolder = "source_subfolder" _build_subfolder = "build_subfolder" + __my_private = "secret" + __attribute__ = "foobar" + __qux= "baz" foobar = "package" package_subfolder = "package" def package(self): self.copy("*", dst="include") + + def _foobar(self): + pass + + def __private(self): + pass """) tools.save('conanfile.py', content=conanfile) output = self.conan(['create', '.', 'name/version@user/test']) - self.assertIn("ERROR: [CUSTOM ATTRIBUTES (KB-H035)] Custom attributes must be declared " \ - "as protected. The follow attributes are invalid: 'foobar', " \ - "'package_subfolder'", output) + self.assertIn("ERROR: [CUSTOM ATTRIBUTES (KB-H035)] Custom attributes must be declared as " + "protected. The follow attributes are invalid: '__my_private ', " + "'__attribute__ ', '__qux', 'foobar', 'package_subfolder'", output)