Skip to content

Commit

Permalink
Comply with XDG Base Directory specification
Browse files Browse the repository at this point in the history
Fixes #868
  • Loading branch information
kynikos authored and ncw committed Jan 26, 2017
1 parent 9fdeb82 commit 9d36258
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 25 deletions.
23 changes: 15 additions & 8 deletions docs/content/docs.md
Expand Up @@ -8,9 +8,9 @@ Configure
---------

First you'll need to configure rclone. As the object storage systems
have quite complicated authentication these are kept in a config file
`.rclone.conf` in your home directory by default. (You can use the
`--config` option to choose a different config file.)
have quite complicated authentication these are kept in a config file.
(See the `--config` entry for how to find the config file and choose
its location.)

The easiest way to make the config is to run rclone with the config
option:
Expand Down Expand Up @@ -281,11 +281,18 @@ they are incorrect as it would normally.

### --config=CONFIG_FILE ###

Specify the location of the rclone config file. Normally this is in
your home directory as a file called `.rclone.conf`. If you run
`rclone -h` and look at the help for the `--config` option you will
see where the default location is for you. Use this flag to override
the config location, eg `rclone --config=".myconfig" .config`.
Specify the location of the rclone config file.

Normally the config file is in your home directory as a file called
`.config/rclone/rclone.conf` (or `.rclone.conf` if created with an
older version). If `$XDG_CONFIG_HOME` is set it will be at
`$XDG_CONFIG_HOME/rclone/rclone.conf`

If you run `rclone -h` and look at the help for the `--config` option
you will see where the default location is for you.

Use this flag to override the config location, eg `rclone
--config=".myconfig" .config`.

### --contimeout=TIME ###

Expand Down
80 changes: 63 additions & 17 deletions fs/config.go
Expand Up @@ -16,7 +16,7 @@ import (
"log"
"os"
"os/user"
"path"
"path/filepath"
"regexp"
"sort"
"strconv"
Expand All @@ -31,7 +31,8 @@ import (
)

const (
configFileName = ".rclone.conf"
configFileName = "rclone.conf"
hiddenConfigFileName = "." + configFileName

// ConfigToken is the key used to store the token under
ConfigToken = "token"
Expand All @@ -50,10 +51,8 @@ const (
var (
// configData is the config file data structure
configData *goconfig.ConfigFile
// HomeDir is the home directory of the user
HomeDir = configHome()
// ConfigPath points to the config file
ConfigPath = path.Join(HomeDir, configFileName)
ConfigPath = makeConfigPath()
// Config is the global config
Config = &ConfigInfo{}
// Flags
Expand Down Expand Up @@ -215,25 +214,72 @@ type ConfigInfo struct {
Suffix string
}

// Find the config directory
func configHome() string {
// Find users home directory
// Return the path to the configuration file
func makeConfigPath() string {
// Find user's home directory
usr, err := user.Current()
var homedir string
if err == nil {
return usr.HomeDir
homedir = usr.HomeDir
} else {
// Fall back to reading $HOME - work around user.Current() not
// working for cross compiled binaries on OSX.
// https://github.com/golang/go/issues/6376
homedir = os.Getenv("HOME")
}

// Possibly find the user's XDG config paths
// See XDG Base Directory specification
// https://specifications.freedesktop.org/basedir-spec/latest/
xdgdir := os.Getenv("XDG_CONFIG_HOME")
var xdgcfgdir string
if xdgdir != "" {
xdgcfgdir = filepath.Join(xdgdir, "rclone")
} else if homedir != "" {
xdgdir = filepath.Join(homedir, ".config")
xdgcfgdir = filepath.Join(xdgdir, "rclone")
}

// Use $XDG_CONFIG_HOME/rclone/rclone.conf if already existing
var xdgconf string
if xdgcfgdir != "" {
xdgconf = filepath.Join(xdgcfgdir, configFileName)
_, err := os.Stat(xdgconf)
if err == nil {
return xdgconf
}
}

// Use $HOME/.rclone.conf if already existing
var homeconf string
if homedir != "" {
homeconf = filepath.Join(homedir, hiddenConfigFileName)
_, err := os.Stat(homeconf)
if err == nil {
return homeconf
}
}
// Fall back to reading $HOME - work around user.Current() not
// working for cross compiled binaries on OSX.
// https://github.com/golang/go/issues/6376
home := os.Getenv("HOME")
if home != "" {
return home

// Try to create $XDG_CONFIG_HOME/rclone/rclone.conf
if xdgconf != "" {
// xdgconf != "" implies xdgcfgdir != ""
err := os.MkdirAll(xdgcfgdir, os.ModePerm)
if err == nil {
return xdgconf
}
}
ErrorLog(nil, "Couldn't find home directory or read HOME environment variable.")

// Try to create $HOME/.rclone.conf
if homeconf != "" {
return homeconf
}

// Default to ./.rclone.conf (current working directory)
ErrorLog(nil, "Couldn't find home directory or read HOME or XDG_CONFIG_HOME environment variables.")
ErrorLog(nil, "Defaulting to storing config in current directory.")
ErrorLog(nil, "Use -config flag to workaround.")
ErrorLog(nil, "Error was: %v", err)
return ""
return hiddenConfigFileName
}

// LoadConfig loads the config file
Expand Down

0 comments on commit 9d36258

Please sign in to comment.