类型 API
pkg/types
包定义了用于表示 NuGet 配置文件的所有数据结构。这些类型直接对应于 NuGet.Config 文件的 XML 结构。
核心配置类型
NuGetConfig
go
type NuGetConfig struct {
PackageSources PackageSources `xml:"packageSources"`
PackageSourceCredentials *PackageSourceCredentials `xml:"packageSourceCredentials,omitempty"`
Config *Config `xml:"config,omitempty"`
DisabledPackageSources *DisabledPackageSources `xml:"disabledPackageSources,omitempty"`
ActivePackageSource *ActivePackageSource `xml:"activePackageSource,omitempty"`
}
表示完整 NuGet 配置的根配置结构。
字段:
PackageSources
: 可用包源列表(必需)PackageSourceCredentials
: 包源凭证(可选)Config
: 全局配置选项(可选)DisabledPackageSources
: 禁用包源列表(可选)ActivePackageSource
: 当前活跃包源(可选)
示例:
go
config := &types.NuGetConfig{
PackageSources: types.PackageSources{
Add: []types.PackageSource{
{
Key: "nuget.org",
Value: "https://api.nuget.org/v3/index.json",
ProtocolVersion: "3",
},
},
},
}
包源类型
PackageSources
go
type PackageSources struct {
Clear bool `xml:"clear,attr,omitempty"`
Add []PackageSource `xml:"add"`
}
包源定义的容器。
字段:
Clear
: 如果为 true,清除所有先前定义的包源Add
: 要添加的包源列表
PackageSource
go
type PackageSource struct {
Key string `xml:"key,attr"`
Value string `xml:"value,attr"`
ProtocolVersion string `xml:"protocolVersion,attr,omitempty"`
}
表示单个包源。
字段:
Key
: 包源的唯一标识符Value
: 包源的 URL 或文件路径ProtocolVersion
: NuGet 协议版本(可选,通常为 "2" 或 "3")
示例:
go
source := types.PackageSource{
Key: "company-feed",
Value: "https://nuget.company.com/v3/index.json",
ProtocolVersion: "3",
}
DisabledPackageSources
go
type DisabledPackageSources struct {
Add []DisabledSource `xml:"add"`
}
禁用包源的容器。
DisabledSource
go
type DisabledSource struct {
Key string `xml:"key,attr"`
Value string `xml:"value,attr"`
}
表示禁用的包源。
字段:
Key
: 要禁用的包源的键Value
: 通常为 "true" 表示源被禁用
ActivePackageSource
go
type ActivePackageSource struct {
Add PackageSource `xml:"add"`
}
表示当前活跃的包源。
凭证类型
PackageSourceCredentials
go
type PackageSourceCredentials struct {
Sources map[string]SourceCredential `xml:"-"`
}
包源凭证的容器。Sources
映射使用包源键作为键,凭证作为值。
注意: 此类型具有自定义 XML 编组/解组逻辑,以处理 NuGet.Config 文件中凭证的动态结构。
SourceCredential
go
type SourceCredential struct {
Add []Credential `xml:"add"`
}
特定包源的凭证。
Credential
go
type Credential struct {
Key string `xml:"key,attr"`
Value string `xml:"value,attr"`
}
单个凭证键值对。
常见凭证键:
Username
: 认证用户名Password
: 认证密码(通常加密)ClearTextPassword
: 明文密码(生产环境不推荐)
示例:
go
credentials := types.SourceCredential{
Add: []types.Credential{
{Key: "Username", Value: "myuser"},
{Key: "ClearTextPassword", Value: "mypassword"},
},
}
配置选项类型
Config
go
type Config struct {
Add []ConfigOption `xml:"add"`
}
全局配置选项的容器。
ConfigOption
go
type ConfigOption struct {
Key string `xml:"key,attr"`
Value string `xml:"value,attr"`
}
单个配置选项。
常见配置键:
globalPackagesFolder
: 全局包文件夹路径repositoryPath
: 包仓库路径defaultPushSource
: 包发布的默认源http_proxy
: HTTP 代理设置http_proxy.user
: HTTP 代理用户名http_proxy.password
: HTTP 代理密码
示例:
go
configOptions := []types.ConfigOption{
{Key: "globalPackagesFolder", Value: "/custom/packages/path"},
{Key: "defaultPushSource", Value: "https://my-nuget-server.com"},
}
XML 编组
所有类型都通过 Go 的 encoding/xml
包支持 XML 编组和解组。结构标签定义每个字段如何映射到 XML 元素和属性。
自定义编组
PackageSourceCredentials
类型实现自定义 XML 编组以处理动态结构,其中每个包源都有自己的 XML 元素:
xml
<packageSourceCredentials>
<MyPrivateSource>
<add key="Username" value="myuser" />
<add key="ClearTextPassword" value="mypass" />
</MyPrivateSource>
</packageSourceCredentials>
使用示例
创建完整配置
go
config := &types.NuGetConfig{
PackageSources: types.PackageSources{
Add: []types.PackageSource{
{
Key: "nuget.org",
Value: "https://api.nuget.org/v3/index.json",
ProtocolVersion: "3",
},
{
Key: "local",
Value: "/path/to/local/packages",
},
},
},
PackageSourceCredentials: &types.PackageSourceCredentials{
Sources: map[string]types.SourceCredential{
"private-feed": {
Add: []types.Credential{
{Key: "Username", Value: "user"},
{Key: "ClearTextPassword", Value: "pass"},
},
},
},
},
Config: &types.Config{
Add: []types.ConfigOption{
{Key: "globalPackagesFolder", Value: "/custom/packages"},
},
},
DisabledPackageSources: &types.DisabledPackageSources{
Add: []types.DisabledSource{
{Key: "local", Value: "true"},
},
},
ActivePackageSource: &types.ActivePackageSource{
Add: types.PackageSource{
Key: "nuget.org",
Value: "https://api.nuget.org/v3/index.json",
},
},
}
使用包源
go
// 添加新包源
newSource := types.PackageSource{
Key: "company-feed",
Value: "https://nuget.company.com/v3/index.json",
ProtocolVersion: "3",
}
config.PackageSources.Add = append(config.PackageSources.Add, newSource)
// 查找包源
var foundSource *types.PackageSource
for i, source := range config.PackageSources.Add {
if source.Key == "company-feed" {
foundSource = &config.PackageSources.Add[i]
break
}
}
// 移除包源
for i, source := range config.PackageSources.Add {
if source.Key == "company-feed" {
config.PackageSources.Add = append(
config.PackageSources.Add[:i],
config.PackageSources.Add[i+1:]...,
)
break
}
}
使用凭证
go
// 如果为 nil 则初始化凭证
if config.PackageSourceCredentials == nil {
config.PackageSourceCredentials = &types.PackageSourceCredentials{
Sources: make(map[string]types.SourceCredential),
}
}
// 为源添加凭证
config.PackageSourceCredentials.Sources["private-feed"] = types.SourceCredential{
Add: []types.Credential{
{Key: "Username", Value: "myuser"},
{Key: "ClearTextPassword", Value: "mypass"},
},
}
// 获取源的凭证
if cred, exists := config.PackageSourceCredentials.Sources["private-feed"]; exists {
for _, c := range cred.Add {
if c.Key == "Username" {
fmt.Printf("用户名: %s\n", c.Value)
}
}
}
使用配置选项
go
// 如果为 nil 则初始化配置
if config.Config == nil {
config.Config = &types.Config{
Add: []types.ConfigOption{},
}
}
// 添加配置选项
config.Config.Add = append(config.Config.Add, types.ConfigOption{
Key: "globalPackagesFolder",
Value: "/custom/packages/path",
})
// 查找配置选项
var globalPackagesFolder string
for _, option := range config.Config.Add {
if option.Key == "globalPackagesFolder" {
globalPackagesFolder = option.Value
break
}
}
验证
虽然类型本身不包含验证逻辑,但在创建或修改配置时应验证数据:
go
func validatePackageSource(source types.PackageSource) error {
if source.Key == "" {
return errors.New("包源键不能为空")
}
if source.Value == "" {
return errors.New("包源值不能为空")
}
if source.ProtocolVersion != "" &&
source.ProtocolVersion != "2" &&
source.ProtocolVersion != "3" {
return errors.New("无效的协议版本")
}
return nil
}
线程安全
此包中的类型不是线程安全的。如果需要从多个 goroutine 访问或修改配置对象,必须提供自己的同步。
最佳实践
- 初始化可选字段: 在访问可选字段之前始终检查它们是否为 nil
- 对可选结构使用指针: 可选配置部分使用指针来区分空和缺失
- 验证数据: 在创建配置之前验证包源键、URL 和其他数据
- 小心处理凭证: 谨慎处理凭证,特别是明文密码
- 使用 API: 在可能的情况下,优先使用高级 API 方法而不是直接结构操作