diff --git a/hooks/conan-center.py b/hooks/conan-center.py index 6de08159..c6a8d518 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-H036": "CUSTOM METHODS", + } class _HooksOutputErrorCollector(object): @@ -318,6 +320,29 @@ def _not_allowed_entries(info, allowed_entries): "conandata.yml" % (entries, version)) return + @run_test("KB-H036", output) + def test(out): + def get_methods(conanfile): + methods = [] + for member in dir(conanfile): + try: + if callable(getattr(conanfile, member)): + methods.append(str(member)) + except: + methods.append(str(member)) + return methods + + mock = ConanFile(conanfile.output, None) + valid_attrs = get_methods(mock) + current_attrs = get_methods(conanfile) + 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 methods must be declared as protected. " \ + "The follow methods 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..c2ecb27f 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 METHODS (KB-H036)] 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 METHODS (KB-H036)] 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 METHODS (KB-H036)] OK", output) def test_conanfile_installer(self): tools.save('conanfile.py', content=self.conanfile_installer) @@ -149,6 +152,7 @@ def test_conanfile_installer(self): "recipe", output) self.assertIn("[META LINES (KB-H025)] OK", output) self.assertIn("[CMAKE MINIMUM VERSION (KB-H028)] OK", output) + self.assertIn("[CUSTOM METHODS (KB-H036)] OK", output) def test_shebang(self): conanfile = textwrap.dedent("""\ @@ -397,3 +401,28 @@ 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_methods(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") + + def configure(self): + self.output.info("ok") + + def barbarian(self): + self.output.info("Conan") + + def my_own_method(self): + self.output.info("foobar") + """) + tools.save('conanfile.py', content=conanfile) + output = self.conan(['create', '.', 'name/version@user/test']) + self.assertIn("ERROR: [CUSTOM METHODS (KB-H036)] Custom methods must be declared as " \ + "protected. The follow methods are invalid: 'barbarian', " \ + "'my_own_method'", output)