96 lines
2.1 KiB
Go
96 lines
2.1 KiB
Go
package sequence
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"path/filepath"
|
|
"strings"
|
|
)
|
|
|
|
// Placement controls where a sequence number is inserted.
|
|
type Placement string
|
|
|
|
const (
|
|
// PlacementSuffix appends the sequence number after the filename stem.
|
|
PlacementSuffix Placement = "suffix"
|
|
// PlacementPrefix inserts the sequence number before the filename stem.
|
|
PlacementPrefix Placement = "prefix"
|
|
)
|
|
|
|
// Options captures configuration for numbering operations.
|
|
type Options struct {
|
|
WorkingDir string
|
|
Start int
|
|
Width int
|
|
WidthSet bool
|
|
NumberPrefix string
|
|
NumberSuffix string
|
|
Placement Placement
|
|
Separator string
|
|
IncludeHidden bool
|
|
IncludeDirectories bool
|
|
Recursive bool
|
|
Extensions []string
|
|
DryRun bool
|
|
AutoApply bool
|
|
}
|
|
|
|
// DefaultOptions returns a copy of the default configuration.
|
|
func DefaultOptions() Options {
|
|
return Options{
|
|
Start: 1,
|
|
Width: 3,
|
|
Placement: PlacementPrefix,
|
|
Separator: "_",
|
|
}
|
|
}
|
|
|
|
func validateOptions(opts *Options) error {
|
|
if opts == nil {
|
|
return errors.New("options cannot be nil")
|
|
}
|
|
|
|
if opts.WorkingDir == "" {
|
|
return errors.New("working directory must be provided")
|
|
}
|
|
|
|
abs, err := filepath.Abs(opts.WorkingDir)
|
|
if err != nil {
|
|
return fmt.Errorf("resolve working directory: %w", err)
|
|
}
|
|
opts.WorkingDir = abs
|
|
|
|
if opts.Start < 1 {
|
|
return errors.New("start must be >= 1")
|
|
}
|
|
|
|
if opts.Width < 0 {
|
|
return errors.New("width cannot be negative")
|
|
}
|
|
if opts.WidthSet && opts.Width < 1 {
|
|
return errors.New("width must be >= 1 when specified")
|
|
}
|
|
|
|
switch opts.Placement {
|
|
case PlacementPrefix, PlacementSuffix:
|
|
// ok
|
|
case "":
|
|
opts.Placement = PlacementSuffix
|
|
default:
|
|
return fmt.Errorf("unsupported placement %q", opts.Placement)
|
|
}
|
|
|
|
if strings.ContainsAny(opts.Separator, "/\\") {
|
|
return errors.New("separator cannot contain path separators")
|
|
}
|
|
|
|
if strings.ContainsAny(opts.NumberPrefix, "/\\") {
|
|
return errors.New("number prefix cannot contain path separators")
|
|
}
|
|
if strings.ContainsAny(opts.NumberSuffix, "/\\") {
|
|
return errors.New("number suffix cannot contain path separators")
|
|
}
|
|
|
|
return nil
|
|
}
|