Root package index containing multiple packages
| 395 | |
| 396 | |
| 397 | class PackageIndex(BaseModel): |
| 398 | """Root package index containing multiple packages""" |
| 399 | |
| 400 | packages: list[Package] = Field(min_length=1, description="Available packages") |
| 401 | |
| 402 | @field_validator("packages") |
| 403 | @classmethod |
| 404 | def validate_unique_packages(cls, v: list[Package]) -> list[Package]: |
| 405 | """Ensure no duplicate package names""" |
| 406 | names = [pkg.name for pkg in v] |
| 407 | if len(names) != len(set(names)): |
| 408 | raise ValueError("Duplicate package names found in index") |
| 409 | return v |
| 410 | |
| 411 | def find_package(self, name: str) -> Optional[Package]: |
| 412 | """Find package by name""" |
| 413 | for package in self.packages: |
| 414 | if package.name == name: |
| 415 | return package |
| 416 | return None |
| 417 | |
| 418 | def get_all_platforms(self) -> list[Platform]: |
| 419 | """Get all platforms from all packages""" |
| 420 | platforms: list[Platform] = [] |
| 421 | for package in self.packages: |
| 422 | platforms.extend(package.platforms) |
| 423 | return platforms |
| 424 | |
| 425 | def get_all_tools(self) -> list[Tool]: |
| 426 | """Get all tools from all packages""" |
| 427 | tools: list[Tool] = [] |
| 428 | for package in self.packages: |
| 429 | tools.extend(package.tools) |
| 430 | return tools |
| 431 | |
| 432 | |
| 433 | # Enhanced Parser with Validation and Error Handling |