in oss/lib/sync.go [472:602]
func (sc *SyncCommand) RunCommand() error {
sc.syncOption.bDelete, _ = GetBool(OptionDelete, sc.command.options)
sc.syncOption.encodingType, _ = GetString(OptionEncodingType, sc.command.options)
sc.syncOption.backupDir, _ = GetString(OptionBackupDir, sc.command.options)
// for list file
sc.syncOption.enableSymlinkDir, _ = GetBool(OptionEnableSymlinkDir, sc.command.options)
sc.syncOption.onlyCurrentDir, _ = GetBool(OptionOnlyCurrentDir, sc.command.options)
sc.syncOption.disableDirObject, _ = GetBool(OptionDisableDirObject, sc.command.options)
sc.syncOption.disableAllSymlink, _ = GetBool(OptionDisableAllSymlink, sc.command.options)
sc.syncOption.force, _ = GetBool(OptionForce, sc.command.options)
// check point dir
sc.syncOption.cpDir, _ = GetString(OptionCheckpointDir, sc.command.options)
// payer
payer, _ := GetString(OptionRequestPayer, sc.command.options)
if payer != "" {
if payer != strings.ToLower(string(oss.Requester)) {
return fmt.Errorf("invalid request payer: %s, please check", payer)
}
sc.syncOption.payerOptions = append(sc.syncOption.payerOptions, oss.RequestPayer(oss.PayerType(payer)))
}
// filters
var res bool
res, sc.syncOption.filters = getFilter(os.Args)
if !res {
return fmt.Errorf("--include or --exclude does not support format containing dir info")
}
for k, v := range sc.syncOption.filters {
LogInfo("filter %d,name:%s,pattern:%s\n", k, v.name, v.pattern)
}
srcURL, err := StorageURLFromString(sc.command.args[0], sc.syncOption.encodingType)
if err != nil {
return err
}
destURL, err := StorageURLFromString(sc.command.args[1], sc.syncOption.encodingType)
if err != nil {
return err
}
if srcURL.IsFileURL() && destURL.IsFileURL() {
return fmt.Errorf("not support sync between local directory")
}
if srcURL.IsFileURL() {
f, err := os.Stat(srcURL.ToString())
if err != nil {
return err
}
if !f.IsDir() {
return fmt.Errorf("src %s is not directory", srcURL.ToString())
}
}
if !sc.syncOption.bDelete {
return copyCommand.RunCommand()
}
// sync command add '/' afert cloud prefix
// cp command must have the same action when run as sync command
srcURL = sc.adjustCloudUrl(srcURL)
destURL = sc.adjustCloudUrl(destURL)
// check backup dir
if destURL.IsFileURL() {
err = sc.CheckDestBackupDir(destURL)
if err != nil {
return err
}
}
opType := sc.getCommandType(srcURL, destURL)
// get file list or object key list
srcKeys := make(map[string]string)
destKeys := make(map[string]string)
if srcURL.IsFileURL() {
err = sc.GetLocalFileKeys(srcURL, srcKeys)
} else {
err = sc.GetOssKeys(srcURL, srcKeys)
}
if err != nil {
return err
}
if destURL.IsFileURL() {
err = sc.GetLocalFileKeys(destURL, destKeys)
} else {
err = sc.GetOssKeys(destURL, destKeys)
}
if err != nil {
return err
}
// Get keys to be deleted
bSame := (string(os.PathSeparator) == "/")
for k, _ := range srcKeys {
if bSame || opType == operationTypeCopy {
delete(destKeys, k)
} else if opType == operationTypePut {
delete(destKeys, strings.Replace(k, "\\", "/", -1))
} else {
delete(destKeys, strings.Replace(k, "/", "\\", -1))
}
}
if destURL.IsFileURL() {
fmt.Printf("\nfile(directory) will be removed count:%d\n", len(destKeys))
} else {
fmt.Printf("\nobject will be deleted count:%d\n", len(destKeys))
}
err = copyCommand.RunCommand()
if err != nil {
return err
}
// move dest files or rm dest objects which not exist in src
if opType == operationTypeCopy || opType == operationTypePut {
err = sc.DeleteExtraObjects(destKeys, destURL)
} else {
err = sc.RemoveExtraFiles(destKeys, destURL)
}
return err
}