From 5c32f2a0bec109615c6362a136f61a25154bc3d7 Mon Sep 17 00:00:00 2001 From: Uilian Ries Date: Fri, 20 Sep 2024 09:01:43 +0200 Subject: [PATCH] (#25329) Remove Linter v2 migration Signed-off-by: Uilian Ries --- .github/workflows/linter-conan-v2.yml | 124 ---------------------- docs/linters.md | 82 +------------- docs/v2_migration.md | 147 -------------------------- linter/check_import_tools.py | 30 ------ linter/check_layout_src_folder.py | 44 -------- linter/check_package_name.py | 44 -------- linter/check_version_attribute.py | 33 ------ linter/conanv2_transition.py | 18 ---- 8 files changed, 1 insertion(+), 521 deletions(-) delete mode 100644 .github/workflows/linter-conan-v2.yml delete mode 100644 docs/v2_migration.md delete mode 100644 linter/check_import_tools.py delete mode 100644 linter/check_layout_src_folder.py delete mode 100644 linter/check_package_name.py delete mode 100644 linter/check_version_attribute.py delete mode 100644 linter/conanv2_transition.py diff --git a/.github/workflows/linter-conan-v2.yml b/.github/workflows/linter-conan-v2.yml deleted file mode 100644 index 769623eebf2c9..0000000000000 --- a/.github/workflows/linter-conan-v2.yml +++ /dev/null @@ -1,124 +0,0 @@ -name: "[linter] Conan v2 migration" - -on: - pull_request: - -env: - PYTHONPATH: ${{github.workspace}} - PYVER: "3.8" - REQUIREMENTS: "pylint==2.14" - -jobs: - test_linter: - name: Test linter changes (v2 migration) - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Get changed files - uses: ./.github/actions/pr_changed_files - id: changed_files - with: - files: | - linter/** - .github/workflows/linter-conan-v2.yml - - - name: Get Conan v2 version - id: parse_conan_v2_version - if: steps.changed_files.outputs.any_changed == 'true' - uses: mikefarah/yq@master - with: - cmd: yq '.conan.version' '.c3i/config_v2.yml' - - - uses: actions/setup-python@v4 - if: steps.changed_files.outputs.any_changed == 'true' - with: - python-version: ${{ env.PYVER }} - - - name: Install requirements - if: steps.changed_files.outputs.any_changed == 'true' - run: | - pip install ${{ env.REQUIREMENTS }} conan==${{ steps.parse_conan_v2_version.outputs.result }} - - - name: Execute linter over all recipes in the repository - id: linter_recipes - if: steps.changed_files.outputs.any_changed == 'true' - run: | - echo '## Linter summary (recipes)' >> $GITHUB_STEP_SUMMARY - pylint --rcfile=linter/pylintrc_recipe `ls recipes/*/*/conanfile.py | shuf -n 500` --output-format=json --output=recipes.json --score=y --exit-zero - jq '[map( select(.type=="error")) | group_by (.message)[] | {message: .[0].message, length: length}] | sort_by(.length) | reverse' recipes.json > recipes2.json - jq -r '.[] | " * \(.message): \(.length)"' recipes2.json >> $GITHUB_STEP_SUMMARY - - - name: Execute linter over all test_package/recipes in the repository - id: linter_test_package - if: steps.changed_files.outputs.any_changed == 'true' - run: | - echo '## Linter summary (test_package)' >> $GITHUB_STEP_SUMMARY - pylint --rcfile=linter/pylintrc_testpackage `ls recipes/*/*/test_package/conanfile.py | shuf -n 500` --output-format=json --output=recipes.json --exit-zero - jq '[map( select(.type=="error")) | group_by (.message)[] | {message: .[0].message, length: length}] | sort_by(.length) | reverse' recipes.json > recipes2.json - jq -r '.[] | " * \(.message): \(.length)"' recipes2.json >> $GITHUB_STEP_SUMMARY - - conanfile_recipe: - name: Lint changed conanfile.py (v2 migration) - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Get changed files - id: changed-files - uses: ./.github/actions/pr_changed_files - with: - files: | - recipes/*/*/conanfile.py - - name: Get Conan v2 version - id: parse_conan_v2_version - if: steps.changed-files.outputs.any_changed == 'true' - uses: mikefarah/yq@master - with: - cmd: yq '.conan.version' '.c3i/config_v2.yml' - - uses: actions/setup-python@v4 - if: steps.changed-files.outputs.any_changed == 'true' - with: - python-version: ${{ env.PYVER }} - - name: Install dependencies - if: steps.changed-files.outputs.any_changed == 'true' - run: | - pip install ${{ env.REQUIREMENTS }} conan==${{ steps.parse_conan_v2_version.outputs.result }} - - name: Run linter - if: steps.changed-files.outputs.any_changed == 'true' - run: | - echo "::add-matcher::linter/recipe_linter.json" - for file in ${{ steps.changed-files.outputs.all_changed_files }}; do - pylint --rcfile=linter/pylintrc_recipe --output-format=parseable ${file} - done - - conanfile_test_package: - name: Lint changed test_package/conanfile.py (v2 migration) - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Get changed files - id: changed-files - uses: ./.github/actions/pr_changed_files - with: - files: | - recipes/*/*/test_*/conanfile.py - - name: Get Conan v2 version - id: parse_conan_v2_version - if: steps.changed-files.outputs.any_changed == 'true' - uses: mikefarah/yq@master - with: - cmd: yq '.conan.version' '.c3i/config_v2.yml' - - uses: actions/setup-python@v4 - if: steps.changed-files.outputs.any_changed == 'true' - with: - python-version: ${{ env.PYVER }} - - name: Install dependencies - if: steps.changed-files.outputs.any_changed == 'true' - run: | - pip install ${{ env.REQUIREMENTS }} conan==${{ steps.parse_conan_v2_version.outputs.result }} - - name: Run linter - if: steps.changed-files.outputs.any_changed == 'true' - run: | - echo "::add-matcher::linter/recipe_linter.json" - for file in ${{ steps.changed-files.outputs.all_changed_files }}; do - pylint --rcfile=linter/pylintrc_testpackage --ignore-paths="recipes/[^/]*/[^/]*/test_v2[^/]*/conanfile.py" --output-format=parseable ${file} - done diff --git a/docs/linters.md b/docs/linters.md index 1a76e25288b80..e9e0c601fe0fc 100644 --- a/docs/linters.md +++ b/docs/linters.md @@ -15,11 +15,7 @@ to configure plugins, warnings and errors which should be enabled or disabled. * [Understanding the different linters](#understanding-the-different-linters) * [Running the linters locally](#running-the-linters-locally) * [Pylint configuration files](#pylint-configuration-files) - * [Linter Warning and Errors](#linter-warning-and-errors) - * [E9005 - conan-missing-name: Every conan recipe must contain the attribute name](#e9005---conan-missing-name-every-conan-recipe-must-contain-the-attribute-name) - * [E9007 - conan-test-no-name: Do not add name attribute in test package recipes](#e9007---conan-test-no-name-do-not-add-name-attribute-in-test-package-recipes) - * [E9011 - conan-import-tools: Importing conan.tools or conan.tools.xxx.zzz.yyy should be considered as private](#e9011---conan-import-tools-importing-conantools-or-conantoolsxxxzzzyyy-should-be-considered-as-private) - * [E9012 - conan-attr-version: Recipe should not contain version attribute](#e9012---conan-attr-version-recipe-should-not-contain-version-attribute) + ## Understanding the different linters @@ -37,79 +33,3 @@ Check the [Developing Recipes](developing_recipes_locally.md) for more informati - [Pylint Recipe](../linter/pylintrc_recipe): This `rcfile` lists plugins and rules to be executed over all recipes (not test package) and validate them. - [Pylint Test Package Recipe](../linter/pylintrc_testpackage): This `rcfile` lists plugins and rules to be executed over all recipes in test package folders only: - -## Linter Warning and Errors - -Here is the list of current warning and errors provided by pylint, when using CCI configuration. - -### E9005 - conan-missing-name: Every conan recipe must contain the attribute name - -The attribute `name` is always expected. On the other hand, `version` should not be listed. - -```python -def BazConanfile(ConanFile): - name = "baz" -``` - -### E9007 - conan-test-no-name: Do not add name attribute in test package recipes - -The test package is not a recipe, thus, it should not have a name - -```python -def TestPackageConanFile(ConanFile): - name = "test_package" # Wrong! -``` - -### E9011 - conan-import-tools: Importing conan.tools or conan.tools.xxx.zzz.yyy should be considered as private - -Documented on [conanfile.tools](https://docs.conan.io/1/reference/conanfile/tools.html): -It's not allowed to use `tools.xxx` directly: - -```python -from conan import tools -... - -tools.scm.Version(self.version) -``` - -Neither sub modules: - -```python -from conan.tools.apple.apple import is_apple_os -``` - -Only modules under `conan.tools` and `conan.tools.xxx` are allowed: - -```python -from conan.tools.files import rmdir -from conan.tools import scm -``` - -### E9012 - conan-attr-version: Recipe should not contain version attribute - -All recipes on CCI should be generic enough to support as many versions as possible, so enforcing a specific -version as attribute will not allow to re-use the same recipe for multiple release versions. - -```python -from conan import ConanFile - -class FooConanFile(ConanFile): - version = "1.0.0" # Wrong! -``` - -The package version should be passed as command argument, e.g: - - conan create all/ 1.0.0@ -pr:h=default -pr:b=default - -Or, if you are running Conan 2.0: - - conan create all/ --version=1.0.0 -pr:h=default -pr:b=default - -The only exception is when providing ``system`` packages, which are allowed. - -```python -from conan import ConanFile - -class FooConanFile(ConanFile): - version = "system" # Okay! -``` diff --git a/docs/v2_migration.md b/docs/v2_migration.md deleted file mode 100644 index d372401b811e0..0000000000000 --- a/docs/v2_migration.md +++ /dev/null @@ -1,147 +0,0 @@ -# Preparing recipes for Conan 2.0 - -This is expected for recipes to be updates in each pull request. - -- Updated helpers are expected, this is enforced by the [v2_linter](v2_linter.md) -- Once a recipe publishes v2 packages, it must pass the v2 pipeline always. -- The v2 pipeline with **is required** for changes to be merged. - - -## Contents - - * [Using Layout](#using-layout) - * [With New Generators](#with-new-generators) - * [With Multiple Build Helpers](#with-multiple-build-helpers) - * [CMakeToolchain](#cmaketoolchain) - * [New conf_info properties](#new-conf_info-properties) - * [New cpp_info set_property model](#new-cpp_info-set_property-model) - * [Translating .names information to cmake_target_name, cmake_module_target_name and cmake_file_name](#translating-names-information-to-cmake_target_name-cmake_module_target_name-and-cmake_file_name) - * [Translating .filenames information to cmake_file_name, cmake_module_file_name and cmake_find_mode](#translating-filenames-information-to-cmake_file_name-cmake_module_file_name-and-cmake_find_mode) - * [Translating .build_modules to cmake_build_modules](#translating-build_modules-to-cmake_build_modules) - * [PkgConfigDeps](#pkgconfigdeps) - -> **Note**: Read about the [linter in pull requests](v2_linter.md) to learn how this is being enforced. - -It's time to start thinking seriously about Conan v2 and prepare recipes -for the incoming changes. Conan v2 comes with many -changes and improvements, you can read about them in the -[Conan documentation](https://docs.conan.io/1/conan_v2.html). - -This document is a practical guide, offering extended information particular to Conan -Center Index recipes to get them ready to upgrade to Conan 2.0. - -## Using Layout - -All recipes should use a layout. Without one, more manual configuration of folders (e.g. source, build, etc) -and package structure will be required. - -### With New Generators - -When doing this there is no need to manually define `self._subfolder_[...]` in a recipe. -Simply use `self.source_folder` and `self.build_folder` instead of "subfolder properties" that used to be the norm. - -### With Multiple Build Helpers - -When different build tools are use, at least one layout needs to be set. - -```python - def layout(self): - if self._use_cmake(): - cmake_layout(self) - else: # using autotools - basic_layout(self) -``` - -The `src_folder` must be the same when using different layouts and should -not depend on settings or options. - -## CMakeToolchain - -The old `CMake.definition` should be replaced by `CMakeToolchain.variables` and moved to the `generate` method. -However, certain options need to be passed as `cache_variables`. You'll need to check project's `CMakeLists.txt` -as there are a few cases to look out for: - -- When an `option` is configured before `project()` is called. - - ```cmake - cmake_minimum_required(3.1) - option(BUILD_EXAMPLES "Build examples using foorbar") - project(foobar) - ``` - -- When an variable is declared with `CACHE`. - - ```cmake - cmake_minimum_required(3.1) - project(foobar) - set(USE_JPEG ON CACHE BOOL "include jpeg support?") - ``` - -For more information refere to the [CMakeToolchain docs](https://docs.conan.io/1/reference/conanfile/tools/cmake/cmaketoolchain.html) -or check out the converstaion in conan-io/conan#11937 for the brave. - -## New conf_info properties - -As described in the documentation `self.user_info` has been depreated and you are now required to use -`self.conf_info` to define individual properties to expose to downstream recipes. -The [2.0 migrations docs](https://docs.conan.io/1/migrating_to_2.0/recipes.html#removed-self-user-info) -should cover the technical details, however for ConanCenterIndex we need to make sure there are no collisions -`conf_info` must be named `user.:`. - -For usage options of `conf_info`, the [documenation](https://docs.conan.io/1/reference/config_files/global_conf.html?highlight=conf_info#configuration-in-your-recipes) - -In ConanCenterIndex this will typically looks like: - -- defining a value - ```py - def package_info(self): - tool_path = os.path.join(self.package_folder, "bin", "tool") - self.conf_info.define("user.pkg:tool", tool_path) - ``` -- using a value - ```py - #generators = "VirtualBuildEnv", "VirtualRunEnv" - - def build_requirements(self): - self.tool_requires("tool/0.1") - - def build(self): - tool_path = self.conf_info.get("user.pkg:tool") - self.run(f"{tool_path} --build") - ``` - -> **Note**: This should only be used when absolutely required. In the vast majority of cases, the new -> ["Environments"](https://docs.conan.io/1/reference/conanfile/tools/env/environment.html?highlight=Virtual) -> will include the `self.cpp_info.bindirs` which will provide access to the tools in the correct scopes. - -## New cpp_info set_property model - -New Conan generators like -[CMakeDeps](https://docs.conan.io/1/reference/conanfile/tools/cmake/cmakedeps.html) -and -[PkgConfigDeps](https://docs.conan.io/1/reference/conanfile/tools/gnu/pkgconfigdeps.html), -don't listen to `cpp_info`'s ``.names``, ``.filenames`` or ``.build_modules`` attributes. -There is a new way of setting the `cpp_info` information with these -generators using the ``set_property(property_name, value)`` method. - -Both of these two models **will live together in recipes** to make -recipes compatible for both 1.x and 2.0 users. Deprecated feilds are not to be removed at this time. - -To understand the impact of these and the relation between different generates, refer to the -[migrating properties](https://docs.conan.io/1/migrating_to_2.0/properties.html) documentation. - -### Translating .names information to cmake_target_name, cmake_module_target_name and cmake_file_name - -The variation of `names` is covered by the [Conan documentation](https://docs.conan.io/1/migrating_to_2.0/properties.html#migrating-from-names-to-cmake-target-name). - -### Translating .filenames information to cmake_file_name, cmake_module_file_name and cmake_find_mode - -As for `filenames`, refer to [this section](https://docs.conan.io/1/migrating_to_2.0/properties.html#migrating-from-filenames-to-cmake-file-name). - -### Translating .build_modules to cmake_build_modules - -The variation of `build_modules` is covered by the [Conan documentation](https://docs.conan.io/1/migrating_to_2.0/properties.html#translating-build-modules-to-cmake-build-modules). - -### PkgConfigDeps - -For migrating, `names` used with `pkg_config`, see [Conan documentation](https://docs.conan.io/1/migrating_to_2.0/properties.html#migration-from-names-to-pkg-config-name) diff --git a/linter/check_import_tools.py b/linter/check_import_tools.py deleted file mode 100644 index 1621c7b3dfd2a..0000000000000 --- a/linter/check_import_tools.py +++ /dev/null @@ -1,30 +0,0 @@ -import re -from email.mime import base -from pylint.checkers import BaseChecker -from pylint.interfaces import IAstroidChecker -from astroid import nodes, Const, AssignName - - -class ImportTools(BaseChecker): - """ - Import tools following pattern 'from conan.tools.xxxx import yyyyy' - """ - - __implements__ = IAstroidChecker - - name = "conan-import-tools" - msgs = { - "E9011": ( - "Import tools following pattern 'from conan.tools.xxxx import yyyyy' (https://docs.conan.io/en/latest/reference/conanfile/tools.html).", - "conan-import-tools", - "Import tools following pattern 'from conan.tools.xxxx import yyyyy' (https://docs.conan.io/en/latest/reference/conanfile/tools.html).", - ), - } - - def visit_importfrom(self, node: nodes.ImportFrom) -> None: - basename = node.modname - names = [name for name, _ in node.names] - if basename == 'conan' and 'tools' in names: - self.add_message("conan-import-tools", node=node) - elif re.match(r'conan\.tools\.[^.]+\..+', basename): - self.add_message("conan-import-tools", node=node) diff --git a/linter/check_layout_src_folder.py b/linter/check_layout_src_folder.py deleted file mode 100644 index b7d418884ca45..0000000000000 --- a/linter/check_layout_src_folder.py +++ /dev/null @@ -1,44 +0,0 @@ -from pylint.checkers import BaseChecker -from pylint.interfaces import IAstroidChecker -from astroid import nodes - -WHY_SRC_FOLDER = "Setting the `src_folder` for layouts will help keep an organized and clean workspace when developing recipes locally. " \ - "The extra folder will help ensure there are no collisions between the upstream sources and recipe's exports - which " \ - "also extends to what happens in the cache when creating packages" - - -class LayoutSrcFolder(BaseChecker): - """ - Ensure `src_folder=src` when using built-in layouts - """ - - __implements__ = IAstroidChecker - - name = "conan-layout-src-folder" - msgs = { - "E9012": ( - "layout is missing `src_folder` argument which should be to `src`", - "conan-missing-layout-src-folder", - WHY_SRC_FOLDER, - ), - "E9013": ( - "layout should set `src_folder` to `src`", - "conan-layout-src-folder-is-src", - WHY_SRC_FOLDER, - ), - } - - def visit_call(self, node: nodes.Call) -> None: - if not isinstance(node.func, nodes.Name): - return - - if node.func.name in ["cmake_layout", "bazel_layout", "basic_layout"]: - for kw in node.keywords: - if kw.arg == "src_folder": - if not kw.value or kw.value.as_string().strip("\"'") != "src": - self.add_message( - "conan-layout-src-folder-is-src", node=node, line=node.lineno - ) - break - else: - self.add_message("conan-missing-layout-src-folder", node=node, line=node.lineno) diff --git a/linter/check_package_name.py b/linter/check_package_name.py deleted file mode 100644 index fcc8f60447a9b..0000000000000 --- a/linter/check_package_name.py +++ /dev/null @@ -1,44 +0,0 @@ -from pylint.checkers import BaseChecker -from pylint.interfaces import IAstroidChecker -from astroid import nodes, Const, AssignName -from pathlib import Path - - -class PackageName(BaseChecker): - """ - All packages must have a lower-case name - """ - - __implements__ = IAstroidChecker - - name = "conan-package-name" - msgs = { - "E9005": ( - "Missing name attribute", - "conan-missing-name", - "The member attribute `name` must be declared: `name = 'foobar'`." - ), - "E9007": ( - "No 'name' attribute in test_package conanfile", - "conan-test-no-name", - "No 'name' attribute in test_package conanfile." - ), - } - - def visit_classdef(self, node: nodes) -> None: - filename = Path(node.root().file) - is_test = filename.match('test_*/*.py') - - if node.basenames == ['ConanFile']: - for attr in node.body: - children = list(attr.get_children()) - if len(children) == 2 and \ - isinstance(children[0], AssignName) and \ - children[0].name == "name" and \ - isinstance(children[1], Const): - if is_test: - self.add_message("conan-test-no-name", node=attr, line=attr.lineno) - return - return - if not is_test: - self.add_message("conan-missing-name", node=node) diff --git a/linter/check_version_attribute.py b/linter/check_version_attribute.py deleted file mode 100644 index 66e61f47ef183..0000000000000 --- a/linter/check_version_attribute.py +++ /dev/null @@ -1,33 +0,0 @@ -from pylint.checkers import BaseChecker -from pylint.interfaces import IAstroidChecker -from astroid import nodes, Const, AssignName - - -class VersionAttribute(BaseChecker): - """ - All packages should not enforce a specific version in the recipe - """ - - __implements__ = IAstroidChecker - - name = "conan-attr-version" - msgs = { - "E9014": ( - "Recipe should not contain version attribute", - "conan-forced-version", - "Do not enforce a specific version in your recipe. Keep it generic for any version." - ), - } - - def visit_classdef(self, node: nodes) -> None: - if node.basenames == ['ConanFile']: - for attr in node.body: - children = list(attr.get_children()) - if len(children) == 2 and \ - isinstance(children[0], AssignName) and \ - children[0].name == "version" and \ - isinstance(children[1], Const): - value = children[1].as_string().replace('"', "").replace("'", "") - if value and value != "system": - self.add_message("conan-forced-version", node=attr, line=attr.lineno) - return diff --git a/linter/conanv2_transition.py b/linter/conanv2_transition.py deleted file mode 100644 index 32fbb30499363..0000000000000 --- a/linter/conanv2_transition.py +++ /dev/null @@ -1,18 +0,0 @@ -""" - -Pylint plugin/rules for conanfiles in Conan Center Index - -""" - -from pylint.lint import PyLinter -from linter.check_package_name import PackageName -from linter.check_import_tools import ImportTools -from linter.check_layout_src_folder import LayoutSrcFolder -from linter.check_version_attribute import VersionAttribute - - -def register(linter: PyLinter) -> None: - linter.register_checker(PackageName(linter)) - linter.register_checker(ImportTools(linter)) - linter.register_checker(LayoutSrcFolder(linter)) - linter.register_checker(VersionAttribute(linter))