Finder API
The pkg/finder
package provides configuration file discovery functionality across different platforms and directory structures.
Overview
The Finder API is responsible for:
- Locating NuGet configuration files in standard locations
- Supporting platform-specific configuration paths
- Providing flexible search strategies
- Handling project-level and global configuration discovery
Types
ConfigFinder
type ConfigFinder struct {
SearchPaths []string
}
The main finder type that handles configuration file discovery.
Fields:
SearchPaths
: List of paths to search for configuration files
Constructors
NewConfigFinder
func NewConfigFinder() *ConfigFinder
Creates a new configuration finder with default search paths.
Returns:
*ConfigFinder
: New finder instance with platform-specific default paths
Example:
finder := finder.NewConfigFinder()
configPath, err := finder.FindConfigFile()
if err != nil {
log.Printf("No configuration file found: %v", err)
} else {
fmt.Printf("Found configuration: %s\n", configPath)
}
NewConfigFinderWithPaths
func NewConfigFinderWithPaths(searchPaths []string) *ConfigFinder
Creates a new configuration finder with custom search paths.
Parameters:
searchPaths
([]string): Custom list of paths to search
Returns:
*ConfigFinder
: New finder instance with specified paths
Example:
customPaths := []string{
"/custom/path/NuGet.Config",
"/another/path/NuGet.Config",
}
finder := finder.NewConfigFinderWithPaths(customPaths)
Discovery Methods
FindConfigFile
func (f *ConfigFinder) FindConfigFile() (string, error)
Finds the first available NuGet configuration file.
Returns:
string
: Path to the found configuration fileerror
: Error if no configuration file is found
Search Order:
- Current directory (
./NuGet.Config
) - Parent directories (walking up the tree)
- User-specific configuration directory
- System-wide configuration directory
Platform-specific paths:
- Windows:
%APPDATA%\NuGet\NuGet.Config
,%ProgramData%\NuGet\NuGet.Config
- macOS:
~/Library/Application Support/NuGet/NuGet.Config
,/Library/Application Support/NuGet/NuGet.Config
- Linux:
~/.config/NuGet/NuGet.Config
,/etc/NuGet/NuGet.Config
Example:
finder := finder.NewConfigFinder()
configPath, err := finder.FindConfigFile()
if err != nil {
if errors.IsNotFoundError(err) {
fmt.Println("No NuGet configuration file found")
// Create default configuration
} else {
log.Fatalf("Error searching for config: %v", err)
}
} else {
fmt.Printf("Using configuration file: %s\n", configPath)
}
FindAllConfigFiles
func (f *ConfigFinder) FindAllConfigFiles() []string
Finds all available NuGet configuration files in the search paths.
Returns:
[]string
: List of paths to all found configuration files
Example:
finder := finder.NewConfigFinder()
configFiles := finder.FindAllConfigFiles()
fmt.Printf("Found %d configuration files:\n", len(configFiles))
for i, path := range configFiles {
fmt.Printf("%d. %s\n", i+1, path)
}
// Use the first one or merge multiple configurations
if len(configFiles) > 0 {
primaryConfig := configFiles[0]
fmt.Printf("Using primary config: %s\n", primaryConfig)
}
FindProjectConfig
func (f *ConfigFinder) FindProjectConfig(startDir string) (string, error)
Finds a project-level configuration file starting from the specified directory.
Parameters:
startDir
(string): Starting directory for the search
Returns:
string
: Path to the found project configuration fileerror
: Error if no project configuration file is found
Search Strategy:
- Starts from
startDir
- Looks for
NuGet.Config
in current directory - Walks up parent directories until found or reaches root
- Stops at the first configuration file found
Example:
finder := finder.NewConfigFinder()
// Find project config starting from current directory
projectConfig, err := finder.FindProjectConfig(".")
if err != nil {
fmt.Println("No project-specific configuration found")
} else {
fmt.Printf("Project config: %s\n", projectConfig)
}
// Find config for a specific project
projectPath := "/path/to/my/project"
projectConfig, err = finder.FindProjectConfig(projectPath)
if err != nil {
fmt.Printf("No config found for project at %s\n", projectPath)
} else {
fmt.Printf("Project config: %s\n", projectConfig)
}
FindGlobalConfig
func (f *ConfigFinder) FindGlobalConfig() (string, error)
Finds the global (user-level) configuration file.
Returns:
string
: Path to the global configuration fileerror
: Error if no global configuration file is found
Example:
finder := finder.NewConfigFinder()
globalConfig, err := finder.FindGlobalConfig()
if err != nil {
fmt.Println("No global configuration found")
} else {
fmt.Printf("Global config: %s\n", globalConfig)
}
FindSystemConfig
func (f *ConfigFinder) FindSystemConfig() (string, error)
Finds the system-wide configuration file.
Returns:
string
: Path to the system configuration fileerror
: Error if no system configuration file is found
Example:
finder := finder.NewConfigFinder()
systemConfig, err := finder.FindSystemConfig()
if err != nil {
fmt.Println("No system configuration found")
} else {
fmt.Printf("System config: %s\n", systemConfig)
}
Path Management
GetDefaultSearchPaths
func (f *ConfigFinder) GetDefaultSearchPaths() []string
Returns the default search paths for the current platform.
Returns:
[]string
: List of default search paths
Example:
finder := finder.NewConfigFinder()
paths := finder.GetDefaultSearchPaths()
fmt.Println("Default search paths:")
for i, path := range paths {
fmt.Printf("%d. %s\n", i+1, path)
}
AddSearchPath
func (f *ConfigFinder) AddSearchPath(path string)
Adds a custom search path to the finder.
Parameters:
path
(string): Path to add to the search list
Example:
finder := finder.NewConfigFinder()
finder.AddSearchPath("/custom/config/location/NuGet.Config")
finder.AddSearchPath("/another/location/NuGet.Config")
// Now search will include custom paths
configPath, err := finder.FindConfigFile()
SetSearchPaths
func (f *ConfigFinder) SetSearchPaths(paths []string)
Sets the complete list of search paths, replacing existing ones.
Parameters:
paths
([]string): New list of search paths
Example:
finder := finder.NewConfigFinder()
customPaths := []string{
"./project.config",
"/etc/nuget/global.config",
"/usr/local/share/nuget/system.config",
}
finder.SetSearchPaths(customPaths)
Utility Methods
ConfigExists
func (f *ConfigFinder) ConfigExists(path string) bool
Checks if a configuration file exists at the specified path.
Parameters:
path
(string): Path to check
Returns:
bool
: True if the configuration file exists and is readable
Example:
finder := finder.NewConfigFinder()
configPath := "/path/to/NuGet.Config"
if finder.ConfigExists(configPath) {
fmt.Printf("Configuration exists: %s\n", configPath)
} else {
fmt.Printf("Configuration not found: %s\n", configPath)
}
ValidateConfigFile
func (f *ConfigFinder) ValidateConfigFile(path string) error
Validates that a file is a valid NuGet configuration file.
Parameters:
path
(string): Path to the configuration file
Returns:
error
: Error if the file is not valid
Example:
finder := finder.NewConfigFinder()
configPath := "/path/to/NuGet.Config"
err := finder.ValidateConfigFile(configPath)
if err != nil {
fmt.Printf("Invalid configuration file: %v\n", err)
} else {
fmt.Println("Configuration file is valid")
}
Advanced Usage
Custom Search Strategy
// Create a finder with custom search strategy
func createCustomFinder() *finder.ConfigFinder {
finder := finder.NewConfigFinder()
// Add project-specific paths
finder.AddSearchPath("./config/NuGet.Config")
finder.AddSearchPath("./settings/NuGet.Config")
// Add environment-specific paths
if env := os.Getenv("NUGET_CONFIG_PATH"); env != "" {
finder.AddSearchPath(env)
}
return finder
}
Hierarchical Configuration Discovery
// Find all configurations in hierarchy
func findConfigHierarchy(projectPath string) ([]string, error) {
finder := finder.NewConfigFinder()
var configs []string
// Project-level config
if projectConfig, err := finder.FindProjectConfig(projectPath); err == nil {
configs = append(configs, projectConfig)
}
// Global config
if globalConfig, err := finder.FindGlobalConfig(); err == nil {
configs = append(configs, globalConfig)
}
// System config
if systemConfig, err := finder.FindSystemConfig(); err == nil {
configs = append(configs, systemConfig)
}
return configs, nil
}
Error Handling
The finder uses standard error types from the pkg/errors
package:
import "github.com/scagogogo/nuget-config-parser/pkg/errors"
finder := finder.NewConfigFinder()
configPath, err := finder.FindConfigFile()
if err != nil {
if errors.IsNotFoundError(err) {
// No configuration file found
fmt.Println("Creating default configuration...")
// Handle missing configuration
} else {
// Other error occurred
log.Fatalf("Search error: %v", err)
}
}
Platform Differences
Windows
- User config:
%APPDATA%\NuGet\NuGet.Config
- System config:
%ProgramData%\NuGet\NuGet.Config
macOS
- User config:
~/Library/Application Support/NuGet/NuGet.Config
- System config:
/Library/Application Support/NuGet/NuGet.Config
Linux/Unix
- User config:
~/.config/NuGet/NuGet.Config
(respectsXDG_CONFIG_HOME
) - System config:
/etc/NuGet/NuGet.Config
Best Practices
- Use default finder: Start with
NewConfigFinder()
for standard behavior - Handle missing files: Always check for
IsNotFoundError
and provide fallbacks - Respect hierarchy: Use project configs over global configs when both exist
- Validate paths: Use
ConfigExists()
before attempting to parse files - Custom paths: Use
AddSearchPath()
for additional locations rather than replacing defaults - Environment variables: Consider environment-specific configuration paths
Thread Safety
The ConfigFinder is thread-safe for read operations but not for modifications. If you need to modify search paths concurrently, provide appropriate synchronization.