func()

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
}