Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Allow default options to be customzied with a flag. #35

Merged
merged 5 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 37 additions & 11 deletions cmd/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ import (
)

type Config struct {
id string
operation operation
modifiedLines []keepsorted.LineRange
id string
defaultOptions keepsorted.BlockOptions
operation operation
modifiedLines []keepsorted.LineRange
}

func (c *Config) FromFlags(fs *flag.FlagSet) {
Expand All @@ -45,13 +46,37 @@ func (c *Config) FromFlags(fs *flag.FlagSet) {
panic(err)
}

c.defaultOptions = keepsorted.DefaultBlockOptions()
fs.Var(&blockOptionsFlag{&c.defaultOptions}, "default-options", "The options keep-sorted will use to sort. Per-block overrides apply on top of these options. Note: list options like prefix_order are not merged with per-block overrides. They are completely overridden.")

of := &operationFlag{op: &c.operation}
if err := of.Set("fix"); err != nil {
panic(err)
}
fs.Var(of, "mode", fmt.Sprintf("Determines what mode to run this tool in. One of %q", knownModes()))

fs.Var(&lineRangeFlag{lineRanges: &c.modifiedLines}, "lines", "Line ranges of the form \"start:end\". Only processes keep-sorted blocks that overlap with the given line ranges. Can only be used when fixing a single file.")
fs.Var(&lineRangeFlag{lineRanges: &c.modifiedLines}, "lines", "Line ranges of the form \"start:end\". Only processes keep-sorted blocks that overlap with the given line ranges. Can only be used when fixing a single file. This flag can either be a comma-separated list of line ranges, or it can be specified multiple times on the command line to specify multiple line ranges.")
}

type blockOptionsFlag struct {
opts *keepsorted.BlockOptions
}

func (f *blockOptionsFlag) String() string {
return f.opts.String()
}

func (f *blockOptionsFlag) Set(val string) error {
opts, err := keepsorted.ParseBlockOptions(val)
if err != nil {
return err
}
*f.opts = opts
return nil
}

func (f *blockOptionsFlag) Type() string {
return "options"
}

var (
Expand All @@ -67,7 +92,7 @@ func knownModes() []string {
return ms
}

type operation func(id string, filenames []string, modifiedLines []keepsorted.LineRange) (ok bool, err error)
type operation func(fixer *keepsorted.Fixer, filenames []string, modifiedLines []keepsorted.LineRange) (ok bool, err error)

type operationFlag struct {
op *operation
Expand All @@ -83,6 +108,7 @@ func (f *operationFlag) Set(val string) error {
if op == nil {
return fmt.Errorf("unknown mode %q. Valid modes: %q", val, knownModes())
}
f.s = val
*f.op = op
return nil
}
Expand Down Expand Up @@ -116,7 +142,7 @@ func (f *lineRangeFlag) Set(val string) error {
}

func (f *lineRangeFlag) Type() string {
return "line ranges"
return "line_ranges"
}

func (f *lineRangeFlag) Append(val string) error {
Expand Down Expand Up @@ -185,16 +211,16 @@ func Run(c *Config, files []string) (ok bool, err error) {
return false, errors.New("cannot specify modifiedLines with more than one file")
}

return c.operation(c.id, files, c.modifiedLines)
return c.operation(keepsorted.New(c.id, c.defaultOptions), files, c.modifiedLines)
}

func fix(id string, filenames []string, modifiedLines []keepsorted.LineRange) (ok bool, err error) {
func fix(fixer *keepsorted.Fixer, filenames []string, modifiedLines []keepsorted.LineRange) (ok bool, err error) {
for _, fn := range filenames {
contents, err := read(fn)
if err != nil {
return false, err
}
if want, alreadyFixed := keepsorted.New(id).Fix(contents, modifiedLines); fn == stdin || !alreadyFixed {
if want, alreadyFixed := fixer.Fix(contents, modifiedLines); fn == stdin || !alreadyFixed {
if err := write(fn, want); err != nil {
return false, err
}
Expand All @@ -203,14 +229,14 @@ func fix(id string, filenames []string, modifiedLines []keepsorted.LineRange) (o
return true, nil
}

func lint(id string, filenames []string, modifiedLines []keepsorted.LineRange) (ok bool, err error) {
func lint(fixer *keepsorted.Fixer, filenames []string, modifiedLines []keepsorted.LineRange) (ok bool, err error) {
var fs []*keepsorted.Finding
for _, fn := range filenames {
contents, err := read(fn)
if err != nil {
return false, err
}
fs = append(fs, keepsorted.New(id).Findings(fn, contents, modifiedLines)...)
fs = append(fs, fixer.Findings(fn, contents, modifiedLines)...)
}

if len(fs) == 0 {
Expand Down
4 changes: 2 additions & 2 deletions keepsorted/block.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ func (f *Fixer) newBlocks(lines []string, offset int, include func(start, end in
continue
}

opts, err := f.parseBlockOptions(start.line)
opts, err := parseBlockOptions(start.line, f.defaultOptions)
if err != nil {
// TODO(b/250608236): Is there a better way to surface this error?
log.Err(fmt.Errorf("keep-sorted block at index %d had bad start directive: %w", start.index+offset, err)).Msg("")
Expand Down Expand Up @@ -238,7 +238,7 @@ func (b block) sorted() (sorted []string, alreadySorted bool) {
}

groups := groupLines(lines, b.metadata)
log.Printf("%d groups for block at index %d are (options %#v)", len(groups), b.start, b.metadata.opts)
log.Printf("%d groups for block at index %d are (options %v)", len(groups), b.start, b.metadata.opts)
for _, lg := range groups {
log.Printf("%#v", lg)
}
Expand Down
4 changes: 3 additions & 1 deletion keepsorted/keep_sorted.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,17 @@ const (
type Fixer struct {
ID string

defaultOptions blockOptions
startDirective string
endDirective string
}

// New creates a new fixer with the given string as its identifier.
// By default, id is "keep-sorted"
func New(id string) *Fixer {
func New(id string, defaultOptions BlockOptions) *Fixer {
return &Fixer{
ID: id,
defaultOptions: defaultOptions.opts,
startDirective: id + " start",
endDirective: id + " end",
}
Expand Down
Loading
Loading