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.
This commit is contained in:
Jelle Spijker 2025-03-26 11:50:52 +01:00
parent fa1ead3064
commit adf8f5bdd8
No known key found for this signature in database
GPG Key ID: DE9D445A0C3D8AA1

View File

@ -5,8 +5,6 @@ import tempfile
import tarfile import tarfile
from io import StringIO from io import StringIO
from pathlib import Path from pathlib import Path
from git import Repo
from git.exc import GitCommandError
from jinja2 import Template 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.files import copy, rmdir, save, mkdir, rm, update_conandata
from conan.tools.microsoft import unix_path from conan.tools.microsoft import unix_path
from conan.tools.env import VirtualRunEnv, Environment, VirtualBuildEnv 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 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 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 dependencies[data["info"]["name"]] = dependency_description
@staticmethod @staticmethod
def _get_license_from_repository(sources_url, version, license_file_name = None): def _format_git_url(url):
if sources_url.startswith("https://github.com/Ultimaker/") and "private" in sources_url: """Return a properly formatted git repository URL."""
return None git_url = url.rstrip("/")
git_url = sources_url
if git_url.endswith('/'):
git_url = git_url[:-1]
if not git_url.endswith(".git"): if not git_url.endswith(".git"):
git_url = f"{git_url}.git" git_url = f"{git_url}.git"
git_url = git_url.replace("/cgit/", "/") return git_url.replace("/cgit/", "/")
tags = [f"v{version}", version] def _get_license_from_repository(self, repository_url, version, license_file_name=None):
files = ["LICENSE", "LICENSE.txt", "LICENSE.md", "COPYRIGHT", "COPYING", "COPYING.LIB"] if license_file_name is None else [license_file_name] # 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: # Prepare the Git URL and candidate lists.
repo = Repo.clone_from(git_url, clone_dir, depth=1, no_checkout=True) 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: try:
repo.git.fetch('--depth', '1', 'origin', 'tag', tag) git.checkout(commit=tag)
except GitCommandError: except Exception:
continue continue # Try next tag if checkout fails.
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()
# 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 break
return None
def _make_conan_dependency_description(self, dependency, dependencies): def _make_conan_dependency_description(self, dependency, dependencies):
dependency_description = { dependency_description = {