From 1655d560910368256ccec8ee04fea10e077376da Mon Sep 17 00:00:00 2001 From: Jeffrey Faer Date: Tue, 7 Jan 2025 16:32:15 -0700 Subject: [PATCH] fix: Make prefix_order case insensitive when case=no. (#60) See the history of this PR to see how prefixes.out has changed. --- goldens/prefixes.in | 80 ++++++++++++++++++++++------------------ goldens/prefixes.out | 80 ++++++++++++++++++++++------------------ keepsorted/block.go | 20 ++++------ keepsorted/line_group.go | 4 -- keepsorted/options.go | 8 ++-- 5 files changed, 101 insertions(+), 91 deletions(-) diff --git a/goldens/prefixes.in b/goldens/prefixes.in index be6e28a..13d6097 100644 --- a/goldens/prefixes.in +++ b/goldens/prefixes.in @@ -1,42 +1,52 @@ preferred prefixes putting 'build_target' before 'branch_name': -build_specs { - # keep-sorted-test start prefix_order=build_target,branch_name - build_target: "//foo/baz" - branch_name: "dev" - build_target: "//foo/bar" - branch_name: "prod" - # keep-sorted-test end -} + build_specs { + # keep-sorted-test start prefix_order=build_target,branch_name + build_target: "//foo/baz" + branch_name: "dev" + build_target: "//foo/bar" + branch_name: "prod" + # keep-sorted-test end + } Put the specified prefixes at the end: -items = [ - # keep-sorted-test start prefix_order=,FOO,BAR - FOO, - DING, - BAR - BATS, - # keep-sorted-test end -] + items = [ + # keep-sorted-test start prefix_order=,FOO,BAR + FOO, + DING, + BAR + BATS, + # keep-sorted-test end + ] + +Case insensitive put the specified prefixes at the end: + items = [ + # keep-sorted-test start case=no prefix_order=,foo,bar + FOO, + DING, + BAR + BATS, + # keep-sorted-test end + ] Put a group of items in the beginning, another group at the end: -// keep-sorted-test start prefix_order=INIT_,,FINAL_ -INIT_FOO, -FINAL_FOO, -INIT_BAR, -FINAL_BAR, -DO_STUFF, -DO_MORE_STUFF, -ZAP_THINGS -// keep-sorted-test end + // keep-sorted-test start prefix_order=INIT_,,FINAL_ + INIT_FOO, + FINAL_FOO, + INIT_BAR, + FINAL_BAR, + DO_STUFF, + DO_MORE_STUFF, + ZAP_THINGS + // keep-sorted-test end preferred prefixes with comments: -build_specs { - # keep-sorted-test start prefix_order=build_target,branch_name - build_target: "//foo/baz" - # required for development. - branch_name: "dev" - # raise the bar! - build_target: "//foo/bar" - branch_name: "prod" - # keep-sorted-test end -} + build_specs { + # keep-sorted-test start prefix_order=build_target,branch_name + build_target: "//foo/baz" + # required for development. + branch_name: "dev" + # raise the bar! + build_target: "//foo/bar" + branch_name: "prod" + # keep-sorted-test end + } diff --git a/goldens/prefixes.out b/goldens/prefixes.out index 774fc36..6735c2f 100644 --- a/goldens/prefixes.out +++ b/goldens/prefixes.out @@ -1,42 +1,52 @@ preferred prefixes putting 'build_target' before 'branch_name': -build_specs { - # keep-sorted-test start prefix_order=build_target,branch_name - build_target: "//foo/bar" - build_target: "//foo/baz" - branch_name: "dev" - branch_name: "prod" - # keep-sorted-test end -} + build_specs { + # keep-sorted-test start prefix_order=build_target,branch_name + build_target: "//foo/bar" + build_target: "//foo/baz" + branch_name: "dev" + branch_name: "prod" + # keep-sorted-test end + } Put the specified prefixes at the end: -items = [ - # keep-sorted-test start prefix_order=,FOO,BAR - BATS, - DING, - FOO, - BAR - # keep-sorted-test end -] + items = [ + # keep-sorted-test start prefix_order=,FOO,BAR + BATS, + DING, + FOO, + BAR + # keep-sorted-test end + ] + +Case insensitive put the specified prefixes at the end: + items = [ + # keep-sorted-test start case=no prefix_order=,foo,bar + BATS, + DING, + FOO, + BAR + # keep-sorted-test end + ] Put a group of items in the beginning, another group at the end: -// keep-sorted-test start prefix_order=INIT_,,FINAL_ -INIT_BAR, -INIT_FOO, -DO_MORE_STUFF, -DO_STUFF, -ZAP_THINGS, -FINAL_BAR, -FINAL_FOO -// keep-sorted-test end + // keep-sorted-test start prefix_order=INIT_,,FINAL_ + INIT_BAR, + INIT_FOO, + DO_MORE_STUFF, + DO_STUFF, + ZAP_THINGS, + FINAL_BAR, + FINAL_FOO + // keep-sorted-test end preferred prefixes with comments: -build_specs { - # keep-sorted-test start prefix_order=build_target,branch_name - # raise the bar! - build_target: "//foo/bar" - build_target: "//foo/baz" - # required for development. - branch_name: "dev" - branch_name: "prod" - # keep-sorted-test end -} + build_specs { + # keep-sorted-test start prefix_order=build_target,branch_name + # raise the bar! + build_target: "//foo/bar" + build_target: "//foo/baz" + # required for development. + branch_name: "dev" + branch_name: "prod" + # keep-sorted-test end + } diff --git a/keepsorted/block.go b/keepsorted/block.go index 386bb24..460d15c 100644 --- a/keepsorted/block.go +++ b/keepsorted/block.go @@ -382,24 +382,20 @@ func (b block) lessFn() cmpFunc[lineGroup] { // // An empty prefix can be used to move "non-matching" entries to a position // between other prefixes. - type prefixWeight struct { - prefix string - weight int - } - var prefixWeights []prefixWeight + prefixWeights := make(map[string]int) for i, p := range b.metadata.opts.PrefixOrder { - prefixWeights = append(prefixWeights, prefixWeight{p, i - len(b.metadata.opts.PrefixOrder)}) + prefixWeights[p] = i - len(b.metadata.opts.PrefixOrder) } // Sort prefixes longest -> shortest to find the most appropriate weight. - slices.SortStableFunc(prefixWeights, comparing(func(pw prefixWeight) int { return len(pw.prefix) }).reversed()) + longestFirst := comparing(func(s string) int { return len(s) }).reversed() + prefixes := slices.SortedStableFunc(slices.Values(b.metadata.opts.PrefixOrder), longestFirst) prefixOrder := comparing(func(lg lineGroup) int { - for _, w := range prefixWeights { - if lg.hasPrefix(w.prefix) { - return w.weight - } + p, ok := b.metadata.opts.hasPrefix(lg.joinedLines(), slices.Values(prefixes)) + if !ok { + return 0 } - return 0 + return prefixWeights[p] }) // Combinations of switches (for example, case-insensitive and numeric diff --git a/keepsorted/line_group.go b/keepsorted/line_group.go index 9a333af..fdedbf5 100644 --- a/keepsorted/line_group.go +++ b/keepsorted/line_group.go @@ -309,10 +309,6 @@ func (lg lineGroup) append(s string) { lg.lines[len(lg.lines)-1] = lg.lines[len(lg.lines)-1] + s } -func (lg lineGroup) hasPrefix(s string) bool { - return strings.HasPrefix(lg.joinedLines(), s) -} - func (lg lineGroup) hasSuffix(s string) bool { return len(lg.lines) > 0 && strings.HasSuffix(lg.lines[len(lg.lines)-1], s) } diff --git a/keepsorted/options.go b/keepsorted/options.go index 9cd1160..1283d59 100644 --- a/keepsorted/options.go +++ b/keepsorted/options.go @@ -15,7 +15,6 @@ package keepsorted import ( - "cmp" "errors" "fmt" "iter" @@ -171,10 +170,9 @@ func parseBlockOptions(commentMarker, options string, defaults blockOptions) (_ if cm := guessCommentMarker(commentMarker); cm != "" { ret.setCommentMarker(cm) } - if len(ret.IgnorePrefixes) > 1 { - // Look at longer prefixes first, in case one of these prefixes is a prefix of another. - slices.SortFunc(ret.IgnorePrefixes, func(a string, b string) int { return cmp.Compare(len(b), len(a)) }) - } + // Look at longer prefixes first, in case one of these prefixes is a prefix of another. + longestFirst := comparing(func(s string) int { return len(s) }).reversed() + slices.SortFunc(ret.IgnorePrefixes, longestFirst) if warn := validate(&ret); len(warn) > 0 { warns = append(warns, warn...)