From adf8f5bdd89f50726dfaa66668c4130df3a3a1c5 Mon Sep 17 00:00:00 2001 From: Jelle Spijker Date: Wed, 26 Mar 2025 11:50:52 +0100 Subject: [PATCH] Refactor license retrieval to use Conan's Git helper Replaced the external `gitpython` library with Conan's built-in `Git` helper for repository operations. Simplified and improved the license retrieval logic while maintaining existing functionality, ensuring better integration and reduced dependency overhead. --- conanfile.py | 68 ++++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/conanfile.py b/conanfile.py index b3e070e3b3..5027c52149 100644 --- a/conanfile.py +++ b/conanfile.py @@ -5,8 +5,6 @@ import tempfile import tarfile from io import StringIO from pathlib import Path -from git import Repo -from git.exc import GitCommandError from jinja2 import Template @@ -14,7 +12,7 @@ from conan import ConanFile from conan.tools.files import copy, rmdir, save, mkdir, rm, update_conandata from conan.tools.microsoft import unix_path from conan.tools.env import VirtualRunEnv, Environment, VirtualBuildEnv -from conan.tools.scm import Version +from conan.tools.scm import Version, Git from conan.errors import ConanInvalidConfiguration, ConanException required_conan_version = ">=2.7.0" # When changing the version, also change the one in conandata.yml/extra_dependencies @@ -218,45 +216,47 @@ class CuraConan(ConanFile): dependencies[data["info"]["name"]] = dependency_description @staticmethod - def _get_license_from_repository(sources_url, version, license_file_name = None): - if sources_url.startswith("https://github.com/Ultimaker/") and "private" in sources_url: - return None - - git_url = sources_url - if git_url.endswith('/'): - git_url = git_url[:-1] + def _format_git_url(url): + """Return a properly formatted git repository URL.""" + git_url = url.rstrip("/") if not git_url.endswith(".git"): git_url = f"{git_url}.git" - git_url = git_url.replace("/cgit/", "/") + return git_url.replace("/cgit/", "/") - tags = [f"v{version}", version] - files = ["LICENSE", "LICENSE.txt", "LICENSE.md", "COPYRIGHT", "COPYING", "COPYING.LIB"] if license_file_name is None else [license_file_name] + def _get_license_from_repository(self, repository_url, version, license_file_name=None): + # Do not retrieve license if repository is flagged as private. + if repository_url.startswith("https://github.com/Ultimaker/") and "private" in repository_url: + return None - with tempfile.TemporaryDirectory() as clone_dir: - repo = Repo.clone_from(git_url, clone_dir, depth=1, no_checkout=True) + # Prepare the Git URL and candidate lists. + git_url = self._format_git_url(repository_url) + candidate_tags = [f"v{version}", version] + candidate_license_files = ( + [license_file_name] if license_file_name + else ["LICENSE", "LICENSE.txt", "LICENSE.md", "COPYRIGHT", "COPYING", "COPYING.LIB"] + ) - for tag in tags: + # Clone the repository into a temporary directory. + with tempfile.TemporaryDirectory() as clone_directory: + git = Git(self, clone_directory) + git.clone(url=git_url, target=".", args=["--depth", "1"]) + + # Iterate over candidate tags. + for tag in candidate_tags: try: - repo.git.fetch('--depth', '1', 'origin', 'tag', tag) - except GitCommandError: - continue - - repo.git.sparse_checkout('init', '--cone') - for file_name in files: - repo.git.sparse_checkout('add', file_name) - - try: - repo.git.checkout(tag) - except GitCommandError: - pass - - for file_name in files: - license_file = os.path.join(clone_dir, file_name) - if os.path.exists(license_file): - with open(license_file, 'r', encoding='utf8') as file: - return file.read() + git.checkout(commit=tag) + except Exception: + continue # Try next tag if checkout fails. + # Search for any existing license file in the repository. + for file_name in candidate_license_files: + license_path = os.path.join(clone_directory, file_name) + if os.path.exists(license_path): + with open(license_path, "r", encoding="utf8") as license_file: + return license_file.read() + # Exit if no license file was found for the checked out tag. break + return None def _make_conan_dependency_description(self, dependency, dependencies): dependency_description = {