📦 包信息模型
pkg/domain 中描述 Composer 包详情的核心结构体。它们对应 Packagist 的 https://repo.packagist.org/p2/<vendor>/<package>.json 接口返回数据,由 ComposerClient.GetPackage 反序列化得到。
类型总览
| 类型 | 角色 | 关键字段数 |
|---|---|---|
ComposerPackageInfo | 包的完整信息(顶层包装) | 5 |
PackageInfo | 包的业务信息主体 | 15 |
PackageDownloads | 下载统计子结构 | 3 |
Maintainer | 维护者 | 2 |
Version | 单版本元数据 | 18+ |
🗂️ ComposerPackageInfo
包的完整信息,包含主键、小写包名、业务信息、md5 指纹与三个时间戳。是 GetPackage 的直接返回类型。
go
type ComposerPackageInfo struct {
PackageName string `json:"package_name" bson:"package_name"`
PackageNameLowercase string `json:"package_name_lowercase" bson:"package_name_lowercase"`
Package PackageInfo `json:"package" bson:"package"`
PackageInfoMd5 string `json:"package_info_md5" bson:"package_info_md5"`
CreateTime *time.Time `json:"create_time" bson:"create_time"`
UpdateTime *time.Time `json:"update_time" bson:"update_time"`
ChangeTime *time.Time `json:"change_time" bson:"change_time"`
}| 字段 | 类型 | 说明 |
|---|---|---|
PackageName | string | 包名,作为唯一主键(如 symfony/console) |
PackageNameLowercase | string | 小写包名,用于不区分大小写的查询 |
Package | PackageInfo | 包的详细业务信息,见下节 |
PackageInfoMd5 | string | 包信息的 md5 指纹,用于识别内容是否较之前发生变化 |
CreateTime | *time.Time | 包记录的创建时间(指针类型,可为 nil) |
UpdateTime | *time.Time | 包记录的更新时间 |
ChangeTime | *time.Time | 包信息内容发生变化的时间 |
三个时间戳的区别
CreateTime:记录首次入库时间UpdateTime:记录任何字段被刷新的时间ChangeTime:记录内容真正变化(md5 不同)的时间,常用于增量同步
📑 PackageInfo
包的业务信息主体,嵌套在 ComposerPackageInfo.Package 中。
go
type PackageInfo struct {
Name string `json:"name" bson:"name"`
Description string `json:"description" bson:"description"`
Time time.Time `json:"time" bson:"time"`
Maintainers []*Maintainer `json:"maintainers" bson:"maintainers"`
Versions map[string]*Version `json:"versions" bson:"versions"`
Type string `json:"type" bson:"type"`
Repository string `json:"repository" bson:"repository"`
GithubStars int `json:"github_stars" bson:"github_stars"`
GithubWatchers int `json:"github_watchers" bson:"github_watchers"`
GithubForks int `json:"github_forks" bson:"github_forks"`
GithubOpenIssues int `json:"github_open_issues" bson:"github_open_issues"`
Language string `json:"language" bson:"language"`
Dependents int `json:"dependents" bson:"dependents"`
Suggesters int `json:"suggesters" bson:"suggesters"`
Downloads PackageDownloads `json:"downloads" bson:"downloads"`
Favers int `json:"favers" bson:"favers"`
}| 字段 | 类型 | 说明 |
|---|---|---|
Name | string | 包名 |
Description | string | 包描述 |
Time | time.Time | 包创建时间 |
Maintainers | []*Maintainer | 维护者列表 |
Versions | map[string]*Version | 所有版本,键为版本号(如 v6.0.0) |
Type | string | 包类型(如 library、composer-plugin) |
Repository | string | 对应的源代码仓库 URL |
GithubStars | int | GitHub star 数 |
GithubWatchers | int | GitHub watcher 数 |
GithubForks | int | GitHub fork 数 |
GithubOpenIssues | int | GitHub open issue 数 |
Language | string | 仓库主语言 |
Dependents | int | 被多少个其它包依赖 |
Suggesters | int | 建议者数量 |
Downloads | PackageDownloads | 下载统计,见下节 |
Favers | int | 收藏数 |
📉 PackageDownloads
下载统计,嵌套在 PackageInfo.Downloads 与 PackageStatsResponse.Downloads 中。
go
type PackageDownloads struct {
Total int `json:"total" bson:"total"`
Monthly int `json:"monthly" bson:"monthly"`
Daily int `json:"daily" bson:"daily"`
}| 字段 | 类型 | 说明 |
|---|---|---|
Total | int | 历史总下载次数 |
Monthly | int | 本月下载次数 |
Daily | int | 今日下载次数 |
👤 Maintainer
包维护者,PackageInfo.Maintainers 元素类型。
go
type Maintainer struct {
Name string `json:"name" bson:"name"`
AvatarURL string `json:"avatar_url" bson:"avatar_url"`
}| 字段 | 类型 | 说明 |
|---|---|---|
Name | string | 维护者名字 |
AvatarURL | string | 维护者头像 URL |
🏷️ Version
单个版本的完整元数据。PackageInfo.Versions 的值类型为 *Version。
go
type Version struct {
Name string `json:"name"`
Description string `json:"description"`
Keywords []string `json:"keywords"`
Homepage string `json:"homepage"`
Version string `json:"version"`
VersionNormalized string `json:"version_normalized"`
License []string `json:"license" bson:"license"`
Authors []struct {
Name string `json:"name" bson:"name"`
Email string `json:"email" bson:"email"`
Homepage string `json:"homepage" bson:"homepage"`
} `json:"authors" bson:"authors"`
Source struct {
URL string `json:"url" bson:"url"`
Type string `json:"type" bson:"type"`
Reference string `json:"reference" bson:"reference"`
} `json:"source" bson:"source"`
Dist struct {
URL string `json:"url" bson:"url"`
Type string `json:"type" bson:"type"`
Shasum string `json:"shasum" bson:"shasum"`
Reference string `json:"reference" bson:"reference"`
} `json:"dist" bson:"dist"`
Type string `json:"type" bson:"type"`
Support struct {
Source string `json:"source" bson:"source"`
} `json:"support" bson:"support"`
Funding []struct {
URL string `json:"url" bson:"url"`
Type string `json:"type" bson:"type"`
} `json:"funding" bson:"funding"`
Time time.Time `json:"time" bson:"time"`
Require map[string]string `json:"require" bson:"require"`
Autoload interface{} `json:"autoload" bson:"autoload"`
Extra interface{} `json:"extra" bson:"extra"`
Suggest interface{} `json:"suggest" bson:"suggest"`
Provide interface{} `json:"provide" bson:"provide"`
}| 字段 | 类型 | 说明 |
|---|---|---|
Name | string | 版本名 |
Description | string | 版本描述 |
Keywords | []string | 关键词 |
Homepage | string | 版本首页 |
Version | string | 版本号(如 6.0.0) |
VersionNormalized | string | 归一化后的版本号 |
License | []string | 此版本采用的 license |
Authors | []struct | 作者列表(含 name/email/homepage) |
Source | struct | 源码信息(url/type/reference) |
Dist | struct | 分发归档信息(url/type/shasum/reference) |
Type | string | 包类型 |
Support | struct | 支持信息(含 source 链接) |
Funding | []struct | 资助信息(url/type) |
Time | time.Time | 版本发布时间 |
Require | map[string]string | 此版本依赖的其它包及版本约束 |
Autoload | interface{} | PSR-4 等自动加载配置 |
Extra | interface{} | 额外配置 |
Suggest | interface{} | 建议安装的包 |
Provide | interface{} | 此版本提供的虚拟包能力 |
Authors/Source/Dist 为匿名结构体
Authors、Source、Dist、Support、Funding 都是内联匿名结构体,无法在外部按类型引用。若要复用其字段,请通过 version.Authors[i].Name 这样的链式访问。
🚀 示例:遍历包版本与依赖
go
package main
import (
"fmt"
"log"
"time"
"github.com/scagogogo/composer-skills/pkg/client"
)
func main() {
c := client.NewComposerClient(30 * time.Second)
info, err := c.GetPackage("monolog/monolog")
if err != nil {
log.Fatal(err)
}
fmt.Printf("维护者: %d 人\n", len(info.Package.Maintainers))
for ver, v := range info.Package.Versions {
fmt.Printf("版本 %s, license=%v, 依赖数=%d\n", ver, v.License, len(v.Require))
for dep, constraint := range v.Require {
fmt.Printf(" - %s: %s\n", dep, constraint)
}
}
}📚 相关文档
- 🔙 返回 Domain 概览
- 🔒 安全公告字段 → advisory.md
- 📊 单包下载统计 → statistics.md