all: Add build constants for runtime.GOOS comparisons (#8442)

all: Add package runtimeos for runtime.GOOS comparisons

I grew tired of hand written string comparisons. This adds generated
constants for the GOOS values, and predefined Is$OS constants that can
be iffed on. In a couple of places I rewrote trivial switch:es to if:s,
and added Illumos where we checked for Solaris (because they are
effectively the same, and if we're going to target one of them that
would be Illumos...).
pull/8470/head
Jakob Borg 4 months ago committed by GitHub
parent f13d65262a
commit a3c724f2c3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 4
      build.go
  2. 3
      cmd/strelaysrv/main.go
  3. 2
      cmd/syncthing/main.go
  4. 6
      cmd/syncthing/monitor.go
  5. 18
      cmd/syncthing/openurl_unix.go
  6. 2
      lib/api/api.go
  7. 6
      lib/api/api_test.go
  8. 38
      lib/build/runtimeos.gen.go
  9. 43
      lib/build/runtimeos.sh
  10. 4
      lib/config/config.go
  11. 7
      lib/config/config_test.go
  12. 8
      lib/config/folderconfiguration.go
  13. 4
      lib/config/migrations.go
  14. 4
      lib/fs/basicfs.go
  15. 16
      lib/fs/basicfs_test.go
  16. 24
      lib/fs/basicfs_watch_test.go
  17. 6
      lib/fs/fakefs_test.go
  18. 11
      lib/fs/filesystem_test.go
  19. 8
      lib/fs/mtimefs_test.go
  20. 4
      lib/fs/tempname.go
  21. 7
      lib/fs/util.go
  22. 5
      lib/fs/util_test.go
  23. 9
      lib/fs/walkfs_test.go
  24. 4
      lib/ignore/ignore.go
  25. 13
      lib/ignore/ignore_test.go
  26. 43
      lib/locations/locations.go
  27. 8
      lib/model/folder_sendrecv.go
  28. 12
      lib/model/folder_sendrecv_test.go
  29. 4
      lib/model/folder_test.go
  30. 3
      lib/model/model.go
  31. 16
      lib/model/model_test.go
  32. 10
      lib/model/requests_test.go
  33. 8
      lib/model/utils_test.go
  34. 4
      lib/osutil/atomic.go
  35. 4
      lib/osutil/osutil.go
  36. 6
      lib/osutil/osutil_test.go
  37. 5
      lib/osutil/replacingwriter.go
  38. 5
      lib/osutil/rlimit_unix.go
  39. 6
      lib/osutil/traversessymlink_test.go
  40. 10
      lib/protocol/bep_extensions.go
  41. 4
      lib/protocol/protocol_test.go
  42. 8
      lib/scanner/walk.go
  43. 18
      lib/scanner/walk_test.go
  44. 12
      lib/upgrade/upgrade_common.go
  45. 4
      lib/upgrade/upgrade_test.go
  46. 4
      lib/upnp/upnp.go
  47. 4
      lib/versioner/external.go
  48. 4
      lib/versioner/external_test.go
  49. 4
      lib/watchaggregator/aggregator_test.go
  50. 5
      test/usage_unix.go
  51. 3
      test/util.go

@ -31,6 +31,8 @@ import (
"strings"
"text/template"
"time"
buildpkg "github.com/syncthing/syncthing/lib/build"
)
var (
@ -393,7 +395,7 @@ func test(tags []string, pkgs ...string) {
if runtime.GOARCH == "amd64" {
switch runtime.GOOS {
case "darwin", "linux", "freebsd": // , "windows": # See https://github.com/golang/go/issues/27089
case buildpkg.Darwin, buildpkg.Linux, buildpkg.FreeBSD: // , "windows": # See https://github.com/golang/go/issues/27089
args = append(args, "-race")
}
}

@ -14,7 +14,6 @@ import (
"os"
"os/signal"
"path/filepath"
"runtime"
"strings"
"sync/atomic"
"syscall"
@ -146,7 +145,7 @@ func main() {
log.Println("Connection limit", descriptorLimit)
go monitorLimits()
} else if err != nil && runtime.GOOS != "windows" {
} else if err != nil && !build.IsWindows {
log.Println("Assuming no connection limit, due to error retrieving rlimits:", err)
}

@ -199,7 +199,7 @@ func defaultVars() kong.Vars {
// Windows, the "default" options.logFile will later be replaced with the
// default path, unless the user has manually specified "-" or
// something else.
if runtime.GOOS == "windows" {
if build.IsWindows {
vars["logFile"] = "default"
} else {
vars["logFile"] = "-"

@ -15,11 +15,11 @@ import (
"os/exec"
"os/signal"
"path/filepath"
"runtime"
"strings"
"syscall"
"time"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/locations"
"github.com/syncthing/syncthing/lib/osutil"
@ -66,7 +66,7 @@ func monitorMain(options serveOptions) {
if err != nil {
l.Warnln("Failed to setup logging to file, proceeding with logging to stdout only:", err)
} else {
if runtime.GOOS == "windows" {
if build.IsWindows {
// Translate line breaks to Windows standard
fileDst = osutil.ReplacingWriter{
Writer: fileDst,
@ -315,7 +315,7 @@ func restartMonitor(args []string) error {
// opening the browser on startup.
os.Setenv("STRESTART", "yes")
if runtime.GOOS != "windows" {
if !build.IsWindows {
// syscall.Exec is the cleanest way to restart on Unixes as it
// replaces the current process with the new one, keeping the pid and
// controlling terminal and so on

@ -11,20 +11,18 @@ package main
import (
"os/exec"
"runtime"
"syscall"
"github.com/syncthing/syncthing/lib/build"
)
func openURL(url string) error {
switch runtime.GOOS {
case "darwin":
if build.IsDarwin {
return exec.Command("open", url).Run()
default:
cmd := exec.Command("xdg-open", url)
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
}
return cmd.Run()
}
cmd := exec.Command("xdg-open", url)
cmd.SysProcAttr = &syscall.SysProcAttr{
Setpgid: true,
}
return cmd.Run()
}

@ -1925,7 +1925,7 @@ func shouldRegenerateCertificate(cert tls.Certificate) error {
// On macOS, check for certificates issued on or after July 1st, 2019,
// with a longer validity time than 825 days.
cutoff := time.Date(2019, 7, 1, 0, 0, 0, 0, time.UTC)
if runtime.GOOS == "darwin" &&
if build.IsDarwin &&
leaf.NotBefore.After(cutoff) &&
leaf.NotAfter.Sub(leaf.NotBefore) > 825*24*time.Hour {
return errors.New("certificate incompatible with macOS 10.15 (Catalina)")

@ -19,7 +19,6 @@ import (
"os"
"path/filepath"
"reflect"
"runtime"
"strconv"
"strings"
"testing"
@ -27,6 +26,7 @@ import (
"github.com/d4l3k/messagediff"
"github.com/syncthing/syncthing/lib/assets"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/config"
connmocks "github.com/syncthing/syncthing/lib/connections/mocks"
discovermocks "github.com/syncthing/syncthing/lib/discover/mocks"
@ -1255,7 +1255,7 @@ func TestShouldRegenerateCertificate(t *testing.T) {
t.Error("expected no error:", err)
}
if runtime.GOOS == "darwin" {
if build.IsDarwin {
// Certificates with too long an expiry time are not allowed on macOS
crt, err = tlsutil.NewCertificateInMemory("foo.example.com", 1000)
if err != nil {
@ -1416,7 +1416,7 @@ func TestSanitizedHostname(t *testing.T) {
// be prone to false negatives if things change in the future, but likely
// not false positives.
func runningInContainer() bool {
if runtime.GOOS != "linux" {
if !build.IsLinux {
return false
}

@ -0,0 +1,38 @@
// Code generated by runtimeos.sh. DO NOT EDIT.
package build
import "runtime"
const (
AIX = "aix"
Android = "android"
Darwin = "darwin"
Dragonfly = "dragonfly"
FreeBSD = "freebsd"
Illumos = "illumos"
IOS = "ios"
JS = "js"
Linux = "linux"
NetBSD = "netbsd"
OpenBSD = "openbsd"
Plan9 = "plan9"
Solaris = "solaris"
Windows = "windows"
)
const (
IsAIX = runtime.GOOS == AIX
IsAndroid = runtime.GOOS == Android
IsDarwin = runtime.GOOS == Darwin
IsDragonfly = runtime.GOOS == Dragonfly
IsFreeBSD = runtime.GOOS == FreeBSD
IsIllumos = runtime.GOOS == Illumos
IsIOS = runtime.GOOS == IOS
IsJS = runtime.GOOS == JS
IsLinux = runtime.GOOS == Linux
IsNetBSD = runtime.GOOS == NetBSD
IsOpenBSD = runtime.GOOS == OpenBSD
IsPlan9 = runtime.GOOS == Plan9
IsSolaris = runtime.GOOS == Solaris
IsWindows = runtime.GOOS == Windows
)

@ -0,0 +1,43 @@
# Copyright (C) 2022 The Syncthing Authors.
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at https://mozilla.org/MPL/2.0/.
#!/bin/sh
# List known operating system/architecture combos, removing the
# architecture, and making constants of them.
osname() {
echo "$1" | awk '{print toupper(substr($1, 1, 1)) substr($1, 2)}' \
| sed s/aix/AIX/i \
| sed s/bsd/BSD/i \
| sed s/ios/IOS/i \
| sed s/js/JS/i
}
osconstants() {
echo "// Code generated by runtimeos.sh. DO NOT EDIT."
echo "package build"
echo "import \"runtime\""
echo "const ("
for OS in $(go tool dist list | sed 's|/.*||' | sort | uniq) ; do
name=$(osname "$OS")
echo "$name = \"$OS\""
done
echo ")"
echo
echo "const ("
for OS in $(go tool dist list | sed 's|/.*||' | sort | uniq) ; do
name=$(osname "$OS")
echo "Is$name = runtime.GOOS == $name"
done
echo ")"
}
osconstants > runtimeos.gen.go
gofmt -w -s runtimeos.gen.go

@ -15,13 +15,13 @@ import (
"net"
"net/url"
"os"
"runtime"
"sort"
"strconv"
"strings"
"github.com/pkg/errors"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/protocol"
"github.com/syncthing/syncthing/lib/util"
@ -549,7 +549,7 @@ loop:
}
func cleanSymlinks(filesystem fs.Filesystem, dir string) {
if runtime.GOOS == "windows" {
if build.IsWindows {
// We don't do symlinks on Windows. Additionally, there may
// be things that look like symlinks that are not, which we
// should leave alone. Deduplicated files, for example.

@ -23,6 +23,7 @@ import (
"github.com/d4l3k/messagediff"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/events"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/protocol"
@ -445,7 +446,7 @@ func TestVersioningConfig(t *testing.T) {
}
func TestIssue1262(t *testing.T) {
if runtime.GOOS != "windows" {
if !build.IsWindows {
t.Skipf("path gets converted to absolute as part of the filesystem initialization on linux")
}
@ -538,7 +539,7 @@ func TestFolderCheckPath(t *testing.T) {
path: "link",
err: nil,
})
} else if runtime.GOOS != "windows" {
} else if !build.IsWindows {
t.Log("running without symlink check")
t.Fatal(err)
}
@ -593,7 +594,7 @@ func TestNewSaveLoad(t *testing.T) {
}
func TestWindowsLineEndings(t *testing.T) {
if runtime.GOOS != "windows" {
if !build.IsWindows {
t.Skip("Windows specific")
}

@ -9,13 +9,13 @@ package config
import (
"errors"
"fmt"
"runtime"
"sort"
"strings"
"time"
"github.com/shirou/gopsutil/v3/disk"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/db"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/protocol"
@ -64,7 +64,7 @@ func (f FolderConfiguration) Filesystem(fset *db.FileSet) fs.Filesystem {
func (f FolderConfiguration) ModTimeWindow() time.Duration {
dur := time.Duration(f.RawModTimeWindowS) * time.Second
if f.RawModTimeWindowS < 1 && runtime.GOOS == "android" {
if f.RawModTimeWindowS < 1 && build.IsAndroid {
if usage, err := disk.Usage(f.Filesystem(nil).URI()); err != nil {
dur = 2 * time.Second
l.Debugf(`Detecting FS at "%v" on android: Setting mtime window to 2s: err == "%v"`, f.Path, err)
@ -90,7 +90,7 @@ func (f *FolderConfiguration) CreateMarker() error {
}
permBits := fs.FileMode(0777)
if runtime.GOOS == "windows" {
if build.IsWindows {
// Windows has no umask so we must chose a safer set of bits to
// begin with.
permBits = 0700
@ -145,7 +145,7 @@ func (f *FolderConfiguration) CreateRoot() (err error) {
// Directory permission bits. Will be filtered down to something
// sane by umask on Unixes.
permBits := fs.FileMode(0777)
if runtime.GOOS == "windows" {
if build.IsWindows {
// Windows has no umask so we must chose a safer set of bits to
// begin with.
permBits = 0700

@ -11,11 +11,11 @@ import (
"os"
"path"
"path/filepath"
"runtime"
"sort"
"strings"
"sync"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/upgrade"
"github.com/syncthing/syncthing/lib/util"
@ -189,7 +189,7 @@ func migrateToConfigV24(cfg *Configuration) {
func migrateToConfigV23(cfg *Configuration) {
permBits := fs.FileMode(0777)
if runtime.GOOS == "windows" {
if build.IsWindows {
// Windows has no umask so we must chose a safer set of bits to
// begin with.
permBits = 0700

@ -11,11 +11,11 @@ import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"time"
"github.com/shirou/gopsutil/v3/disk"
"github.com/syncthing/syncthing/lib/build"
)
var (
@ -79,7 +79,7 @@ func newBasicFilesystem(root string, opts ...Option) *BasicFilesystem {
// Attempt to enable long filename support on Windows. We may still not
// have an absolute path here if the previous steps failed.
if runtime.GOOS == "windows" {
if build.IsWindows {
root = longFilenameSupport(root)
}

@ -9,13 +9,13 @@ package fs
import (
"os"
"path/filepath"
"runtime"
"sort"
"strconv"
"strings"
"testing"
"time"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/rand"
)
@ -55,7 +55,7 @@ func TestChmodFile(t *testing.T) {
}
func TestChownFile(t *testing.T) {
if runtime.GOOS == "windows" {
if build.IsWindows {
t.Skip("Not supported on Windows")
return
}
@ -106,7 +106,7 @@ func TestChmodDir(t *testing.T) {
path := filepath.Join(dir, "dir")
mode := os.FileMode(0755)
if runtime.GOOS == "windows" {
if build.IsWindows {
mode = os.FileMode(0777)
}
@ -177,7 +177,7 @@ func TestCreate(t *testing.T) {
}
func TestCreateSymlink(t *testing.T) {
if runtime.GOOS == "windows" {
if build.IsWindows {
t.Skip("windows not supported")
}
@ -336,7 +336,7 @@ func TestUsage(t *testing.T) {
fs, _ := setup(t)
usage, err := fs.Usage(".")
if err != nil {
if runtime.GOOS == "netbsd" || runtime.GOOS == "openbsd" || runtime.GOOS == "solaris" {
if build.IsNetBSD || build.IsOpenBSD || build.IsSolaris || build.IsIllumos {
t.Skip()
}
t.Errorf("Unexpected error: %s", err)
@ -429,7 +429,7 @@ func TestRooted(t *testing.T) {
{"/", ".", "/", true},
}
if runtime.GOOS == "windows" {
if build.IsWindows {
extraCases := []testcase{
{`c:\`, `foo`, `c:\foo`, true},
{`\\?\c:\`, `foo`, `\\?\c:\foo`, true},
@ -503,7 +503,7 @@ func TestRooted(t *testing.T) {
}
func TestNewBasicFilesystem(t *testing.T) {
if runtime.GOOS == "windows" {
if build.IsWindows {
t.Skip("non-windows root paths")
}
@ -550,7 +550,7 @@ func TestRel(t *testing.T) {
{"/", "/Test", "Test"},
{"/Test", "/Test/test", "test"},
}
if runtime.GOOS == "windows" {
if build.IsWindows {
for i := range testCases {
testCases[i].root = filepath.FromSlash(testCases[i].root)
testCases[i].abs = filepath.FromSlash(testCases[i].abs)

@ -15,7 +15,6 @@ import (
"fmt"
"os"
"path/filepath"
"runtime"
"strconv"
"strings"
"syscall"
@ -23,6 +22,7 @@ import (
"time"
"github.com/syncthing/notify"
"github.com/syncthing/syncthing/lib/build"
)
func TestMain(m *testing.M) {
@ -41,7 +41,7 @@ func TestMain(m *testing.M) {
}
testDirAbs = filepath.Join(dir, testDir)
if runtime.GOOS == "windows" {
if build.IsWindows {
testDirAbs = longFilenameSupport(testDirAbs)
}
@ -68,7 +68,7 @@ var (
)
func TestWatchIgnore(t *testing.T) {
if runtime.GOOS == "openbsd" {
if build.IsOpenBSD {
t.Skip(failsOnOpenBSD)
}
name := "ignore"
@ -92,7 +92,7 @@ func TestWatchIgnore(t *testing.T) {
}
func TestWatchInclude(t *testing.T) {
if runtime.GOOS == "openbsd" {
if build.IsOpenBSD {
t.Skip(failsOnOpenBSD)
}
name := "include"
@ -119,7 +119,7 @@ func TestWatchInclude(t *testing.T) {
}
func TestWatchRename(t *testing.T) {
if runtime.GOOS == "openbsd" {
if build.IsOpenBSD {
t.Skip(failsOnOpenBSD)
}
name := "rename"
@ -134,7 +134,7 @@ func TestWatchRename(t *testing.T) {
destEvent := Event{new, Remove}
// Only on these platforms the removed file can be differentiated from
// the created file during renaming
if runtime.GOOS == "windows" || runtime.GOOS == "linux" || runtime.GOOS == "solaris" || runtime.GOOS == "freebsd" {
if build.IsWindows || build.IsLinux || build.IsSolaris || build.IsIllumos || build.IsFreeBSD {
destEvent = Event{new, NonRemove}
}
expectedEvents := []Event{
@ -154,7 +154,7 @@ func TestWatchRename(t *testing.T) {
// out of root event on every event.
// https://github.com/syncthing/syncthing/issues/5695
func TestWatchWinRoot(t *testing.T) {
if runtime.GOOS != "windows" {
if !build.IsWindows {
t.Skip("Windows specific test")
}
@ -288,7 +288,7 @@ func TestWatchSubpath(t *testing.T) {
// TestWatchOverflow checks that an event at the root is sent when maxFiles is reached
func TestWatchOverflow(t *testing.T) {
if runtime.GOOS == "openbsd" {
if build.IsOpenBSD {
t.Skip(failsOnOpenBSD)
}
name := "overflow"
@ -313,7 +313,7 @@ func TestWatchOverflow(t *testing.T) {
}
func TestWatchErrorLinuxInterpretation(t *testing.T) {
if runtime.GOOS != "linux" {
if !build.IsLinux {
t.Skip("testing of linux specific error codes")
}
@ -341,7 +341,7 @@ func TestWatchErrorLinuxInterpretation(t *testing.T) {
}
func TestWatchSymlinkedRoot(t *testing.T) {
if runtime.GOOS == "windows" {
if build.IsWindows {
t.Skip("Involves symlinks")
}
@ -385,7 +385,7 @@ func TestUnrootedChecked(t *testing.T) {
}
func TestWatchIssue4877(t *testing.T) {
if runtime.GOOS != "windows" {
if !build.IsWindows {
t.Skip("Windows specific test")
}
@ -440,7 +440,7 @@ func TestWatchModTime(t *testing.T) {
var allowedEvents []Event
// Apparently an event for the parent is also sent on mac
if runtime.GOOS == "darwin" {
if build.IsDarwin {
allowedEvents = []Event{
{name, NonRemove},
}

@ -17,6 +17,8 @@ import (
"sort"
"testing"
"time"
"github.com/syncthing/syncthing/lib/build"
)
func TestFakeFS(t *testing.T) {
@ -563,7 +565,7 @@ func testFakeFSRenameInsensitive(t *testing.T, fs Filesystem) {
}
// not checking on darwin due to https://github.com/golang/go/issues/35222
if runtime.GOOS != "darwin" {
if !build.IsDarwin {
if err := fs.Rename("/foo/bar/BAZ", "/FOO/BAR/bAz"); err != nil {
t.Errorf("Could not perform in-place case-only directory rename: %s", err)
}
@ -786,7 +788,7 @@ func testFakeFSSameFile(t *testing.T, fs Filesystem) {
t.Fatalf("Could not create %s: %s", filename, err)
} else {
fd.Close()
if runtime.GOOS == "windows" {
if build.IsWindows {
time.Sleep(1 * time.Millisecond)
}
}

@ -8,8 +8,9 @@ package fs
import (
"path/filepath"
"runtime"
"testing"
"github.com/syncthing/syncthing/lib/build"
)
func TestIsInternal(t *testing.T) {
@ -120,7 +121,7 @@ func TestIsParent(t *testing.T) {
testBoth := func(path, parent string, expected bool) {
t.Helper()
test(path, parent, expected)
if runtime.GOOS == "windows" {
if build.IsWindows {
test("C:/"+path, "C:/"+parent, expected)
} else {
test("/"+path, "/"+parent, expected)
@ -130,7 +131,7 @@ func TestIsParent(t *testing.T) {
// rel - abs
for _, parent := range []string{"/", "/foo", "/foo/bar"} {
for _, path := range []string{"", ".", "foo", "foo/bar", "bas", "bas/baz"} {
if runtime.GOOS == "windows" {
if build.IsWindows {
parent = "C:/" + parent
}
test(parent, path, false)
@ -140,7 +141,7 @@ func TestIsParent(t *testing.T) {
// equal
for i, path := range []string{"/", "/foo", "/foo/bar", "", ".", "foo", "foo/bar"} {
if i < 3 && runtime.GOOS == "windows" {
if i < 3 && build.IsWindows {
path = "C:" + path
}
test(path, path, false)
@ -164,7 +165,7 @@ func TestIsParent(t *testing.T) {
for _, path := range []string{"foo/bar/baz", "foo/bar/baz/bas"} {
testBoth(path, parent, true)
testBoth(parent, path, false)
if runtime.GOOS == "windows" {
if build.IsWindows {
test("C:/"+path, "D:/"+parent, false)
}
}

@ -10,9 +10,10 @@ import (
"errors"
"os"
"path/filepath"
"runtime"
"testing"
"time"
"github.com/syncthing/syncthing/lib/build"
)
func TestMtimeFS(t *testing.T) {
@ -181,11 +182,10 @@ func TestMtimeFSOpen(t *testing.T) {
}
func TestMtimeFSInsensitive(t *testing.T) {
switch runtime.GOOS {
case "darwin", "windows":
if build.IsDarwin || build.IsWindows {
// blatantly assume file systems here are case insensitive. Might be
// a spurious failure on oddly configured systems.
default:
} else {
t.Skip("need case insensitive FS")
}

@ -9,9 +9,9 @@ package fs
import (
"fmt"
"path/filepath"
"runtime"
"strings"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/sha256"
)
@ -21,7 +21,7 @@ const (
)
func tempPrefix() string {
if runtime.GOOS == "windows" {
if build.IsWindows {
return WindowsTempPrefix
} else {
return UnixTempPrefix

@ -10,9 +10,10 @@ import (
"fmt"
"os"
"path/filepath"
"runtime"
"strings"
"unicode"
"github.com/syncthing/syncthing/lib/build"
)
const pathSeparatorString = string(PathSeparator)
@ -35,7 +36,7 @@ func ExpandTilde(path string) (string, error) {
}
func getHomeDir() (string, error) {
if runtime.GOOS == "windows" {
if build.IsWindows {
// Legacy -- we prioritize this for historical reasons, whereas
// os.UserHomeDir uses %USERPROFILE% always.
home := filepath.Join(os.Getenv("HomeDrive"), os.Getenv("HomePath"))
@ -196,7 +197,7 @@ func CommonPrefix(first, second string) string {
}
if isAbs {
if runtime.GOOS == "windows" && isVolumeNameOnly(common) {
if build.IsWindows && isVolumeNameOnly(common) {
// Because strings.Split strips out path separators, if we're at the volume name, we end up without a separator
// Wedge an empty element to be joined with.
common = append(common, "")

@ -8,10 +8,11 @@ package fs
import (
"math/rand"
"runtime"
"testing"
"unicode"
"unicode/utf8"
"github.com/syncthing/syncthing/lib/build"
)
func TestCommonPrefix(t *testing.T) {
@ -23,7 +24,7 @@ func TestCommonPrefix(t *testing.T) {
}
}
if runtime.GOOS == "windows" {
if build.IsWindows {
test(`c:\Audrius\Downloads`, `c:\Audrius\Docs`, `c:\Audrius`)
test(`c:\Audrius\Downloads`, `C:\Audrius\Docs`, ``) // Case differences :(
test(`C:\Audrius-a\Downloads`, `C:\Audrius-b\Docs`, `C:\`)

@ -11,12 +11,13 @@ import (
"fmt"
osexec "os/exec"
"path/filepath"
"runtime"
"testing"
"github.com/syncthing/syncthing/lib/build"
)
func testWalkSkipSymlink(t *testing.T, fsType FilesystemType, uri string) {
if runtime.GOOS == "windows" {
if build.IsWindows {
t.Skip("Symlinks skipping is not tested on windows")
}
@ -53,7 +54,7 @@ func createDirJunct(target string, name string) error {
}
func testWalkTraverseDirJunct(t *testing.T, fsType FilesystemType, uri string) {
if runtime.GOOS != "windows" {
if !build.IsWindows {
t.Skip("Directory junctions are available and tested on windows only")
}
@ -86,7 +87,7 @@ func testWalkTraverseDirJunct(t *testing.T, fsType FilesystemType, uri string) {
}
func testWalkInfiniteRecursion(t *testing.T, fsType FilesystemType, uri string) {
if runtime.GOOS != "windows" {
if !build.IsWindows {
t.Skip("Infinite recursion detection is tested on windows only")
}

@ -13,12 +13,12 @@ import (
"fmt"
"io"
"path/filepath"
"runtime"
"strings"
"time"
"github.com/gobwas/glob"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/osutil"
"github.com/syncthing/syncthing/lib/sha256"
@ -35,7 +35,7 @@ const (
var defaultResult Result = resultInclude
func init() {
if runtime.GOOS == "darwin" || runtime.GOOS == "windows" {
if build.IsDarwin || build.IsWindows {
defaultResult |= resultFoldCase
}
}

@ -12,11 +12,11 @@ import (
"io"
"os"
"path/filepath"
"runtime"
"strings"
"testing"
"time"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/osutil"
)
@ -210,10 +210,9 @@ func TestCaseSensitivity(t *testing.T) {
match := []string{"test"}
dontMatch := []string{"foo"}
switch runtime.GOOS {
case "darwin", "windows":
if build.IsDarwin || build.IsWindows {
match = append(match, "TEST", "Test", "tESt")
default:
} else {
dontMatch = append(dontMatch, "TEST", "Test", "tESt")
}
@ -618,7 +617,7 @@ func TestHashOfEmpty(t *testing.T) {
func TestWindowsPatterns(t *testing.T) {
// We should accept patterns as both a/b and a\b and match that against
// both kinds of slash as well.
if runtime.GOOS != "windows" {
if !build.IsWindows {
t.Skip("Windows specific test")
return
}
@ -643,7 +642,7 @@ func TestWindowsPatterns(t *testing.T) {
func TestAutomaticCaseInsensitivity(t *testing.T) {
// We should do case insensitive matching by default on some platforms.
if runtime.GOOS != "windows" && runtime.GOOS != "darwin" {
if !build.IsWindows && !build.IsDarwin {
t.Skip("Windows/Mac specific test")
return
}
@ -1205,7 +1204,7 @@ func TestEmptyPatterns(t *testing.T) {
}
func TestWindowsLineEndings(t *testing.T) {
if runtime.GOOS != "windows" {
if !build.IsWindows {
t.Skip("Windows specific")
}

@ -14,6 +14,7 @@ import (
"strings"
"time"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/fs"
)
@ -133,13 +134,13 @@ func expandLocations() error {
// trying.
func defaultConfigDir(userHome string) string {
switch runtime.GOOS {
case "windows":
case build.Windows:
if p := os.Getenv("LocalAppData"); p != "" {
return filepath.Join(p, "Syncthing")
}
return filepath.Join(os.Getenv("AppData"), "Syncthing")
case "darwin":
case build.Darwin:
return filepath.Join(userHome, "Library/Application Support/Syncthing")
default:
@ -153,30 +154,28 @@ func defaultConfigDir(userHome string) string {
// defaultDataDir returns the default data directory, which usually is the
// config directory but might be something else.
func defaultDataDir(userHome, config string) string {
switch runtime.GOOS {
case "windows", "darwin":
if build.IsWindows || build.IsDarwin {
return config
}
default:
// If a database exists at the "normal" location, use that anyway.
if _, err := os.Lstat(filepath.Join(config, LevelDBDir)); err == nil {
return config
}
// Always use this env var, as it's explicitly set by the user
if xdgHome := os.Getenv("XDG_DATA_HOME"); xdgHome != "" {
return filepath.Join(xdgHome, "syncthing")
}
// Only use the XDG default, if a syncthing specific dir already
// exists. Existence of ~/.local/share is not deemed enough, as
// it may also exist erroneously on non-XDG systems.
xdgDefault := filepath.Join(userHome, ".local/share/syncthing")
if _, err := os.Lstat(xdgDefault); err == nil {
return xdgDefault
}
// FYI: XDG_DATA_DIRS is not relevant, as it is for system-wide
// data dirs, not user specific ones.
// If a database exists at the "normal" location, use that anyway.
if _, err := os.Lstat(filepath.Join(config, LevelDBDir)); err == nil {
return config
}
// Always use this env var, as it's explicitly set by the user
if xdgHome := os.Getenv("XDG_DATA_HOME"); xdgHome != "" {
return filepath.Join(xdgHome, "syncthing")
}
// Only use the XDG default, if a syncthing specific dir already
// exists. Existence of ~/.local/share is not deemed enough, as
// it may also exist erroneously on non-XDG systems.
xdgDefault := filepath.Join(userHome, ".local/share/syncthing")
if _, err := os.Lstat(xdgDefault); err == nil {
return xdgDefault
}
// FYI: XDG_DATA_DIRS is not relevant, as it is for system-wide
// data dirs, not user specific ones.
return config
}
// userHomeDir returns the user's home directory, or dies trying.

@ -11,7 +11,6 @@ import (
"fmt"
"io"
"path/filepath"
"runtime"
"sort"
"strconv"
"strings"
@ -19,6 +18,7 @@ import (
"github.com/pkg/errors"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/db"
"github.com/syncthing/syncthing/lib/events"
@ -344,7 +344,7 @@ func (f *sendReceiveFolder) processNeeded(snap *db.Snapshot, dbUpdateChan chan<-
l.Debugln(f, "Handling ignored file", file)
dbUpdateChan <- dbUpdateJob{file, dbUpdateInvalidate}
case runtime.GOOS == "windows" && fs.WindowsInvalidFilename(file.Name) != nil:
case build.IsWindows && fs.WindowsInvalidFilename(file.Name) != nil:
if file.IsDeleted() {
// Just pretend we deleted it, no reason to create an error
// about a deleted file that we can't have anyway.
@ -394,7 +394,7 @@ func (f *sendReceiveFolder) processNeeded(snap *db.Snapshot, dbUpdateChan chan<-
f.queue.Push(file.Name, file.Size, file.ModTime())
}
case runtime.GOOS == "windows" && file.IsSymlink():
case build.IsWindows && file.IsSymlink():
if err := f.handleSymlinkCheckExisting(file, snap, scanChan); err != nil {
f.newPullError(file.Name, fmt.Errorf("handling unsupported symlink: %w", err))
break
@ -2115,7 +2115,7 @@ func (f *sendReceiveFolder) maybeAdjustOwnership(file *protocol.FileInfo, name s
}
func (f *sendReceiveFolder) copyOwnershipFromParent(path string) error {
if runtime.GOOS == "windows" {
if build.IsWindows {
// Can't do anything.
return nil
}

@ -15,12 +15,12 @@ import (
"io"
"os"
"path/filepath"
"runtime"
"strconv"
"strings"
"testing"
"time"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/events"
"github.com/syncthing/syncthing/lib/fs"
"github.com/syncthing/syncthing/lib/ignore"
@ -205,7 +205,7 @@ func TestHandleFileWithTemp(t *testing.T) {
func TestCopierFinder(t *testing.T) {
methods := []fs.CopyRangeMethod{fs.CopyRangeMethodStandard, fs.CopyRangeMethodAllWithFallback}
if runtime.GOOS == "linux" {
if build.IsLinux {
methods = append(methods, fs.CopyRangeMethodSendFile)
}
for _, method := range methods {
@ -789,7 +789,7 @@ func TestCopyOwner(t *testing.T) {
// Verifies that owner and group are copied from the parent, for both
// files and directories.
if runtime.GOOS == "windows" {
if build.IsWindows {
t.Skip("copying owner not supported on Windows")
}
@ -986,7 +986,7 @@ func TestDeleteBehindSymlink(t *testing.T) {
must(t, ffs.RemoveAll(link))
if err := fs.DebugSymlinkForTestsOnly(destFs, ffs, "", link); err != nil {
if runtime.GOOS == "windows" {
if build.IsWindows {
// Probably we require permissions we don't have.
t.Skip("Need admin permissions or developer mode to run symlink test on Windows: " + err.Error())
} else {
@ -1145,7 +1145,7 @@ func TestPullCaseOnlyDir(t *testing.T) {
}
func TestPullCaseOnlySymlink(t *testing.T) {
if runtime.GOOS == "windows" {
if build.IsWindows {
t.Skip("symlinks not supported on windows")
}
testPullCaseOnlyDirOrSymlink(t, false)
@ -1275,7 +1275,7 @@ func TestPullCaseOnlyRename(t *testing.T) {
}
func TestPullSymlinkOverExistingWindows(t *testing.T) {
if runtime.GOOS != "windows" {
if !build.IsWindows {
t.Skip()
}

@ -8,11 +8,11 @@ package model
import (
"path/filepath"
"runtime"
"testing"
"github.com/d4l3k/messagediff"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/config"
)
@ -96,7 +96,7 @@ func unifySubsCases() []unifySubsCase {
},
}
if runtime.GOOS == "windows" {
if build.IsWindows {
// Fixup path separators
for i := range cases {
for j, p := range cases[i].in {

@ -27,6 +27,7 @@ import (
"github.com/pkg/errors"
"github.com/thejerf/suture/v4"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/connections"
"github.com/syncthing/syncthing/lib/db"
@ -2399,7 +2400,7 @@ func (m *model) numHashers(folder string) int {
return folderCfg.Hashers
}
if runtime.GOOS == "windows" || runtime.GOOS == "darwin" || runtime.GOOS == "android" {
if build.IsWindows || build.IsDarwin || build.IsAndroid {
// Interactive operating systems; don't load the system too heavily by
// default.
return 1

@ -15,7 +15,6 @@ import (
"math/rand"
"os"
"path/filepath"
"runtime"
"runtime/pprof"
"sort"
"strconv"
@ -26,6 +25,7 @@ import (
"time"
"github.com/pkg/errors"
"github.com/syncthing/syncthing/lib/build"
"github.com/syncthing/syncthing/lib/config"
"github.com/syncthing/syncthing/lib/db"
"github.com/syncthing/syncthing/lib/db/backend"
@ -1463,7 +1463,7 @@ func changeIgnores(t *testing.T, m *testModel, expected []string) {
t.Errorf("Incorrect ignores: %v != %v", ignores2, ignores)
}
if runtime.GOOS == "darwin" {
if build.IsDarwin {
// see above
time.Sleep(time.Second)
} else {
@ -2130,7 +2130,7 @@ func TestIssue4357(t *testing.T) {
func TestIssue2782(t *testing.T) {
// CheckHealth should accept a symlinked folder, when using tilde-expanded path.
if runtime.GOOS == "windows" {
if build.IsWindows {
t.Skip(&