Merge branch 'main' into v2
* main: refactor: use slices package for sorting (#10136) build: handle multiple general release notes build: no need to build on the branches that just trigger tags
This commit is contained in:
@@ -3,6 +3,9 @@ name: Build Syncthing
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches-ignore:
|
||||
- release
|
||||
- release-rc*
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
)
|
||||
@@ -37,7 +37,9 @@ func uploadPanicLogs(ctx context.Context, urlBase, dir string) {
|
||||
return
|
||||
}
|
||||
|
||||
sort.Sort(sort.Reverse(sort.StringSlice(files)))
|
||||
slices.SortFunc(files, func(a, b string) int {
|
||||
return strings.Compare(b, a)
|
||||
})
|
||||
for _, file := range files {
|
||||
if strings.Contains(file, ".reported.") {
|
||||
// We've already sent this file. It'll be cleaned out at some
|
||||
|
||||
@@ -117,8 +117,8 @@ func (m *tokenManager) saveLocked() {
|
||||
for token, expiry := range m.tokens.Tokens {
|
||||
tokens = append(tokens, tokenExpiry{token, expiry})
|
||||
}
|
||||
slices.SortFunc(tokens, func(i, j tokenExpiry) int {
|
||||
return int(i.expiry - j.expiry)
|
||||
slices.SortFunc(tokens, func(a, b tokenExpiry) int {
|
||||
return int(a.expiry - b.expiry)
|
||||
})
|
||||
// Remove the oldest tokens.
|
||||
for _, token := range tokens[:len(tokens)-m.maxItems] {
|
||||
|
||||
@@ -18,7 +18,6 @@ import (
|
||||
"os"
|
||||
"reflect"
|
||||
"slices"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
@@ -338,8 +337,8 @@ func (cfg *Configuration) prepareDeviceList() map[protocol.DeviceID]*DeviceConfi
|
||||
// - sorted by ID
|
||||
// Happen before preparting folders as that needs a correct device list.
|
||||
cfg.Devices = ensureNoDuplicateOrEmptyIDDevices(cfg.Devices)
|
||||
sort.Slice(cfg.Devices, func(a, b int) bool {
|
||||
return cfg.Devices[a].DeviceID.Compare(cfg.Devices[b].DeviceID) == -1
|
||||
slices.SortFunc(cfg.Devices, func(a, b DeviceConfiguration) int {
|
||||
return a.DeviceID.Compare(b.DeviceID)
|
||||
})
|
||||
|
||||
// Build a list of available devices
|
||||
|
||||
@@ -8,7 +8,7 @@ package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"slices"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
)
|
||||
@@ -100,8 +100,8 @@ func sortedObservedFolderSlice(input map[string]ObservedFolder) []ObservedFolder
|
||||
for _, folder := range input {
|
||||
output = append(output, folder)
|
||||
}
|
||||
sort.Slice(output, func(i, j int) bool {
|
||||
return output[i].Time.Before(output[j].Time)
|
||||
slices.SortFunc(output, func(a, b ObservedFolder) int {
|
||||
return a.Time.Compare(b.Time)
|
||||
})
|
||||
return output
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
"fmt"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
@@ -288,8 +288,8 @@ func (f *FolderConfiguration) prepare(myID protocol.DeviceID, existingDevices ma
|
||||
f.Devices = ensureDevicePresent(f.Devices, myID)
|
||||
f.Devices = ensureNoUntrustedTrustingSharing(f, f.Devices, existingDevices)
|
||||
|
||||
sort.Slice(f.Devices, func(a, b int) bool {
|
||||
return f.Devices[a].DeviceID.Compare(f.Devices[b].DeviceID) == -1
|
||||
slices.SortFunc(f.Devices, func(a, b FolderDeviceConfiguration) int {
|
||||
return a.DeviceID.Compare(b.DeviceID)
|
||||
})
|
||||
|
||||
if f.RescanIntervalS > MaxRescanIntervalS {
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"slices"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/config"
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
@@ -52,8 +52,8 @@ type standardBlockPullReorderer struct {
|
||||
|
||||
func newStandardBlockPullReorderer(id protocol.DeviceID, otherDevices []protocol.DeviceID) *standardBlockPullReorderer {
|
||||
allDevices := append(otherDevices, id)
|
||||
sort.Slice(allDevices, func(i, j int) bool {
|
||||
return allDevices[i].Compare(allDevices[j]) == -1
|
||||
slices.SortFunc(allDevices, func(a, b protocol.DeviceID) int {
|
||||
return a.Compare(b)
|
||||
})
|
||||
// Find our index
|
||||
myIndex := -1
|
||||
|
||||
@@ -8,7 +8,7 @@ package model
|
||||
|
||||
import (
|
||||
"reflect"
|
||||
"sort"
|
||||
"slices"
|
||||
"testing"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/protocol"
|
||||
@@ -65,8 +65,8 @@ func Test_inOrderBlockPullReorderer_Reorder(t *testing.T) {
|
||||
func Test_standardBlockPullReorderer_Reorder(t *testing.T) {
|
||||
// Order the devices, so we know their ordering ahead of time.
|
||||
devices := []protocol.DeviceID{myID, device1, device2}
|
||||
sort.Slice(devices, func(i, j int) bool {
|
||||
return devices[i].Compare(devices[j]) == -1
|
||||
slices.SortFunc(devices, func(a, b protocol.DeviceID) int {
|
||||
return a.Compare(b)
|
||||
})
|
||||
|
||||
blocks := func(i ...int) []protocol.BlockInfo {
|
||||
|
||||
+4
-2
@@ -13,7 +13,7 @@ import (
|
||||
"math/rand"
|
||||
"path/filepath"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/syncthing/syncthing/internal/db"
|
||||
@@ -1226,7 +1226,9 @@ func (f *folder) Errors() []FileError {
|
||||
errors := make([]FileError, scanLen+len(f.pullErrors))
|
||||
copy(errors[:scanLen], f.scanErrors)
|
||||
copy(errors[scanLen:], f.pullErrors)
|
||||
sort.Sort(fileErrorList(errors))
|
||||
slices.SortFunc(errors, func(a, b FileError) int {
|
||||
return strings.Compare(a.Path, b.Path)
|
||||
})
|
||||
return errors
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@ package model
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/syncthing/syncthing/internal/itererr"
|
||||
"github.com/syncthing/syncthing/lib/config"
|
||||
@@ -104,7 +105,9 @@ func (f *receiveEncryptedFolder) revertHandleDirs(dirs []string) {
|
||||
go f.pullScannerRoutine(scanChan)
|
||||
defer close(scanChan)
|
||||
|
||||
sort.Sort(sort.Reverse(sort.StringSlice(dirs)))
|
||||
slices.SortFunc(dirs, func(a, b string) int {
|
||||
return strings.Compare(b, a)
|
||||
})
|
||||
for _, dir := range dirs {
|
||||
if err := f.deleteDirOnDisk(dir, scanChan); err != nil {
|
||||
f.newScanError(dir, fmt.Errorf("deleting unexpected dir: %w", err))
|
||||
|
||||
@@ -7,7 +7,8 @@
|
||||
package model
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"slices"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/syncthing/syncthing/internal/itererr"
|
||||
@@ -208,7 +209,9 @@ func (q *deleteQueue) handle(fi protocol.FileInfo) (bool, error) {
|
||||
|
||||
func (q *deleteQueue) flush() ([]string, error) {
|
||||
// Process directories from the leaves inward.
|
||||
sort.Sort(sort.Reverse(sort.StringSlice(q.dirs)))
|
||||
slices.SortFunc(q.dirs, func(a, b string) int {
|
||||
return strings.Compare(b, a)
|
||||
})
|
||||
|
||||
var firstError error
|
||||
var deleted []string
|
||||
|
||||
@@ -14,7 +14,7 @@ import (
|
||||
"fmt"
|
||||
"io"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"slices"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -1854,7 +1854,9 @@ func (f *sendReceiveFolder) moveForConflict(name, lastModBy string, scanChan cha
|
||||
if f.MaxConflicts > -1 {
|
||||
matches := existingConflicts(name, f.mtimefs)
|
||||
if len(matches) > f.MaxConflicts {
|
||||
sort.Sort(sort.Reverse(sort.StringSlice(matches)))
|
||||
slices.SortFunc(matches, func(a, b string) int {
|
||||
return strings.Compare(b, a)
|
||||
})
|
||||
for _, match := range matches[f.MaxConflicts:] {
|
||||
if gerr := f.mtimefs.Remove(match); gerr != nil {
|
||||
l.Debugln(f, "removing extra conflict", gerr)
|
||||
@@ -2196,20 +2198,6 @@ type FileError struct {
|
||||
Err string `json:"error"`
|
||||
}
|
||||
|
||||
type fileErrorList []FileError
|
||||
|
||||
func (l fileErrorList) Len() int {
|
||||
return len(l)
|
||||
}
|
||||
|
||||
func (l fileErrorList) Less(a, b int) bool {
|
||||
return l[a].Path < l[b].Path
|
||||
}
|
||||
|
||||
func (l fileErrorList) Swap(a, b int) {
|
||||
l[a], l[b] = l[b], l[a]
|
||||
}
|
||||
|
||||
func conflictName(name, lastModBy string) string {
|
||||
ext := filepath.Ext(name)
|
||||
return name[:len(name)-len(ext)] + time.Now().Format(".sync-conflict-20060102-150405-") + lastModBy + ext
|
||||
|
||||
@@ -16,7 +16,8 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
rdebug "runtime/debug"
|
||||
"sort"
|
||||
"slices"
|
||||
"strings"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
@@ -145,7 +146,7 @@ func TestWalk(t *testing.T) {
|
||||
}
|
||||
tmp = append(tmp, f.File)
|
||||
}
|
||||
sort.Sort(fileList(tmp))
|
||||
slices.SortFunc(fileList(tmp), compareByName)
|
||||
files := fileList(tmp).testfiles()
|
||||
|
||||
if diff, equal := messagediff.PrettyDiff(testdata, files); !equal {
|
||||
@@ -584,23 +585,15 @@ func walkDir(fs fs.Filesystem, dir string, cfiler CurrentFiler, matcher *ignore.
|
||||
tmp = append(tmp, f.File)
|
||||
}
|
||||
}
|
||||
sort.Sort(fileList(tmp))
|
||||
slices.SortFunc(fileList(tmp), compareByName)
|
||||
|
||||
return tmp
|
||||
}
|
||||
|
||||
type fileList []protocol.FileInfo
|
||||
|
||||
func (l fileList) Len() int {
|
||||
return len(l)
|
||||
}
|
||||
|
||||
func (l fileList) Less(a, b int) bool {
|
||||
return l[a].Name < l[b].Name
|
||||
}
|
||||
|
||||
func (l fileList) Swap(a, b int) {
|
||||
l[a], l[b] = l[b], l[a]
|
||||
func compareByName(a, b protocol.FileInfo) int {
|
||||
return strings.Compare(a.Name, b.Name)
|
||||
}
|
||||
|
||||
func (l fileList) testfiles() testfileList {
|
||||
@@ -825,7 +818,7 @@ func TestIssue4841(t *testing.T) {
|
||||
}
|
||||
files = append(files, f.File)
|
||||
}
|
||||
sort.Sort(fileList(files))
|
||||
slices.SortFunc(fileList(files), compareByName)
|
||||
|
||||
if len(files) != 1 {
|
||||
t.Fatalf("Expected 1 file, got %d: %v", len(files), files)
|
||||
|
||||
@@ -8,7 +8,8 @@ package versioner
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"slices"
|
||||
"strings"
|
||||
|
||||
"github.com/syncthing/syncthing/lib/fs"
|
||||
)
|
||||
@@ -37,7 +38,9 @@ func (t emptyDirTracker) emptyDirs() []string {
|
||||
for dir := range t {
|
||||
empty = append(empty, dir)
|
||||
}
|
||||
sort.Sort(sort.Reverse(sort.StringSlice(empty)))
|
||||
slices.SortFunc(empty, func(a, b string) int {
|
||||
return strings.Compare(b, a)
|
||||
})
|
||||
return empty
|
||||
}
|
||||
|
||||
|
||||
@@ -16,3 +16,6 @@ example:
|
||||
|
||||
The release notes will also be included in candidate releases (e.g.
|
||||
v1.2.3-rc.1).
|
||||
|
||||
Additional notes will also be loaded from `v1.2.md` and `v1.md`, if they
|
||||
exist.
|
||||
|
||||
@@ -99,6 +99,11 @@ func main() {
|
||||
|
||||
// Write AUTHORS file
|
||||
|
||||
// Sort by author name
|
||||
slices.SortFunc(authors, func(a, b author) int {
|
||||
return strings.Compare(strings.ToLower(a.name), strings.ToLower(b.name))
|
||||
})
|
||||
|
||||
out, err := os.Create("AUTHORS")
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
||||
+21
-12
@@ -43,29 +43,38 @@ func main() {
|
||||
log.Fatalln("Must set $GITHUB_TOKEN")
|
||||
}
|
||||
|
||||
addl, err := additionalNotes(*ver)
|
||||
notes, err := additionalNotes(*ver)
|
||||
if err != nil {
|
||||
log.Fatalln("Gathering additional notes:", err)
|
||||
}
|
||||
notes, err := generatedNotes(*ver, *branch, *prevVer)
|
||||
gh, err := generatedNotes(*ver, *branch, *prevVer)
|
||||
if err != nil {
|
||||
log.Fatalln("Gathering github notes:", err)
|
||||
}
|
||||
notes = append(notes, gh)
|
||||
|
||||
if addl != "" {
|
||||
fmt.Println(addl)
|
||||
}
|
||||
fmt.Println(notes)
|
||||
fmt.Println(strings.Join(notes, "\n\n"))
|
||||
}
|
||||
|
||||
// Load potential additional release notes from within the repo
|
||||
func additionalNotes(newVer string) (string, error) {
|
||||
func additionalNotes(newVer string) ([]string, error) {
|
||||
var notes []string
|
||||
ver, _, _ := strings.Cut(newVer, "-")
|
||||
bs, err := os.ReadFile(fmt.Sprintf("relnotes/%s.md", ver))
|
||||
if os.IsNotExist(err) {
|
||||
return "", nil
|
||||
for {
|
||||
file := fmt.Sprintf("relnotes/%s.md", ver)
|
||||
if bs, err := os.ReadFile(file); err == nil {
|
||||
notes = append(notes, strings.TrimSpace(string(bs)))
|
||||
} else if !os.IsNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if idx := strings.LastIndex(ver, "."); idx > 0 {
|
||||
ver = ver[:idx]
|
||||
} else {
|
||||
break
|
||||
}
|
||||
}
|
||||
return string(bs), err
|
||||
return notes, nil
|
||||
}
|
||||
|
||||
// Load generated release notes (list of pull requests and contributors)
|
||||
@@ -105,5 +114,5 @@ func generatedNotes(newVer, targetCommit, prevVer string) (string, error) {
|
||||
if err := json.NewDecoder(res.Body).Decode(&resJSON); err != nil {
|
||||
return "", err
|
||||
}
|
||||
return resJSON.Body, nil
|
||||
return strings.TrimSpace(resJSON.Body), nil
|
||||
}
|
||||
|
||||
+4
-16
@@ -20,7 +20,7 @@ import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"sort"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
@@ -375,7 +375,9 @@ func mergeDirectoryContents(c ...[]fileInfo) []fileInfo {
|
||||
i++
|
||||
}
|
||||
|
||||
sort.Sort(fileInfoList(res))
|
||||
slices.SortFunc(res, func(a, b fileInfo) int {
|
||||
return strings.Compare(a.name, b.name)
|
||||
})
|
||||
return res
|
||||
}
|
||||
|
||||
@@ -404,20 +406,6 @@ func (f fileInfo) String() string {
|
||||
return fmt.Sprintf("%s %04o %d %x", f.name, f.mode, f.mod, f.hash)
|
||||
}
|
||||
|
||||
type fileInfoList []fileInfo
|
||||
|
||||
func (l fileInfoList) Len() int {
|
||||
return len(l)
|
||||
}
|
||||
|
||||
func (l fileInfoList) Less(a, b int) bool {
|
||||
return l[a].name < l[b].name
|
||||
}
|
||||
|
||||
func (l fileInfoList) Swap(a, b int) {
|
||||
l[a], l[b] = l[b], l[a]
|
||||
}
|
||||
|
||||
func startWalker(dir string, res chan<- fileInfo, abort <-chan struct{}) chan error {
|
||||
walker := func(path string, info os.FileInfo, err error) error {
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user