# repodata **Repository Path**: shaoninghouse/repodata ## Basic Information - **Project Name**: repodata - **Description**: No description available - **Primary Language**: Go - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-04-21 - **Last Updated**: 2026-07-10 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # repodata 一个用于解析和读取 RPM/YUM 仓库元数据的 Go 语言库。 ## 功能特性 - 通过链接下载并解析 `repomd.xml` 文件 - 自动查找并下载 `primary_db.sqlite` 数据库 - 支持 `.bz2` 压缩格式的自动解压 - 使用 GORM 进行 SQLite 数据库查询 - 支持查询包信息、依赖关系(provides/requires)等 ## 安装 ```bash go get gitee.com/shaoninghouse/repodata ``` ## 快速使用 ```go package main import ( "fmt" "gitee.com/shaoninghouse/repodata" ) func main() { ri, err := repodata.NewRepoInfo(repodata.WithWorkspace("./repo")) if err != nil { panic(err) } sqlitePath, err := ri.DownloadPrimaryDBFromLink(repodata.Context{}, "https://example.com/yum/repo/") if err != nil { panic(err) } db, err := repodata.GetConnectForSqlite(sqlitePath) if err != nil { panic(err) } packages, err := repodata.GetPackagesWithProvidesAndRequires(db) if err != nil { panic(err) } for _, pkg := range packages[:5] { fmt.Printf("Name: %s, Version: %s, Arch: %s\n", pkg.Name, pkg.Version, pkg.Arch) } } ``` ## 完整示例 以下是一个完整的示例,演示如何从真实的 RPM 仓库下载并解析元数据: ```go package main import ( "fmt" "gitee.com/shaoninghouse/repodata" ) func main() { ri, err := repodata.NewRepoInfo(repodata.WithWorkspaceRandom("./test")) if err != nil { fmt.Println("Error creating RepoInfo:", err) return } repoURL := "https://update.cs2c.com.cn/NS/V10/V10SP3/os/adv/lic/updates/x86_64/" sqlitePath, err := ri.DownloadPrimaryDBFromLink(repodata.Context{}, repoURL) if err != nil { fmt.Println("Error downloading primary_db:", err) return } fmt.Println("SQLite file downloaded to:", sqlitePath) db, err := repodata.GetConnectForSqlite(sqlitePath) if err != nil { fmt.Println("Error connecting to database:", err) return } packages, err := repodata.GetPackagesWithProvidesAndRequires(db) if err != nil { fmt.Println("Error querying packages:", err) return } fmt.Printf("Total packages found: %d\n", len(packages)) limit := len(packages) if limit > 5 { limit = 5 } for _, pkg := range packages[:limit] { pkg.Summary = "" pkg.Description = "" pkg.RpmLicense = "" pkg.RpmVendor = "" fmt.Printf("%+v\n", pkg) } } ``` ## 核心 API ### RepoInfo 用于管理仓库信息和工作目录。 ```go // 创建 RepoInfo 实例 ri, err := repodata.NewRepoInfo(opts ...RepoInfoOption) // 使用指定工作目录 ri, err := repodata.NewRepoInfo(repodata.WithWorkspace("./repo")) // 使用随机子目录作为工作目录 ri, err := repodata.NewRepoInfo(repodata.WithWorkspaceRandom("./repo")) ``` ### 数据下载 ```go // 从仓库链接下载 primary_db.sqlite sqlitePath, err := ri.DownloadPrimaryDBFromLink(ctx Context, repoLink string) // 解析 repomd.xml repomd, err := ri.LoadRepomdXMLFromLink(ctx Context, repoLink string) // 查找 primary_db 链接 link, err := ri.FindPrimaryDBLinkFromRepodataLink(ctx Context, repoLink string) ``` ### 数据库查询 ```go // 获取数据库连接 db, err := repodata.GetConnectForSqlite(path2Sqlite string) // 查询所有包 packages, err := repodata.GetPackages(db) // 查询所有 provides provides, err := repodata.GetProvides(db) // 查询所有 requires requires, err := repodata.GetRequires(db) // 查询包及其关联的 provides 和 requires packages, err := repodata.GetPackagesWithProvidesAndRequires(db) ``` ## 数据模型 ### Package 包信息结构体,对应 SQLite 数据库中的 `packages` 表。 | 字段 | 类型 | 说明 | |------|------|------| | PkgKey | int | 包唯一标识 | | PkgId | string | 包 ID | | Name | string | 包名 | | Arch | string | 架构 | | Version | string | 版本 | | Release | string | 发布版本 | | Summary | string | 摘要 | | Description | string | 描述 | | Url | string | 主页地址 | | SizePackage | int | 包大小 | | SizeInstalled | int | 安装后大小 | ### Provide / Require 依赖信息结构体,对应 `provides` 和 `requires` 表。 | 字段 | 类型 | 说明 | |------|------|------| | Name | string | 依赖名称 | | Epoch | string | Epoch | | Version | string | 版本 | | Release | string | 发布版本 | | PkgKey | int | 关联的包标识 | ## 测试 ```bash # 运行所有单元测试 go test -v ./... ``` ## 参与贡献 1. Fork 本仓库 2. 新建 Feat_xxx 分支 3. 提交代码 4. 新建 Pull Request