Repository: syncthing/syncthing
File: lib/locations/locations.go (Go)

Code before:
		}
		return filepath.Join(os.Getenv("AppData"), "Syncthing")

	case "darwin":
		return filepath.Join(home, "Library/Application Support/Syncthing")

	default:
		if xdgCfg := os.Getenv("XDG_CONFIG_HOME"); xdgCfg != "" {
			return filepath.Join(xdgCfg, "syncthing")
		}
		return filepath.Join(home, ".config/syncthing")
	}
}

// defaultDataDir returns the default data directory, which usually is the
// config directory but might be something else.
func defaultDataDir(home, config string) string {
	switch runtime.GOOS {
	case "windows", "darwin":
		return config

	default:
		xdgData := os.Getenv("XDG_DATA_HOME")
		if xdgData == "" {
			if xdgDatas := os.Getenv("XDG_DATA_DIRS"); xdgDatas == "" {
				xdgData = filepath.Join(home, ".local/share/syncthing")
				if _, err := os.Lstat(xdgData); err != nil {
					return config
				}
			} else {
				xdgData = strings.SplitN(xdgDatas, ":", 2)[0]
			}
		}
		// Only use XDG location if no database exists at "normal" location
		if _, err := os.Lstat(filepath.Join(home, "syncthing", databaseDirname)); os.IsNotExist(err) {
			return xdgData
		}
		return config
	}
}

// homeDir returns the user's home directory, or dies trying.
func homeDir() string {
	home, err := fs.ExpandTilde("~")
	if err != nil {
		fmt.Println(err)
		panic("Failed to get user home dir")
	}
	return home
}


Review comment (suggestion):
Logic is convoluted, I'd rather linearize this a bit

```
// first check for the existing traditional location
if _, err := os.Lstat(traditional location); err == nil {
  // ...
}

// go hunting for an xdg dir
xdgData := os.Getenv("XDG_DATA_HOME")
if xdgData == "" {
  // split and grab xdg_data_dirs
}
if xdgData != "" {
  // return the xdg dir we found
}

try for the existence of the default XDG dir and return that if it exists

return traditional place
```


Code after:
		}
		return filepath.Join(os.Getenv("AppData"), "Syncthing")

	case "darwin":
		return filepath.Join(userHome, "Library/Application Support/Syncthing")

	default:
		if xdgCfg := os.Getenv("XDG_CONFIG_HOME"); xdgCfg != "" {
			return filepath.Join(xdgCfg, "syncthing")
		}
		return filepath.Join(userHome, ".config/syncthing")
	}
}

// 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":
		return config

	default:
		// If a database exists at the "normal" location, use that anyway.
		if _, err := os.Lstat(filepath.Join(config, databaseDirname)); 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.
func userHomeDir() string {
	userHome, err := fs.ExpandTilde("~")
	if err != nil {
		fmt.Println(err)
		panic("Failed to get user home dir")
	}
	return userHome