类型 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 方法而不是直接结构操作