2018-01-12 17:30:54 +01:00
// Package configflags defines the flags used by rclone. It is
// decoupled into a separate package so it can be replaced.
package configflags
// Options set by command line flags
import (
"log"
"net"
"path/filepath"
"strings"
2019-07-28 19:47:38 +02:00
"github.com/rclone/rclone/fs"
"github.com/rclone/rclone/fs/config"
"github.com/rclone/rclone/fs/config/flags"
fsLog "github.com/rclone/rclone/fs/log"
"github.com/rclone/rclone/fs/rc"
2019-07-26 02:54:09 +02:00
"github.com/sirupsen/logrus"
2018-01-12 17:30:54 +01:00
"github.com/spf13/pflag"
)
var (
// these will get interpreted into fs.Config via SetFlags() below
2020-02-25 18:03:21 +01:00
verbose int
quiet bool
dumpHeaders bool
dumpBodies bool
deleteBefore bool
deleteDuring bool
deleteAfter bool
bindAddr string
disableFeatures string
2020-02-10 08:50:08 +01:00
uploadHeaders [ ] string
downloadHeaders [ ] string
2020-04-23 16:24:21 +02:00
headers [ ] string
2018-01-12 17:30:54 +01:00
)
// AddFlags adds the non filing system specific flags to the command
func AddFlags ( flagSet * pflag . FlagSet ) {
2018-10-28 00:58:18 +02:00
rc . AddOption ( "main" , fs . Config )
2018-01-12 17:30:54 +01:00
// NB defaults which aren't the zero for the type should be set in fs/config.go NewConfig
flags . CountVarP ( flagSet , & verbose , "verbose" , "v" , "Print lots more stuff (repeat for more)" )
flags . BoolVarP ( flagSet , & quiet , "quiet" , "q" , false , "Print as little stuff as possible" )
flags . DurationVarP ( flagSet , & fs . Config . ModifyWindow , "modify-window" , "" , fs . Config . ModifyWindow , "Max time diff to be considered the same" )
flags . IntVarP ( flagSet , & fs . Config . Checkers , "checkers" , "" , fs . Config . Checkers , "Number of checkers to run in parallel." )
flags . IntVarP ( flagSet , & fs . Config . Transfers , "transfers" , "" , fs . Config . Transfers , "Number of file transfers to run in parallel." )
flags . StringVarP ( flagSet , & config . ConfigPath , "config" , "" , config . ConfigPath , "Config file." )
flags . StringVarP ( flagSet , & config . CacheDir , "cache-dir" , "" , config . CacheDir , "Directory rclone will use for caching." )
2019-01-10 12:07:10 +01:00
flags . BoolVarP ( flagSet , & fs . Config . CheckSum , "checksum" , "c" , fs . Config . CheckSum , "Skip based on checksum (if available) & size, not mod-time & size" )
2018-01-12 17:30:54 +01:00
flags . BoolVarP ( flagSet , & fs . Config . SizeOnly , "size-only" , "" , fs . Config . SizeOnly , "Skip based on size only, not mod-time or checksum" )
flags . BoolVarP ( flagSet , & fs . Config . IgnoreTimes , "ignore-times" , "I" , fs . Config . IgnoreTimes , "Don't skip files that match size and time - transfer all files" )
flags . BoolVarP ( flagSet , & fs . Config . IgnoreExisting , "ignore-existing" , "" , fs . Config . IgnoreExisting , "Skip all files that exist on destination" )
2018-03-13 00:40:19 +01:00
flags . BoolVarP ( flagSet , & fs . Config . IgnoreErrors , "ignore-errors" , "" , fs . Config . IgnoreErrors , "delete even if there are I/O errors" )
2018-01-12 17:30:54 +01:00
flags . BoolVarP ( flagSet , & fs . Config . DryRun , "dry-run" , "n" , fs . Config . DryRun , "Do a trial run with no permanent changes" )
2020-03-20 19:43:29 +01:00
flags . BoolVarP ( flagSet , & fs . Config . Interactive , "interactive" , "i" , fs . Config . Interactive , "Enable interactive mode" )
2018-01-12 17:30:54 +01:00
flags . DurationVarP ( flagSet , & fs . Config . ConnectTimeout , "contimeout" , "" , fs . Config . ConnectTimeout , "Connect timeout" )
flags . DurationVarP ( flagSet , & fs . Config . Timeout , "timeout" , "" , fs . Config . Timeout , "IO idle timeout" )
2020-01-09 15:00:46 +01:00
flags . DurationVarP ( flagSet , & fs . Config . ExpectContinueTimeout , "expect-continue-timeout" , "" , fs . Config . ExpectContinueTimeout , "Timeout when using expect / 100-continue in HTTP" )
2019-05-09 06:06:24 +02:00
flags . BoolVarP ( flagSet , & dumpHeaders , "dump-headers" , "" , false , "Dump HTTP headers - may contain sensitive info" )
2018-01-12 17:30:54 +01:00
flags . BoolVarP ( flagSet , & dumpBodies , "dump-bodies" , "" , false , "Dump HTTP headers and bodies - may contain sensitive info" )
flags . BoolVarP ( flagSet , & fs . Config . InsecureSkipVerify , "no-check-certificate" , "" , fs . Config . InsecureSkipVerify , "Do not verify the server SSL certificate. Insecure." )
flags . BoolVarP ( flagSet , & fs . Config . AskPassword , "ask-password" , "" , fs . Config . AskPassword , "Allow prompt for password for encrypted configuration." )
2020-01-23 15:14:58 +01:00
flags . FVarP ( flagSet , & fs . Config . PasswordCommand , "password-command" , "" , "Command for supplying password for encrypted configuration." )
2018-11-14 17:11:58 +01:00
flags . BoolVarP ( flagSet , & deleteBefore , "delete-before" , "" , false , "When synchronizing, delete files on destination before transferring" )
2018-07-18 20:30:14 +02:00
flags . BoolVarP ( flagSet , & deleteDuring , "delete-during" , "" , false , "When synchronizing, delete files during transfer" )
2018-11-14 17:11:58 +01:00
flags . BoolVarP ( flagSet , & deleteAfter , "delete-after" , "" , false , "When synchronizing, delete files on destination after transferring (default)" )
2019-10-11 17:55:04 +02:00
flags . Int64VarP ( flagSet , & fs . Config . MaxDelete , "max-delete" , "" , - 1 , "When synchronizing, limit the number of deletes" )
2018-01-12 17:30:54 +01:00
flags . BoolVarP ( flagSet , & fs . Config . TrackRenames , "track-renames" , "" , fs . Config . TrackRenames , "When synchronizing, track file renames and do a server side move if possible" )
2020-06-09 21:40:03 +02:00
flags . StringVarP ( flagSet , & fs . Config . TrackRenamesStrategy , "track-renames-strategy" , "" , fs . Config . TrackRenamesStrategy , "Strategies to use when synchronizing using track-renames hash|modtime|leaf" )
2018-01-12 17:30:54 +01:00
flags . IntVarP ( flagSet , & fs . Config . LowLevelRetries , "low-level-retries" , "" , fs . Config . LowLevelRetries , "Number of low level retries to do." )
flags . BoolVarP ( flagSet , & fs . Config . UpdateOlder , "update" , "u" , fs . Config . UpdateOlder , "Skip files that are newer on the destination." )
2018-04-13 14:32:17 +02:00
flags . BoolVarP ( flagSet , & fs . Config . UseServerModTime , "use-server-modtime" , "" , fs . Config . UseServerModTime , "Use server modified time instead of object metadata" )
2018-01-12 17:30:54 +01:00
flags . BoolVarP ( flagSet , & fs . Config . NoGzip , "no-gzip-encoding" , "" , fs . Config . NoGzip , "Don't set Accept-Encoding: gzip." )
flags . IntVarP ( flagSet , & fs . Config . MaxDepth , "max-depth" , "" , fs . Config . MaxDepth , "If set limits the recursion depth to this." )
flags . BoolVarP ( flagSet , & fs . Config . IgnoreSize , "ignore-size" , "" , false , "Ignore size when skipping use mod-time or checksum." )
flags . BoolVarP ( flagSet , & fs . Config . IgnoreChecksum , "ignore-checksum" , "" , fs . Config . IgnoreChecksum , "Skip post copy check of checksums." )
2019-06-03 22:12:10 +02:00
flags . BoolVarP ( flagSet , & fs . Config . IgnoreCaseSync , "ignore-case-sync" , "" , fs . Config . IgnoreCaseSync , "Ignore case when synchronizing" )
2018-11-25 17:49:38 +01:00
flags . BoolVarP ( flagSet , & fs . Config . NoTraverse , "no-traverse" , "" , fs . Config . NoTraverse , "Don't traverse destination file system on copy." )
2020-05-15 12:39:07 +02:00
flags . BoolVarP ( flagSet , & fs . Config . CheckFirst , "check-first" , "" , fs . Config . CheckFirst , "Do all the checks before starting transfers." )
2019-10-17 18:41:11 +02:00
flags . BoolVarP ( flagSet , & fs . Config . NoCheckDest , "no-check-dest" , "" , fs . Config . NoCheckDest , "Don't check the destination, copy regardless." )
2020-05-15 01:27:59 +02:00
flags . BoolVarP ( flagSet , & fs . Config . NoUnicodeNormalization , "no-unicode-normalization" , "" , fs . Config . NoUnicodeNormalization , "Don't normalize unicode characters in filenames." )
2018-01-12 17:30:54 +01:00
flags . BoolVarP ( flagSet , & fs . Config . NoUpdateModTime , "no-update-modtime" , "" , fs . Config . NoUpdateModTime , "Don't update destination mod-time if files identical." )
2019-11-12 14:37:58 +01:00
flags . StringVarP ( flagSet , & fs . Config . CompareDest , "compare-dest" , "" , fs . Config . CompareDest , "Include additional server-side path during comparison." )
flags . StringVarP ( flagSet , & fs . Config . CopyDest , "copy-dest" , "" , fs . Config . CopyDest , "Implies --compare-dest but also copies files from path into destination." )
2018-01-12 17:30:54 +01:00
flags . StringVarP ( flagSet , & fs . Config . BackupDir , "backup-dir" , "" , fs . Config . BackupDir , "Make backups into hierarchy based in DIR." )
2019-06-23 05:52:09 +02:00
flags . StringVarP ( flagSet , & fs . Config . Suffix , "suffix" , "" , fs . Config . Suffix , "Suffix to add to changed files." )
2019-03-10 17:50:28 +01:00
flags . BoolVarP ( flagSet , & fs . Config . SuffixKeepExtension , "suffix-keep-extension" , "" , fs . Config . SuffixKeepExtension , "Preserve the extension when using --suffix." )
2018-01-12 17:30:54 +01:00
flags . BoolVarP ( flagSet , & fs . Config . UseListR , "fast-list" , "" , fs . Config . UseListR , "Use recursive list if available. Uses more memory but fewer transactions." )
flags . Float64VarP ( flagSet , & fs . Config . TPSLimit , "tpslimit" , "" , fs . Config . TPSLimit , "Limit HTTP transactions per second to this." )
flags . IntVarP ( flagSet , & fs . Config . TPSLimitBurst , "tpslimit-burst" , "" , fs . Config . TPSLimitBurst , "Max burst of transactions for --tpslimit." )
flags . StringVarP ( flagSet , & bindAddr , "bind" , "" , "" , "Local address to bind to for outgoing connections, IPv4, IPv6 or name." )
flags . StringVarP ( flagSet , & disableFeatures , "disable" , "" , "" , "Disable a comma separated list of features. Use help to see a list." )
flags . StringVarP ( flagSet , & fs . Config . UserAgent , "user-agent" , "" , fs . Config . UserAgent , "Set the user-agent to a specified string. The default is rclone/ version" )
flags . BoolVarP ( flagSet , & fs . Config . Immutable , "immutable" , "" , fs . Config . Immutable , "Do not modify files. Fail if existing files have been modified." )
flags . BoolVarP ( flagSet , & fs . Config . AutoConfirm , "auto-confirm" , "" , fs . Config . AutoConfirm , "If enabled, do not request console confirmation." )
flags . IntVarP ( flagSet , & fs . Config . StatsFileNameLength , "stats-file-name-length" , "" , fs . Config . StatsFileNameLength , "Max file name length in stats. 0 for no limit" )
flags . FVarP ( flagSet , & fs . Config . LogLevel , "log-level" , "" , "Log level DEBUG|INFO|NOTICE|ERROR" )
flags . FVarP ( flagSet , & fs . Config . StatsLogLevel , "stats-log-level" , "" , "Log level to show --stats output DEBUG|INFO|NOTICE|ERROR" )
flags . FVarP ( flagSet , & fs . Config . BwLimit , "bwlimit" , "" , "Bandwidth limit in kBytes/s, or use suffix b|k|M|G or a full timetable." )
2020-06-20 17:10:02 +02:00
flags . FVarP ( flagSet , & fs . Config . BwLimitFile , "bwlimit-file" , "" , "Bandwidth limit per file in kBytes/s, or use suffix b|k|M|G or a full timetable." )
2018-08-15 13:23:57 +02:00
flags . FVarP ( flagSet , & fs . Config . BufferSize , "buffer-size" , "" , "In memory buffer size when reading files for each --transfer." )
2018-01-12 17:30:54 +01:00
flags . FVarP ( flagSet , & fs . Config . StreamingUploadCutoff , "streaming-upload-cutoff" , "" , "Cutoff for switching to chunked upload if file size is unknown. Upload starts after reaching cutoff or when file ends." )
flags . FVarP ( flagSet , & fs . Config . Dump , "dump" , "" , "List of items to dump from: " + fs . DumpFlagsList )
2018-04-21 23:03:27 +02:00
flags . FVarP ( flagSet , & fs . Config . MaxTransfer , "max-transfer" , "" , "Maximum size of data to transfer." )
2019-07-25 12:28:27 +02:00
flags . DurationVarP ( flagSet , & fs . Config . MaxDuration , "max-duration" , "" , 0 , "Maximum duration rclone will transfer data for." )
2020-02-25 18:03:21 +01:00
flags . FVarP ( flagSet , & fs . Config . CutoffMode , "cutoff-mode" , "" , "Mode to stop transfers when reaching the max transfer limit HARD|SOFT|CAUTIOUS" )
2018-07-19 23:41:34 +02:00
flags . IntVarP ( flagSet , & fs . Config . MaxBacklog , "max-backlog" , "" , fs . Config . MaxBacklog , "Maximum number of objects in sync or check backlog." )
2019-07-23 17:45:07 +02:00
flags . IntVarP ( flagSet , & fs . Config . MaxStatsGroups , "max-stats-groups" , "" , fs . Config . MaxStatsGroups , "Maximum number of stats groups to keep in memory. On max oldest is discarded." )
2018-08-16 17:32:35 +02:00
flags . BoolVarP ( flagSet , & fs . Config . StatsOneLine , "stats-one-line" , "" , fs . Config . StatsOneLine , "Make the stats fit on one line." )
2019-03-26 03:41:45 +01:00
flags . BoolVarP ( flagSet , & fs . Config . StatsOneLineDate , "stats-one-line-date" , "" , fs . Config . StatsOneLineDate , "Enables --stats-one-line and add current date/time prefix." )
flags . StringVarP ( flagSet , & fs . Config . StatsOneLineDateFormat , "stats-one-line-date-format" , "" , fs . Config . StatsOneLineDateFormat , "Enables --stats-one-line-date and uses custom formatted date. Enclose date string in double quotes (\"). See https://golang.org/pkg/time/#Time.Format" )
2019-12-18 12:52:20 +01:00
flags . BoolVarP ( flagSet , & fs . Config . ErrorOnNoTransfer , "error-on-no-transfer" , "" , fs . Config . ErrorOnNoTransfer , "Sets exit code 9 if no files are transferred, useful in scripts" )
2018-06-30 17:05:31 +02:00
flags . BoolVarP ( flagSet , & fs . Config . Progress , "progress" , "P" , fs . Config . Progress , "Show progress during transfer." )
2019-01-11 18:35:29 +01:00
flags . BoolVarP ( flagSet , & fs . Config . Cookie , "use-cookies" , "" , fs . Config . Cookie , "Enable session cookiejar." )
2018-05-22 15:48:23 +02:00
flags . BoolVarP ( flagSet , & fs . Config . UseMmap , "use-mmap" , "" , fs . Config . UseMmap , "Use mmap allocator (see docs)." )
2019-02-11 14:09:32 +01:00
flags . StringVarP ( flagSet , & fs . Config . CaCert , "ca-cert" , "" , fs . Config . CaCert , "CA certificate used to verify servers" )
flags . StringVarP ( flagSet , & fs . Config . ClientCert , "client-cert" , "" , fs . Config . ClientCert , "Client SSL certificate (PEM) for mutual TLS auth" )
flags . StringVarP ( flagSet , & fs . Config . ClientKey , "client-key" , "" , fs . Config . ClientKey , "Client SSL private key (PEM) for mutual TLS auth" )
2019-04-24 18:04:40 +02:00
flags . FVarP ( flagSet , & fs . Config . MultiThreadCutoff , "multi-thread-cutoff" , "" , "Use multi-thread downloads for files above this size." )
flags . IntVarP ( flagSet , & fs . Config . MultiThreadStreams , "multi-thread-streams" , "" , fs . Config . MultiThreadStreams , "Max number of streams to use for multi-thread downloads." )
2019-07-26 02:54:09 +02:00
flags . BoolVarP ( flagSet , & fs . Config . UseJSONLog , "use-json-log" , "" , fs . Config . UseJSONLog , "Use json log format." )
2019-11-28 18:01:21 +01:00
flags . StringVarP ( flagSet , & fs . Config . OrderBy , "order-by" , "" , fs . Config . OrderBy , "Instructions on how to order the transfers, eg 'size,descending'" )
2020-02-10 08:50:08 +01:00
flags . StringArrayVarP ( flagSet , & uploadHeaders , "header-upload" , "" , nil , "Set HTTP header for upload transactions" )
flags . StringArrayVarP ( flagSet , & downloadHeaders , "header-download" , "" , nil , "Set HTTP header for download transactions" )
2020-04-23 16:24:21 +02:00
flags . StringArrayVarP ( flagSet , & headers , "header" , "" , nil , "Set HTTP header for all transactions" )
2020-06-16 17:24:54 +02:00
flags . BoolVarP ( flagSet , & fs . Config . RefreshTimes , "refresh-times" , "" , fs . Config . RefreshTimes , "Refresh the modtime of remote files." )
2020-02-10 08:50:08 +01:00
}
// ParseHeaders converts the strings passed in via the header flags into HTTPOptions
func ParseHeaders ( headers [ ] string ) [ ] * fs . HTTPOption {
opts := [ ] * fs . HTTPOption { }
for _ , header := range headers {
parts := strings . SplitN ( header , ":" , 2 )
if len ( parts ) == 1 {
log . Fatalf ( "Failed to parse '%s' as an HTTP header. Expecting a string like: 'Content-Encoding: gzip'" , header )
}
option := & fs . HTTPOption {
Key : strings . TrimSpace ( parts [ 0 ] ) ,
Value : strings . TrimSpace ( parts [ 1 ] ) ,
}
opts = append ( opts , option )
}
return opts
2018-01-12 17:30:54 +01:00
}
2019-04-30 14:06:24 +02:00
// SetFlags converts any flags into config which weren't straight forward
2018-01-12 17:30:54 +01:00
func SetFlags ( ) {
if verbose >= 2 {
fs . Config . LogLevel = fs . LogLevelDebug
} else if verbose >= 1 {
fs . Config . LogLevel = fs . LogLevelInfo
}
if quiet {
if verbose > 0 {
log . Fatalf ( "Can't set -v and -q" )
}
fs . Config . LogLevel = fs . LogLevelError
}
logLevelFlag := pflag . Lookup ( "log-level" )
if logLevelFlag != nil && logLevelFlag . Changed {
if verbose > 0 {
log . Fatalf ( "Can't set -v and --log-level" )
}
if quiet {
log . Fatalf ( "Can't set -q and --log-level" )
}
}
2019-07-26 02:54:09 +02:00
if fs . Config . UseJSONLog {
logrus . AddHook ( fsLog . NewCallerHook ( ) )
logrus . SetFormatter ( & logrus . JSONFormatter {
TimestampFormat : "2006-01-02T15:04:05.999999-07:00" ,
} )
logrus . SetLevel ( logrus . DebugLevel )
switch fs . Config . LogLevel {
case fs . LogLevelEmergency , fs . LogLevelAlert :
logrus . SetLevel ( logrus . PanicLevel )
case fs . LogLevelCritical :
logrus . SetLevel ( logrus . FatalLevel )
case fs . LogLevelError :
logrus . SetLevel ( logrus . ErrorLevel )
case fs . LogLevelWarning , fs . LogLevelNotice :
logrus . SetLevel ( logrus . WarnLevel )
case fs . LogLevelInfo :
logrus . SetLevel ( logrus . InfoLevel )
case fs . LogLevelDebug :
logrus . SetLevel ( logrus . DebugLevel )
}
}
2018-01-12 17:30:54 +01:00
if dumpHeaders {
fs . Config . Dump |= fs . DumpHeaders
2017-12-29 18:32:28 +01:00
fs . Logf ( nil , "--dump-headers is obsolete - please use --dump headers instead" )
2018-01-12 17:30:54 +01:00
}
if dumpBodies {
fs . Config . Dump |= fs . DumpBodies
2017-12-29 18:32:28 +01:00
fs . Logf ( nil , "--dump-bodies is obsolete - please use --dump bodies instead" )
2018-01-12 17:30:54 +01:00
}
switch {
case deleteBefore && ( deleteDuring || deleteAfter ) ,
deleteDuring && deleteAfter :
log . Fatalf ( ` Only one of --delete-before, --delete-during or --delete-after can be used. ` )
case deleteBefore :
fs . Config . DeleteMode = fs . DeleteModeBefore
case deleteDuring :
fs . Config . DeleteMode = fs . DeleteModeDuring
case deleteAfter :
fs . Config . DeleteMode = fs . DeleteModeAfter
default :
fs . Config . DeleteMode = fs . DeleteModeDefault
}
2019-07-08 03:02:53 +02:00
if fs . Config . CompareDest != "" && fs . Config . CopyDest != "" {
log . Fatalf ( ` Can't use --compare-dest with --copy-dest. ` )
}
2019-03-26 03:41:45 +01:00
switch {
case len ( fs . Config . StatsOneLineDateFormat ) > 0 :
fs . Config . StatsOneLineDate = true
fs . Config . StatsOneLine = true
case fs . Config . StatsOneLineDate :
fs . Config . StatsOneLineDateFormat = "2006/01/02 15:04:05 - "
fs . Config . StatsOneLine = true
}
2018-01-12 17:30:54 +01:00
if bindAddr != "" {
addrs , err := net . LookupIP ( bindAddr )
if err != nil {
log . Fatalf ( "--bind: Failed to parse %q as IP address: %v" , bindAddr , err )
}
if len ( addrs ) != 1 {
log . Fatalf ( "--bind: Expecting 1 IP address for %q but got %d" , bindAddr , len ( addrs ) )
}
fs . Config . BindAddr = addrs [ 0 ]
}
if disableFeatures != "" {
if disableFeatures == "help" {
log . Fatalf ( "Possible backend features are: %s\n" , strings . Join ( new ( fs . Features ) . List ( ) , ", " ) )
}
fs . Config . DisableFeatures = strings . Split ( disableFeatures , "," )
}
2020-02-10 08:50:08 +01:00
if len ( uploadHeaders ) != 0 {
fs . Config . UploadHeaders = ParseHeaders ( uploadHeaders )
}
if len ( downloadHeaders ) != 0 {
fs . Config . DownloadHeaders = ParseHeaders ( downloadHeaders )
}
2020-04-23 16:24:21 +02:00
if len ( headers ) != 0 {
fs . Config . Headers = ParseHeaders ( headers )
}
2020-02-10 08:50:08 +01:00
2018-01-12 17:30:54 +01:00
// Make the config file absolute
configPath , err := filepath . Abs ( config . ConfigPath )
if err == nil {
config . ConfigPath = configPath
}
2019-08-12 23:09:40 +02:00
// Set whether multi-thread-streams was set
multiThreadStreamsFlag := pflag . Lookup ( "multi-thread-streams" )
fs . Config . MultiThreadSet = multiThreadStreamsFlag != nil && multiThreadStreamsFlag . Changed
2018-01-12 17:30:54 +01:00
}