Parser API
The pkg/parser
package provides configuration file parsing functionality with support for position tracking and detailed error reporting.
Overview
The Parser API is responsible for:
- Parsing NuGet configuration files from various sources
- Tracking element positions for position-aware editing
- Providing detailed error information for debugging
- Validating configuration file structure
Types
ConfigParser
type ConfigParser struct {
DefaultConfigSearchPaths []string
TrackPositions bool
}
The main parser type that handles configuration file parsing.
Fields:
DefaultConfigSearchPaths
: List of default paths to search for configuration filesTrackPositions
: Whether to track element positions during parsing
ParseResult
type ParseResult struct {
Config *types.NuGetConfig // Parsed configuration
Positions map[string]*ElementPosition // Element position information
Content []byte // Original file content
}
Contains the result of position-aware parsing.
Fields:
Config
: The parsed NuGet configuration objectPositions
: Map of element paths to their position informationContent
: Original file content as bytes
ElementPosition
type ElementPosition struct {
TagName string // XML tag name
Attributes map[string]string // Element attributes
Range Range // Element range in the file
AttrRanges map[string]Range // Attribute value ranges
Content string // Element content
SelfClose bool // Whether it's a self-closing tag
}
Represents the position and metadata of an XML element.
Range
type Range struct {
Start Position // Start position
End Position // End position
}
Represents a range in the file.
Position
type Position struct {
Line int // Line number (1-based)
Column int // Column number (1-based)
Offset int // Byte offset from start of file
}
Represents a specific position in the file.
Constructors
NewConfigParser
func NewConfigParser() *ConfigParser
Creates a new configuration parser with default settings.
Returns:
*ConfigParser
: New parser instance
Example:
parser := parser.NewConfigParser()
config, err := parser.ParseFromFile("/path/to/NuGet.Config")
NewPositionAwareParser
func NewPositionAwareParser() *ConfigParser
Creates a new parser with position tracking enabled.
Returns:
*ConfigParser
: New parser instance with position tracking
Example:
parser := parser.NewPositionAwareParser()
result, err := parser.ParseFromFileWithPositions("/path/to/NuGet.Config")
Parsing Methods
ParseFromFile
func (p *ConfigParser) ParseFromFile(filePath string) (*types.NuGetConfig, error)
Parses a NuGet configuration file from the specified path.
Parameters:
filePath
(string): Path to the configuration file
Returns:
*types.NuGetConfig
: Parsed configuration objecterror
: Error if parsing fails
Errors:
errors.ErrConfigFileNotFound
: File doesn't existerrors.ErrEmptyConfigFile
: File is emptyerrors.ErrInvalidConfigFormat
: Invalid XML format*errors.ParseError
: Detailed parsing error with position information
Example:
parser := parser.NewConfigParser()
config, err := parser.ParseFromFile("/path/to/NuGet.Config")
if err != nil {
if errors.IsNotFoundError(err) {
fmt.Println("Configuration file not found")
} else if errors.IsParseError(err) {
fmt.Printf("Parse error: %v\n", err)
}
return
}
fmt.Printf("Loaded %d package sources\n", len(config.PackageSources.Add))
ParseFromString
func (p *ConfigParser) ParseFromString(content string) (*types.NuGetConfig, error)
Parses a NuGet configuration from an XML string.
Parameters:
content
(string): XML content as string
Returns:
*types.NuGetConfig
: Parsed configuration objecterror
: Error if parsing fails
Example:
xmlContent := `<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>`
parser := parser.NewConfigParser()
config, err := parser.ParseFromString(xmlContent)
if err != nil {
log.Fatalf("Failed to parse XML: %v", err)
}
ParseFromReader
func (p *ConfigParser) ParseFromReader(reader io.Reader) (*types.NuGetConfig, error)
Parses a NuGet configuration from an io.Reader.
Parameters:
reader
(io.Reader): Reader containing XML content
Returns:
*types.NuGetConfig
: Parsed configuration objecterror
: Error if parsing fails
Example:
file, err := os.Open("NuGet.Config")
if err != nil {
log.Fatal(err)
}
defer file.Close()
parser := parser.NewConfigParser()
config, err := parser.ParseFromReader(file)
if err != nil {
log.Fatalf("Failed to parse from reader: %v", err)
}
Position-Aware Parsing
ParseFromFileWithPositions
func (p *ConfigParser) ParseFromFileWithPositions(filePath string) (*ParseResult, error)
Parses a configuration file while tracking element positions.
Parameters:
filePath
(string): Path to the configuration file
Returns:
*ParseResult
: Parse result with position informationerror
: Error if parsing fails
Example:
parser := parser.NewPositionAwareParser()
result, err := parser.ParseFromFileWithPositions("/path/to/NuGet.Config")
if err != nil {
log.Fatalf("Failed to parse with positions: %v", err)
}
// Access the configuration
config := result.Config
fmt.Printf("Package sources: %d\n", len(config.PackageSources.Add))
// Access position information
for path, pos := range result.Positions {
fmt.Printf("Element %s at line %d\n", path, pos.Range.Start.Line)
}
ParseFromContentWithPositions
func (p *ConfigParser) ParseFromContentWithPositions(content []byte) (*ParseResult, error)
Parses configuration content while tracking element positions.
Parameters:
content
([]byte): XML content as bytes
Returns:
*ParseResult
: Parse result with position informationerror
: Error if parsing fails
Example:
content := []byte(`<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageSources>
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" />
</packageSources>
</configuration>`)
parser := parser.NewPositionAwareParser()
result, err := parser.ParseFromContentWithPositions(content)
if err != nil {
log.Fatalf("Failed to parse content: %v", err)
}
Serialization Methods
SaveToFile
func (p *ConfigParser) SaveToFile(config *types.NuGetConfig, filePath string) error
Serializes a configuration object to an XML file.
Parameters:
config
(*types.NuGetConfig): Configuration to savefilePath
(string): Target file path
Returns:
error
: Error if saving fails
Example:
parser := parser.NewConfigParser()
config := &types.NuGetConfig{
PackageSources: types.PackageSources{
Add: []types.PackageSource{
{
Key: "nuget.org",
Value: "https://api.nuget.org/v3/index.json",
},
},
},
}
err := parser.SaveToFile(config, "/path/to/NuGet.Config")
if err != nil {
log.Fatalf("Failed to save config: %v", err)
}
SerializeToXML
func (p *ConfigParser) SerializeToXML(config *types.NuGetConfig) (string, error)
Serializes a configuration object to an XML string.
Parameters:
config
(*types.NuGetConfig): Configuration to serialize
Returns:
string
: XML representationerror
: Error if serialization fails
Example:
parser := parser.NewConfigParser()
xmlString, err := parser.SerializeToXML(config)
if err != nil {
log.Fatalf("Failed to serialize: %v", err)
}
fmt.Println("Generated XML:")
fmt.Println(xmlString)
Discovery Methods
FindAndParseConfig
func (p *ConfigParser) FindAndParseConfig() (*types.NuGetConfig, string, error)
Finds and parses the first available configuration file.
Returns:
*types.NuGetConfig
: Parsed configurationstring
: Path to the found configuration fileerror
: Error if no file found or parsing fails
Example:
parser := parser.NewConfigParser()
config, configPath, err := parser.FindAndParseConfig()
if err != nil {
log.Fatalf("Failed to find and parse config: %v", err)
}
fmt.Printf("Using config from: %s\n", configPath)
Error Handling
The parser provides detailed error information through structured error types:
import "github.com/scagogogo/nuget-config-parser/pkg/errors"
config, err := parser.ParseFromFile("invalid.config")
if err != nil {
if errors.IsNotFoundError(err) {
// Handle file not found
fmt.Println("Configuration file not found")
} else if errors.IsParseError(err) {
// Handle parsing error with details
parseErr := err.(*errors.ParseError)
fmt.Printf("Parse error at line %d: %s\n", parseErr.Line, parseErr.Context)
} else if errors.IsFormatError(err) {
// Handle format error
fmt.Println("Invalid configuration format")
}
}
Best Practices
- Use appropriate parser type: Use
NewConfigParser()
for simple parsing,NewPositionAwareParser()
for editing scenarios - Handle errors properly: Always check for specific error types using the error utilities
- Validate input: Ensure file paths exist and content is valid before parsing
- Resource management: Close file handles properly when using
ParseFromReader
- Position tracking: Only enable position tracking when needed for editing to avoid overhead
Thread Safety
The ConfigParser is not thread-safe. Create separate instances for concurrent use or provide appropriate synchronization.