Add extension normalization command
This commit is contained in:
77
internal/extension/parser.go
Normal file
77
internal/extension/parser.go
Normal file
@@ -0,0 +1,77 @@
|
||||
package extension
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ParseResult captures normalized CLI arguments for the extension command.
|
||||
type ParseResult struct {
|
||||
SourcesCanonical []string
|
||||
SourcesDisplay []string
|
||||
Duplicates []string
|
||||
NoOps []string
|
||||
Target string
|
||||
}
|
||||
|
||||
// ParseArgs validates extension command arguments and returns normalized tokens.
|
||||
func ParseArgs(args []string) (ParseResult, error) {
|
||||
if len(args) < 2 {
|
||||
return ParseResult{}, errors.New("at least one source extension and a target extension are required")
|
||||
}
|
||||
|
||||
target := NormalizeTargetExtension(args[len(args)-1])
|
||||
if target == "" {
|
||||
return ParseResult{}, errors.New("target extension cannot be empty")
|
||||
}
|
||||
if !strings.HasPrefix(target, ".") {
|
||||
return ParseResult{}, fmt.Errorf("target extension %q must start with '.'", target)
|
||||
}
|
||||
if len(target) == 1 {
|
||||
return ParseResult{}, fmt.Errorf("target extension %q must include characters after '.'", target)
|
||||
}
|
||||
|
||||
rawSources := args[:len(args)-1]
|
||||
trimmedSources := make([]string, len(rawSources))
|
||||
for i, src := range rawSources {
|
||||
trimmed := strings.TrimSpace(src)
|
||||
if trimmed == "" {
|
||||
return ParseResult{}, errors.New("source extensions cannot be empty")
|
||||
}
|
||||
if !strings.HasPrefix(trimmed, ".") {
|
||||
return ParseResult{}, fmt.Errorf("source extension %q must start with '.'", trimmed)
|
||||
}
|
||||
if len(trimmed) == 1 {
|
||||
return ParseResult{}, fmt.Errorf("source extension %q must include characters after '.'", trimmed)
|
||||
}
|
||||
trimmedSources[i] = trimmed
|
||||
}
|
||||
|
||||
canonical, display, duplicates := NormalizeSourceExtensions(trimmedSources)
|
||||
targetCanonical := CanonicalExtension(target)
|
||||
|
||||
filteredCanonical := make([]string, 0, len(canonical))
|
||||
filteredDisplay := make([]string, 0, len(display))
|
||||
noOps := make([]string, 0)
|
||||
for i, canon := range canonical {
|
||||
if canon == targetCanonical {
|
||||
noOps = append(noOps, display[i])
|
||||
continue
|
||||
}
|
||||
filteredCanonical = append(filteredCanonical, canon)
|
||||
filteredDisplay = append(filteredDisplay, display[i])
|
||||
}
|
||||
|
||||
if len(filteredCanonical) == 0 {
|
||||
return ParseResult{}, errors.New("all source extensions match the target extension; provide at least one distinct source extension")
|
||||
}
|
||||
|
||||
return ParseResult{
|
||||
SourcesCanonical: filteredCanonical,
|
||||
SourcesDisplay: filteredDisplay,
|
||||
Duplicates: duplicates,
|
||||
NoOps: noOps,
|
||||
Target: target,
|
||||
}, nil
|
||||
}
|
||||
Reference in New Issue
Block a user