or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

core-functions.mdexceptions.mdindex.mdrepository-holders.mdutilities.mdversion-handling.md

repository-holders.mddocs/

0

# Repository Holders

1

2

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.

3

4

## Capabilities

5

6

### Holder Factory

7

8

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

9

10

```python { .api }

11

class HolderFactory:

12

"""

13

Factory for creating platform-specific repository holders.

14

15

Automatically selects appropriate holder based on repository URL patterns,

16

domain matching, and explicit platform hints. Holders are ordered by

17

specificity with self-hosted platforms evaluated after primary domains.

18

"""

19

20

HOLDERS: dict[str, type] = {

21

"wp": WordPressPluginRepoSession,

22

"sf": SourceForgeRepoSession,

23

"wiki": WikipediaRepoSession,

24

"helm_chart": HelmChartRepoSession,

25

"github": GitHubRepoSession,

26

"gitlab": GitLabRepoSession,

27

"bitbucket": BitBucketRepoSession,

28

"pip": PypiRepoSession,

29

"hg": MercurialRepoSession,

30

"gitea": GiteaRepoSession,

31

"website-feed": FeedRepoSession,

32

"local": LocalVersionSession,

33

"system": SystemRepoSession,

34

}

35

36

DEFAULT_HOLDER: str = "github"

37

38

@staticmethod

39

def get_instance_for_repo(repo: str, at: str = None):

40

"""

41

Get appropriate holder instance for repository.

42

43

Parameters:

44

- repo: Repository identifier (URL, owner/name, package name)

45

- at: Optional platform hint to override auto-detection

46

47

Returns:

48

- Holder class for the specified repository

49

"""

50

```

51

52

### Base Holder Interface

53

54

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

55

56

```python { .api }

57

class BaseProjectHolder:

58

"""

59

Abstract base class for all repository holders.

60

61

Defines common interface and shared functionality for accessing

62

version information across different platforms and repositories.

63

"""

64

65

CACHE_DISABLED: bool = False

66

67

def __init__(self, repo: str, **kwargs):

68

"""

69

Initialize holder for specific repository.

70

71

Parameters:

72

- repo: Repository identifier

73

- **kwargs: Platform-specific configuration options

74

"""

75

76

def get_latest_version(self, **kwargs) -> dict:

77

"""

78

Get latest version information for the repository.

79

80

Returns:

81

- Dictionary containing version and release metadata

82

"""

83

84

def get_versions(self, **kwargs) -> list:

85

"""

86

Get all available versions for the repository.

87

88

Returns:

89

- List of version dictionaries ordered by release date

90

"""

91

```

92

93

### GitHub Integration

94

95

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

96

97

```python { .api }

98

class GitHubRepoSession(BaseProjectHolder):

99

"""

100

GitHub repository holder supporting public GitHub and GitHub Enterprise.

101

102

Features:

103

- GitHub API v3/v4 integration

104

- Release and tag-based version discovery

105

- Asset filtering and download URL generation

106

- Rate limiting and authentication handling

107

- Pre-release detection and filtering

108

"""

109

110

def __init__(self, repo: str, hostname: str = "github.com", **kwargs):

111

"""

112

Initialize GitHub repository session.

113

114

Parameters:

115

- repo: Repository in format "owner/name"

116

- hostname: GitHub hostname for Enterprise instances

117

- **kwargs: Additional GitHub-specific options

118

"""

119

```

120

121

### GitLab Integration

122

123

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

124

125

```python { .api }

126

class GitLabRepoSession(BaseProjectHolder):

127

"""

128

GitLab repository holder for GitLab.com and self-hosted instances.

129

130

Features:

131

- GitLab API v4 integration

132

- Project and tag-based version discovery

133

- Self-hosted GitLab instance support

134

- Release artifacts and download URLs

135

"""

136

137

def __init__(self, repo: str, hostname: str = "gitlab.com", **kwargs):

138

"""

139

Initialize GitLab repository session.

140

141

Parameters:

142

- repo: Repository identifier or full URL

143

- hostname: GitLab hostname for self-hosted instances

144

- **kwargs: GitLab-specific options

145

"""

146

```

147

148

### PyPI Integration

149

150

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

151

152

```python { .api }

153

class PypiRepoSession(BaseProjectHolder):

154

"""

155

PyPI package repository holder.

156

157

Features:

158

- PyPI JSON API integration

159

- Package version history

160

- Wheel and source distribution discovery

161

- Package metadata extraction

162

- Pre-release version filtering

163

"""

164

165

def __init__(self, package_name: str, **kwargs):

166

"""

167

Initialize PyPI package session.

168

169

Parameters:

170

- package_name: PyPI package name

171

- **kwargs: PyPI-specific options

172

"""

173

```

174

175

### Additional Platform Holders

176

177

Integration classes for various other platforms and repositories.

178

179

```python { .api }

180

class BitBucketRepoSession(BaseProjectHolder):

181

"""BitBucket repository holder for Atlassian BitBucket."""

182

183

class SourceForgeRepoSession(BaseProjectHolder):

184

"""SourceForge project holder with file release system support."""

185

186

class WordPressPluginRepoSession(BaseProjectHolder):

187

"""WordPress plugin directory holder."""

188

189

class WikipediaRepoSession(BaseProjectHolder):

190

"""Wikipedia software version extraction from software infoboxes."""

191

192

class MercurialRepoSession(BaseProjectHolder):

193

"""Mercurial repository holder for Hg-based projects."""

194

195

class GiteaRepoSession(BaseProjectHolder):

196

"""Gitea repository holder for self-hosted Git service."""

197

198

class FeedRepoSession(BaseProjectHolder):

199

"""RSS/ATOM feed-based version discovery for arbitrary websites."""

200

201

class LocalVersionSession(BaseProjectHolder):

202

"""Local file-based version discovery."""

203

204

class SystemRepoSession(BaseProjectHolder):

205

"""System package manager integration."""

206

207

class HelmChartRepoSession(BaseProjectHolder):

208

"""Helm chart repository holder for Kubernetes packages."""

209

```

210

211

## Usage Examples

212

213

### Automatic Platform Detection

214

215

```python

216

from lastversion.holder_factory import HolderFactory

217

218

# Automatic holder selection based on repository URL

219

holders = [

220

("numpy/numpy", "github"), # GitHub auto-detected

221

("requests", "pip"), # Explicit PyPI hint

222

("gitlab.com/gitlab-org/gitlab", "gitlab"), # GitLab auto-detected

223

("https://sourceforge.net/projects/sevenzip/", "sf"), # SourceForge

224

]

225

226

for repo, expected in holders:

227

holder_class = HolderFactory.get_holder_class(repo)

228

print(f"{repo} → {holder_class.__name__}")

229

```

230

231

### Direct Holder Usage

232

233

```python

234

from lastversion.repo_holders.github import GitHubRepoSession

235

from lastversion.repo_holders.pypi import PypiRepoSession

236

237

# Direct GitHub repository access

238

github_holder = GitHubRepoSession("kubernetes/kubernetes")

239

k8s_versions = github_holder.get_versions()

240

latest_k8s = github_holder.get_latest_version()

241

242

print(f"Latest Kubernetes: {latest_k8s['version']}")

243

print(f"Total releases: {len(k8s_versions)}")

244

245

# Direct PyPI package access

246

pypi_holder = PypiRepoSession("requests")

247

requests_info = pypi_holder.get_latest_version()

248

print(f"Latest requests: {requests_info['version']}")

249

```

250

251

### GitHub Enterprise Integration

252

253

```python

254

from lastversion.repo_holders.github import GitHubRepoSession

255

256

# GitHub Enterprise instance

257

enterprise_holder = GitHubRepoSession(

258

"internal/project",

259

hostname="github.company.com"

260

)

261

262

# Custom authentication can be provided via environment variables

263

# GITHUB_TOKEN or through holder configuration

264

latest_version = enterprise_holder.get_latest_version()

265

```

266

267

### Advanced Filtering with Holders

268

269

```python

270

from lastversion.holder_factory import HolderFactory

271

272

def get_filtered_versions(repo, **filters):

273

"""Get versions with custom filtering applied."""

274

holder_class = HolderFactory.get_holder_class(repo)

275

holder = holder_class(repo)

276

277

# Get all versions

278

versions = holder.get_versions()

279

280

# Apply filters

281

if filters.get('pre_ok', False) is False:

282

versions = [v for v in versions if not v.get('prerelease', False)]

283

284

if 'major' in filters:

285

major_version = filters['major']

286

versions = [v for v in versions

287

if v['version'].startswith(major_version)]

288

289

return versions

290

291

# Usage example

292

stable_versions = get_filtered_versions("kubernetes/kubernetes", pre_ok=False)

293

v1_28_versions = get_filtered_versions("kubernetes/kubernetes", major="v1.28")

294

```

295

296

### Multi-Platform Version Comparison

297

298

```python

299

from lastversion.holder_factory import HolderFactory

300

301

def compare_versions_across_platforms(package_identifiers):

302

"""Compare same software across different platforms."""

303

results = {}

304

305

for platform, identifier in package_identifiers.items():

306

try:

307

holder_class = HolderFactory.get_holder_class(identifier, at=platform)

308

holder = holder_class(identifier)

309

latest = holder.get_latest_version()

310

results[platform] = latest['version']

311

except Exception as e:

312

results[platform] = f"Error: {e}"

313

314

return results

315

316

# Compare Docker across platforms

317

docker_platforms = {

318

"github": "docker/docker",

319

"pip": "docker", # Docker SDK for Python

320

}

321

322

versions = compare_versions_across_platforms(docker_platforms)

323

for platform, version in versions.items():

324

print(f"{platform}: {version}")

325

```

326

327

### Custom Holder Development

328

329

```python

330

from lastversion.repo_holders.base import BaseProjectHolder

331

332

class CustomRepoSession(BaseProjectHolder):

333

"""Custom repository holder example."""

334

335

def __init__(self, repo, **kwargs):

336

super().__init__(repo, **kwargs)

337

self.base_url = kwargs.get('base_url', 'https://api.example.com')

338

339

def get_latest_version(self, **kwargs):

340

"""Implement custom version discovery logic."""

341

# Custom API integration logic here

342

return {

343

'version': '1.0.0',

344

'date': '2023-01-01',

345

'download_url': 'https://example.com/download'

346

}

347

348

def get_versions(self, **kwargs):

349

"""Get all available versions."""

350

# Custom implementation

351

return [self.get_latest_version()]

352

353

# Register custom holder with factory

354

HolderFactory.HOLDERS['custom'] = CustomRepoSession

355

356

# Use custom holder

357

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

358

```

359

360

### Error Handling and Fallbacks

361

362

```python

363

from lastversion.holder_factory import HolderFactory

364

from lastversion.exceptions import BadProjectError, ApiCredentialsError

365

366

def robust_version_lookup(repo, platforms=None):

367

"""Robust version lookup with fallback platforms."""

368

if platforms is None:

369

platforms = ['github', 'gitlab', 'pip']

370

371

for platform in platforms:

372

try:

373

holder_class = HolderFactory.get_holder_class(repo, at=platform)

374

holder = holder_class(repo)

375

return holder.get_latest_version()

376

except BadProjectError:

377

continue # Try next platform

378

except ApiCredentialsError as e:

379

print(f"API credentials issue for {platform}: {e}")

380

continue

381

except Exception as e:

382

print(f"Error with {platform}: {e}")

383

continue

384

385

raise BadProjectError(f"Could not find {repo} on any platform")

386

387

# Usage with fallback logic

388

try:

389

version_info = robust_version_lookup("some-project")

390

print(f"Found version: {version_info['version']}")

391

except BadProjectError as e:

392

print(f"Project not found: {e}")

393

```