CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-lastversion

A CLI tool to find the latest stable version of an arbitrary project

Pending
Overview
Eval results
Files

repository-holders.mddocs/

Repository Holders

Platform-specific adapters for different hosting services and package repositories. The repository holder system provides a unified interface for accessing version information across diverse platforms, each with their own APIs and data formats.

Capabilities

Holder Factory

Central factory class for creating and managing repository holders based on URL patterns and platform hints.

class HolderFactory:
    """
    Factory for creating platform-specific repository holders.
    
    Automatically selects appropriate holder based on repository URL patterns,
    domain matching, and explicit platform hints. Holders are ordered by
    specificity with self-hosted platforms evaluated after primary domains.
    """
    
    HOLDERS: dict[str, type] = {
        "wp": WordPressPluginRepoSession,
        "sf": SourceForgeRepoSession, 
        "wiki": WikipediaRepoSession,
        "helm_chart": HelmChartRepoSession,
        "github": GitHubRepoSession,
        "gitlab": GitLabRepoSession,
        "bitbucket": BitBucketRepoSession,
        "pip": PypiRepoSession,
        "hg": MercurialRepoSession,
        "gitea": GiteaRepoSession,
        "website-feed": FeedRepoSession,
        "local": LocalVersionSession,
        "system": SystemRepoSession,
    }
    
    DEFAULT_HOLDER: str = "github"
    
    @staticmethod
    def get_instance_for_repo(repo: str, at: str = None):
        """
        Get appropriate holder instance for repository.
        
        Parameters:
        - repo: Repository identifier (URL, owner/name, package name)
        - at: Optional platform hint to override auto-detection
        
        Returns:
        - Holder class for the specified repository
        """

Base Holder Interface

Abstract base class defining the common interface implemented by all repository holders.

class BaseProjectHolder:
    """
    Abstract base class for all repository holders.
    
    Defines common interface and shared functionality for accessing
    version information across different platforms and repositories.
    """
    
    CACHE_DISABLED: bool = False
    
    def __init__(self, repo: str, **kwargs):
        """
        Initialize holder for specific repository.
        
        Parameters:
        - repo: Repository identifier
        - **kwargs: Platform-specific configuration options
        """
    
    def get_latest_version(self, **kwargs) -> dict:
        """
        Get latest version information for the repository.
        
        Returns:
        - Dictionary containing version and release metadata
        """
    
    def get_versions(self, **kwargs) -> list:
        """
        Get all available versions for the repository.
        
        Returns:
        - List of version dictionaries ordered by release date
        """

GitHub Integration

Specialized holder for GitHub repositories with support for GitHub Enterprise and advanced filtering options.

class GitHubRepoSession(BaseProjectHolder):
    """
    GitHub repository holder supporting public GitHub and GitHub Enterprise.
    
    Features:
    - GitHub API v3/v4 integration
    - Release and tag-based version discovery
    - Asset filtering and download URL generation
    - Rate limiting and authentication handling
    - Pre-release detection and filtering
    """
    
    def __init__(self, repo: str, hostname: str = "github.com", **kwargs):
        """
        Initialize GitHub repository session.
        
        Parameters:
        - repo: Repository in format "owner/name"
        - hostname: GitHub hostname for Enterprise instances
        - **kwargs: Additional GitHub-specific options
        """

GitLab Integration

Holder for GitLab repositories supporting both GitLab.com and self-hosted GitLab instances.

class GitLabRepoSession(BaseProjectHolder):
    """
    GitLab repository holder for GitLab.com and self-hosted instances.
    
    Features:
    - GitLab API v4 integration
    - Project and tag-based version discovery
    - Self-hosted GitLab instance support
    - Release artifacts and download URLs
    """
    
    def __init__(self, repo: str, hostname: str = "gitlab.com", **kwargs):
        """
        Initialize GitLab repository session.
        
        Parameters:
        - repo: Repository identifier or full URL
        - hostname: GitLab hostname for self-hosted instances
        - **kwargs: GitLab-specific options
        """

PyPI Integration

Package repository holder for Python Package Index with comprehensive package metadata support.

class PypiRepoSession(BaseProjectHolder):
    """
    PyPI package repository holder.
    
    Features:
    - PyPI JSON API integration
    - Package version history
    - Wheel and source distribution discovery
    - Package metadata extraction
    - Pre-release version filtering
    """
    
    def __init__(self, package_name: str, **kwargs):
        """
        Initialize PyPI package session.
        
        Parameters:
        - package_name: PyPI package name
        - **kwargs: PyPI-specific options
        """

Additional Platform Holders

Integration classes for various other platforms and repositories.

class BitBucketRepoSession(BaseProjectHolder):
    """BitBucket repository holder for Atlassian BitBucket."""

class SourceForgeRepoSession(BaseProjectHolder):
    """SourceForge project holder with file release system support."""

class WordPressPluginRepoSession(BaseProjectHolder):
    """WordPress plugin directory holder."""

class WikipediaRepoSession(BaseProjectHolder):
    """Wikipedia software version extraction from software infoboxes."""

class MercurialRepoSession(BaseProjectHolder):
    """Mercurial repository holder for Hg-based projects."""

class GiteaRepoSession(BaseProjectHolder):
    """Gitea repository holder for self-hosted Git service."""

class FeedRepoSession(BaseProjectHolder):
    """RSS/ATOM feed-based version discovery for arbitrary websites."""

class LocalVersionSession(BaseProjectHolder):
    """Local file-based version discovery."""

class SystemRepoSession(BaseProjectHolder):
    """System package manager integration."""

class HelmChartRepoSession(BaseProjectHolder):
    """Helm chart repository holder for Kubernetes packages."""

Usage Examples

Automatic Platform Detection

from lastversion.holder_factory import HolderFactory

# Automatic holder selection based on repository URL
holders = [
    ("numpy/numpy", "github"),           # GitHub auto-detected
    ("requests", "pip"),                 # Explicit PyPI hint
    ("gitlab.com/gitlab-org/gitlab", "gitlab"),  # GitLab auto-detected
    ("https://sourceforge.net/projects/sevenzip/", "sf"), # SourceForge
]

for repo, expected in holders:
    holder_class = HolderFactory.get_holder_class(repo)
    print(f"{repo} → {holder_class.__name__}")

Direct Holder Usage

from lastversion.repo_holders.github import GitHubRepoSession
from lastversion.repo_holders.pypi import PypiRepoSession

# Direct GitHub repository access
github_holder = GitHubRepoSession("kubernetes/kubernetes")
k8s_versions = github_holder.get_versions()
latest_k8s = github_holder.get_latest_version()

print(f"Latest Kubernetes: {latest_k8s['version']}")
print(f"Total releases: {len(k8s_versions)}")

# Direct PyPI package access
pypi_holder = PypiRepoSession("requests")
requests_info = pypi_holder.get_latest_version()
print(f"Latest requests: {requests_info['version']}")

GitHub Enterprise Integration

from lastversion.repo_holders.github import GitHubRepoSession

# GitHub Enterprise instance
enterprise_holder = GitHubRepoSession(
    "internal/project",
    hostname="github.company.com"
)

# Custom authentication can be provided via environment variables
# GITHUB_TOKEN or through holder configuration
latest_version = enterprise_holder.get_latest_version()

Advanced Filtering with Holders

from lastversion.holder_factory import HolderFactory

def get_filtered_versions(repo, **filters):
    """Get versions with custom filtering applied."""
    holder_class = HolderFactory.get_holder_class(repo)
    holder = holder_class(repo)
    
    # Get all versions
    versions = holder.get_versions()
    
    # Apply filters
    if filters.get('pre_ok', False) is False:
        versions = [v for v in versions if not v.get('prerelease', False)]
    
    if 'major' in filters:
        major_version = filters['major']
        versions = [v for v in versions 
                   if v['version'].startswith(major_version)]
    
    return versions

# Usage example
stable_versions = get_filtered_versions("kubernetes/kubernetes", pre_ok=False)
v1_28_versions = get_filtered_versions("kubernetes/kubernetes", major="v1.28")

Multi-Platform Version Comparison

from lastversion.holder_factory import HolderFactory

def compare_versions_across_platforms(package_identifiers):
    """Compare same software across different platforms."""
    results = {}
    
    for platform, identifier in package_identifiers.items():
        try:
            holder_class = HolderFactory.get_holder_class(identifier, at=platform)
            holder = holder_class(identifier)
            latest = holder.get_latest_version()
            results[platform] = latest['version']
        except Exception as e:
            results[platform] = f"Error: {e}"
    
    return results

# Compare Docker across platforms
docker_platforms = {
    "github": "docker/docker",
    "pip": "docker",  # Docker SDK for Python
}

versions = compare_versions_across_platforms(docker_platforms)
for platform, version in versions.items():
    print(f"{platform}: {version}")

Custom Holder Development

from lastversion.repo_holders.base import BaseProjectHolder

class CustomRepoSession(BaseProjectHolder):
    """Custom repository holder example."""
    
    def __init__(self, repo, **kwargs):
        super().__init__(repo, **kwargs)
        self.base_url = kwargs.get('base_url', 'https://api.example.com')
    
    def get_latest_version(self, **kwargs):
        """Implement custom version discovery logic."""
        # Custom API integration logic here
        return {
            'version': '1.0.0',
            'date': '2023-01-01',
            'download_url': 'https://example.com/download'
        }
    
    def get_versions(self, **kwargs):
        """Get all available versions."""
        # Custom implementation
        return [self.get_latest_version()]

# Register custom holder with factory
HolderFactory.HOLDERS['custom'] = CustomRepoSession

# Use custom holder
custom_version = HolderFactory.get_holder_class('repo', at='custom')

Error Handling and Fallbacks

from lastversion.holder_factory import HolderFactory
from lastversion.exceptions import BadProjectError, ApiCredentialsError

def robust_version_lookup(repo, platforms=None):
    """Robust version lookup with fallback platforms."""
    if platforms is None:
        platforms = ['github', 'gitlab', 'pip']
    
    for platform in platforms:
        try:
            holder_class = HolderFactory.get_holder_class(repo, at=platform)
            holder = holder_class(repo)
            return holder.get_latest_version()
        except BadProjectError:
            continue  # Try next platform
        except ApiCredentialsError as e:
            print(f"API credentials issue for {platform}: {e}")
            continue
        except Exception as e:
            print(f"Error with {platform}: {e}")
            continue
    
    raise BadProjectError(f"Could not find {repo} on any platform")

# Usage with fallback logic
try:
    version_info = robust_version_lookup("some-project")
    print(f"Found version: {version_info['version']}")
except BadProjectError as e:
    print(f"Project not found: {e}")

Install with Tessl CLI

npx tessl i tessl/pypi-lastversion

docs

core-functions.md

exceptions.md

index.md

repository-holders.md

utilities.md

version-handling.md

tile.json