diff --git a/backend/box/box.go b/backend/box/box.go index 23ea0f17b..7b5bed948 100644 --- a/backend/box/box.go +++ b/backend/box/box.go @@ -26,6 +26,7 @@ import ( "time" "github.com/rclone/rclone/lib/encoder" + "github.com/rclone/rclone/lib/env" "github.com/rclone/rclone/lib/jwtutil" "github.com/youmark/pkcs8" @@ -112,7 +113,7 @@ func init() { Advanced: true, }, { Name: "box_config_file", - Help: "Box App config.json location\nLeave blank normally.", + Help: "Box App config.json location\nLeave blank normally." + env.ShellExpandHelp, }, { Name: "box_sub_type", Default: "user", @@ -153,6 +154,7 @@ func init() { } func refreshJWTToken(jsonFile string, boxSubType string, name string, m configmap.Mapper) error { + jsonFile = env.ShellExpand(jsonFile) boxConfig, err := getBoxConfig(jsonFile) if err != nil { log.Fatalf("Failed to configure token: %v", err) diff --git a/backend/drive/drive.go b/backend/drive/drive.go index 799cbfddd..2115fe559 100755 --- a/backend/drive/drive.go +++ b/backend/drive/drive.go @@ -18,7 +18,6 @@ import ( "mime" "net/http" "net/url" - "os" "path" "sort" "strconv" @@ -41,6 +40,7 @@ import ( "github.com/rclone/rclone/fs/walk" "github.com/rclone/rclone/lib/dircache" "github.com/rclone/rclone/lib/encoder" + "github.com/rclone/rclone/lib/env" "github.com/rclone/rclone/lib/oauthutil" "github.com/rclone/rclone/lib/pacer" "github.com/rclone/rclone/lib/readers" @@ -229,7 +229,7 @@ in with the ID of the root folder. `, }, { Name: "service_account_file", - Help: "Service Account Credentials JSON file path \nLeave blank normally.\nNeeded only if you want use SA instead of interactive login.", + Help: "Service Account Credentials JSON file path \nLeave blank normally.\nNeeded only if you want use SA instead of interactive login." + env.ShellExpandHelp, }, { Name: "service_account_credentials", Help: "Service Account Credentials JSON blob\nLeave blank normally.\nNeeded only if you want use SA instead of interactive login.", @@ -1005,7 +1005,7 @@ func createOAuthClient(opt *Options, name string, m configmap.Mapper) (*http.Cli // try loading service account credentials from env variable, then from a file if len(opt.ServiceAccountCredentials) == 0 && opt.ServiceAccountFile != "" { - loadedCreds, err := ioutil.ReadFile(os.ExpandEnv(opt.ServiceAccountFile)) + loadedCreds, err := ioutil.ReadFile(env.ShellExpand(opt.ServiceAccountFile)) if err != nil { return nil, errors.Wrap(err, "error opening service account credentials file") } diff --git a/backend/googlecloudstorage/googlecloudstorage.go b/backend/googlecloudstorage/googlecloudstorage.go index 5ca7dbfde..1ba2a945c 100644 --- a/backend/googlecloudstorage/googlecloudstorage.go +++ b/backend/googlecloudstorage/googlecloudstorage.go @@ -21,7 +21,6 @@ import ( "io/ioutil" "log" "net/http" - "os" "path" "strings" "time" @@ -38,6 +37,7 @@ import ( "github.com/rclone/rclone/fs/walk" "github.com/rclone/rclone/lib/bucket" "github.com/rclone/rclone/lib/encoder" + "github.com/rclone/rclone/lib/env" "github.com/rclone/rclone/lib/oauthutil" "github.com/rclone/rclone/lib/pacer" "golang.org/x/oauth2" @@ -98,7 +98,7 @@ func init() { Help: "Project number.\nOptional - needed only for list/create/delete buckets - see your developer console.", }, { Name: "service_account_file", - Help: "Service Account Credentials JSON file path\nLeave blank normally.\nNeeded only if you want use SA instead of interactive login.", + Help: "Service Account Credentials JSON file path\nLeave blank normally.\nNeeded only if you want use SA instead of interactive login." + env.ShellExpandHelp, }, { Name: "service_account_credentials", Help: "Service Account Credentials JSON blob\nLeave blank normally.\nNeeded only if you want use SA instead of interactive login.", @@ -405,7 +405,7 @@ func NewFs(name, root string, m configmap.Mapper) (fs.Fs, error) { // try loading service account credentials from env variable, then from a file if opt.ServiceAccountCredentials == "" && opt.ServiceAccountFile != "" { - loadedCreds, err := ioutil.ReadFile(os.ExpandEnv(opt.ServiceAccountFile)) + loadedCreds, err := ioutil.ReadFile(env.ShellExpand(opt.ServiceAccountFile)) if err != nil { return nil, errors.Wrap(err, "error opening service account credentials file") } diff --git a/backend/sftp/sftp.go b/backend/sftp/sftp.go index c3020d10c..e3a631a25 100644 --- a/backend/sftp/sftp.go +++ b/backend/sftp/sftp.go @@ -74,7 +74,7 @@ func init() { Help: "Raw PEM-encoded private key, If specified, will override key_file parameter.", }, { Name: "key_file", - Help: "Path to PEM-encoded private key file, leave blank or set key-use-agent to use ssh-agent.", + Help: "Path to PEM-encoded private key file, leave blank or set key-use-agent to use ssh-agent." + env.ShellExpandHelp, }, { Name: "key_file_pass", Help: `The passphrase to decrypt the PEM-encoded private key file. diff --git a/lib/env/env.go b/lib/env/env.go index 6485e8214..739b4a2d7 100644 --- a/lib/env/env.go +++ b/lib/env/env.go @@ -7,6 +7,9 @@ import ( homedir "github.com/mitchellh/go-homedir" ) +// ShellExpandHelp describes what ShellExpand does for inclusion into help +const ShellExpandHelp = "\n\nLeading `~` will be expanded in the file name as will environment variables such as `${RCLONE_CONFIG_DIR}`.\n" + // ShellExpand replaces a leading "~" with the home directory" and // expands all environment variables afterwards. func ShellExpand(s string) string {