@@ -2,8 +2,6 @@ package retrosort
22
33import (
44 "fmt"
5- "maps"
6- "regexp"
75 "slices"
86 "strings"
97
@@ -13,104 +11,62 @@ import (
1311// Sort converts a list of paths to files into a mapping from source paths
1412// to destination paths where no directory in the destinations
1513// contains any more than size files
16- func Sort (files []string , size int ) map [string ]string {
17- group := newGroup (files )
14+ func Sort (sources []string , size int ) map [string ]string {
15+ group := newGroup (sources )
1816
1917 groups := group .sort (size )
2018
2119 return groups .fileMap ()
2220}
2321
24- func getPrefix (fn string , prefixSize int ) string {
25- fn = strings .ToLower (filepath .Base (fn ))
26-
27- if len (fn ) < prefixSize {
28- return fn
29- }
30-
31- return fn [:prefixSize ]
32- }
33-
34- func getCategory (fn string ) string {
35- c := strings .ToLower (filepath .Base (fn ))[0 ]
36-
37- if c >= 'a' && c <= 'z' {
38- return string (c )
39- }
40-
41- return "#"
42- }
43-
44- type file struct {
45- name string
46- sortName string
22+ type group struct {
23+ entries []entry
24+ prefixSize int
25+ path string
4726}
4827
49- var sortNameRe = regexp .MustCompile (`[^a-z0-9]+` )
50-
51- func newFile (fn string ) file {
52- if TosecMode {
53- fn = doTosec (fn )
54- }
55-
56- sortName := filepath .Base (fn )
57- sortName = strings .ToLower (sortName )
58- sortName = sortNameRe .ReplaceAllString (sortName , "_" )
28+ func newGroup (sources []string ) group {
29+ groupedSources := make (map [string ][]string )
30+ for _ , fn := range sources {
31+ name := filepath .Base (fn )
5932
60- return file {
61- name : fn ,
62- sortName : sortName ,
63- }
64- }
33+ if TosecMode {
34+ name = tosecName (name )
35+ }
6536
66- func (f file ) prefix (size int ) string {
67- if size == 1 {
68- return getCategory (f .sortName [:size ])
69- }
37+ if _ , ok := groupedSources [name ]; ! ok {
38+ groupedSources [name ] = make ([]string , 0 )
39+ }
7040
71- if size >= len (f .sortName ) {
72- return f .sortName
41+ groupedSources [name ] = append (groupedSources [name ], fn )
7342 }
7443
75- return f .sortName [:size ]
76- }
77-
78- type group struct {
79- files []file
80- prefixSize int
81- path string
82- }
83-
84- func newGroup (names []string ) group {
85- dedupFiles := make (map [string ]file )
86- for _ , name := range names {
87- f := newFile (name )
88- dedupFiles [f .name ] = f
44+ entries := make ([]entry , 0 )
45+ for name , sources := range groupedSources {
46+ entries = append (entries , newEntry (name , sources ))
8947 }
9048
91- files := slices .Collect (maps .Values (dedupFiles ))
92-
93- slices .SortStableFunc (files , func (a , b file ) int {
49+ slices .SortStableFunc (entries , func (a , b entry ) int {
9450 return strings .Compare (a .sortName , b .sortName )
9551 })
9652
9753 return group {
98- files : files ,
54+ entries : entries ,
9955 prefixSize : 0 ,
10056 }
10157}
10258
10359func (g group ) Len () int {
104- return len (g .files )
60+ return len (g .entries )
10561}
10662
10763func (g group ) name () string {
10864 if g .prefixSize == 0 {
10965 return ""
11066 }
11167
112- a := g .files [0 ].prefix (g .prefixSize )
113- b := g .files [g .Len ()- 1 ].prefix (g .prefixSize )
68+ a := g .entries [0 ].prefix (g .prefixSize )
69+ b := g .entries [g .Len ()- 1 ].prefix (g .prefixSize )
11470
11571 if g .prefixSize == 1 {
11672 a = getCategory (a )
@@ -133,8 +89,8 @@ func (g group) split(prefixSize, size int) (groups, bool) {
13389 prefixes := make ([]string , 0 )
13490
13591 // Fail if any individual prefix is too big
136- for _ , file := range g .files {
137- prefix := file .prefix (prefixSize )
92+ for _ , entry := range g .entries {
93+ prefix := entry .prefix (prefixSize )
13894
13995 if counts [prefix ] == 0 {
14096 prefixes = append (prefixes , prefix )
@@ -157,7 +113,7 @@ func (g group) split(prefixSize, size int) (groups, bool) {
157113 for i , prefix := range prefixes {
158114 // Copy
159115 for j := 0 ; j < counts [prefix ]; j ++ {
160- cur .files = append (cur .files , g .files [pos ])
116+ cur .entries = append (cur .entries , g .entries [pos ])
161117 pos ++
162118 }
163119
@@ -170,7 +126,7 @@ func (g group) split(prefixSize, size int) (groups, bool) {
170126 }
171127 }
172128
173- if len (cur .files ) > 0 {
129+ if len (cur .entries ) > 0 {
174130 groups = append (groups , cur )
175131 }
176132
@@ -216,8 +172,10 @@ func (g group) String() string {
216172func (g group ) fileMap () map [string ]string {
217173 out := make (map [string ]string )
218174
219- for _ , file := range g .files {
220- out [file .name ] = filepath .Join (g .path , g .name (), filepath .Base (file .name ))
175+ for _ , entry := range g .entries {
176+ for src , dst := range entry .fileMap () {
177+ out [src ] = filepath .Join (g .path , g .name (), dst )
178+ }
221179 }
222180
223181 return out
@@ -230,13 +188,7 @@ func (gs groups) fileMap() map[string]string {
230188
231189 for _ , g := range gs {
232190 for src , dst := range g .fileMap () {
233- if fileNames , ok := tosecFiles [src ]; TosecMode && ok {
234- for _ , fn := range fileNames {
235- out [fn ] = filepath .Join (dst , filepath .Base (fn ))
236- }
237- } else {
238- out [src ] = dst
239- }
191+ out [src ] = dst
240192 }
241193 }
242194
0 commit comments