Repository: conda-incubator/grayskull
Pull request #410 (2022-10-28 22:06:11)

Add Python 3.11 to the matrix of tests


Patch:
diff --git a/grayskull/__main__.py b/grayskull/__main__.py
index cb2b416..908acf7 100644
--- a/grayskull/__main__.py
+++ b/grayskull/__main__.py
@@ -168,6 +168,13 @@ def main(args=None):
         help="Create a separate conda package for each extra requirements."
         " Ignored when no extra requirements are selected.",
     )
+    pypi_cmds.add_argument(
+        "--licence-exclude-folders",
+        default=tuple(),
+        nargs="*",
+        dest="licence_exclude_folders",
+        help="Exclude folders when searching for licence.",
+    )
 
     args = parser.parse_args(args)
 
@@ -225,6 +232,7 @@ def generate_recipes_from_list(list_pkgs, args):
                 extras_require_exclude=tuple(args.extras_require_exclude),
                 extras_require_all=args.extras_require_all,
                 extras_require_split=args.extras_require_split,
+                licence_exclude_folders=args.licence_exclude_folders,
             )
         except requests.exceptions.HTTPError as err:
             print_msg(f"{Fore.RED}Package seems to be missing.\nException: {err}\n\n")
diff --git a/grayskull/config.py b/grayskull/config.py
index 1d80625..5ed4c46 100644
--- a/grayskull/config.py
+++ b/grayskull/config.py
@@ -47,6 +47,7 @@ class Configuration:
     extras_require_exclude: Tuple[str] = tuple()
     extras_require_all: bool = False
     extras_require_split: bool = False
+    licence_exclude_folders: Tuple[str] = tuple()
 
     def get_oldest_py3_version(self, list_py_ver: List[PyVer]) -> PyVer:
         list_py_ver = sorted(list_py_ver)
diff --git a/grayskull/license/discovery.py b/grayskull/license/discovery.py
index 0aa1525..ae95d00 100644
--- a/grayskull/license/discovery.py
+++ b/grayskull/license/discovery.py
@@ -9,7 +9,7 @@ from operator import itemgetter
 from pathlib import Path
 from subprocess import check_output
 from tempfile import mkdtemp
-from typing import List, Optional, Union
+from typing import List, Optional, Tuple, Union
 
 import requests
 from colorama import Fore
@@ -183,6 +183,7 @@ def search_license_file(
     git_url: Optional[str] = None,
     version: Optional[str] = None,
     license_name_metadata: Optional[str] = None,
+    folders_exclude_search: Tuple[str] = tuple(),
 ) -> List[ShortLicense]:
     """Search for the license file. First it will try to find it in the given
     folder, after that it will search on the github api and for the last it will
@@ -197,7 +198,9 @@ def search_license_file(
     if license_name_metadata:
         license_name_metadata = get_short_license_id(license_name_metadata)
 
-    all_license_sdist = search_license_folder(folder_path, license_name_metadata)
+    all_license_sdist = search_license_folder(
+        folder_path, license_name_metadata, folders_exclude_search
+    )
     for license_sdist in all_license_sdist:
         license_sdist.is_packaged = True
         license_sdist.path = os.path.relpath(license_sdist.path, folder_path)
@@ -216,7 +219,9 @@ def search_license_file(
     if github_license:
         return [github_license]
 
-    repo_license = search_license_repo(git_url, version, license_name_metadata)
+    repo_license = search_license_repo(
+        git_url, version, license_name_metadata, folders_exclude_search
+    )
     if repo_license:
         return repo_license
     return [ShortLicense(license_name_metadata, None, False)]
@@ -269,7 +274,9 @@ def _get_api_github_url(github_url: str, version: Optional[str] = None) -> str:
 
 
 def search_license_folder(
-    path: Union[str, Path], default: Optional[str] = None
+    path: Union[str, Path],
+    default: Optional[str] = None,
+    folders_exclude_search: Tuple[str] = tuple(),
 ) -> List[ShortLicense]:
     """Search for the license in the given folder
 
@@ -277,6 +284,9 @@ def search_license_folder(
     :param default: Default value for the license type
     :return: License information
     """
+    folders_exclude_search = set(
+        list(folders_exclude_search) + ["doc", "theme", "themes", "docs"]
+    )
     re_search = re.compile(
         r"(\bcopyright\b|\bnotice\b|\blicense[s]*\b|\bcopying\b|\bcopyleft\b)",
         re.IGNORECASE,
@@ -286,8 +296,7 @@ def search_license_folder(
         dirnames[:] = [
             folder
             for folder in dirnames
-            if folder not in ("doc", "theme", "themes", "docs")
-            and not folder.startswith(".")
+            if folder not in folders_exclude_search and not folder.startswith(".")
         ]
         for one_file in filenames:
             if re_search.match(one_file):
@@ -299,13 +308,17 @@ def search_license_folder(
 
 
 def search_license_repo(
-    git_url: str, version: Optional[str], default: Optional[str] = None
+    git_url: str,
+    version: Optional[str],
+    default: Optional[str] = None,
+    folders_exclude_search: Tuple[str] = tuple(),
 ) -> Optional[List[ShortLicense]]:
     """Search for the license file in the given github repository
 
     :param git_url: GitHub URL
     :param version: Package version
     :param default: Default value for the license type
+    :param folders_exclude_search: Folders names to be excluded from search for licences
     :return: License information
     """
     git_url = re.sub(r"/$", ".git", git_url)
@@ -320,9 +333,13 @@ def search_license_repo(
             f" url: {git_url}, version: {version}. Exception: {err}"
         )
         if not version.startswith("v"):
-            return search_license_repo(git_url, f"v{version}", default)
+            return search_license_repo(
+                git_url, f"v{version}", default, folders_exclude_search
+            )
         return None
-    return search_license_folder(str(tmp_dir), default)
+    return search_license_folder(
+        str(tmp_dir), default, folders_exclude_search=folders_exclude_search
+    )
 
 
 def _get_git_cmd(git_url: str, version: str, dest) -> List[str]:


Test patch:
diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml
index b6d8828..132fb48 100644
--- a/.github/workflows/tests.yml
+++ b/.github/workflows/tests.yml
@@ -14,7 +14,7 @@ jobs:
     strategy:
       matrix:
         os: [ubuntu-latest]
-        py_ver: ["3.8", "3.9", "3.10"]
+        py_ver: ["3.8", "3.9", "3.10", "3.11"]
     env:
       OS: ${{ matrix.os }}
       PYTHON: ${{ matrix.py_ver }}
diff --git a/tests/cli/test_cli_cmds.py b/tests/cli/test_cli_cmds.py
index 08fa7b2..54d478f 100644
--- a/tests/cli/test_cli_cmds.py
+++ b/tests/cli/test_cli_cmds.py
@@ -85,6 +85,7 @@ def test_change_pypi_url(mocker):
         extras_require_exclude=tuple(),
         extras_require_all=False,
         extras_require_split=False,
+        licence_exclude_folders=tuple(),
     )
 
 
diff --git a/tests/license/test_discovery.py b/tests/license/test_discovery.py
index f8d9df0..861badf 100644
--- a/tests/license/test_discovery.py
+++ b/tests/license/test_discovery.py
@@ -139,6 +139,24 @@ def test_search_license_folder_hidden_folder(tmp_path, license_pytest_5_3_1):
     assert all_licenses[0].path == str(license_path)
 
 
+def test_search_licence_exclude_folders(tmp_path, license_pytest_5_3_1):
+    folder = tmp_path / "location-exclude-folder"
+    folder.mkdir()
+    folder_exclude = folder / "folder_exclude"
+    folder_exclude.mkdir()
+    (folder_exclude / "LICENSE").write_text("LICENCE TO EXCLUDE")
+    folder_search = folder / "folder_search"
+    folder_search.mkdir()
+    (folder_search / "LICENSE").write_text("LICENCE TO BE FOUND")
+    all_licences = search_license_folder(str(folder))
+    assert len(all_licences) == 2
+    all_licences = search_license_folder(
+        str(folder), folders_exclude_search=("folder_exclude",)
+    )
+    assert len(all_licences) == 1
+    assert all_licences[0].path == str(folder_search / "LICENSE")
+
+
 @pytest.mark.xfail(
     reason="This test may fail because github has limitation regarding the"
     " number of requisitions we can do to their api."