ste/overwritePrompter.go (78 lines of code) (raw):

// Copyright © Microsoft <wastore@microsoft.com> // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. package ste import ( "fmt" "strings" "sync" "github.com/Azure/azure-storage-azcopy/v10/common" ) // asks questions to confirm overwrite, one routine at a time, i.e. only one active question at a time type overwritePrompter struct { lock *sync.Mutex // whether we should still ask the user for permission to overwrite the destination // if false, the user has already specified a "for all" answer shouldPromptUser map[common.EntityType]bool // if the user made a "for all" selection, save the response here savedResponse map[common.EntityType]bool } func (o *overwritePrompter) ShouldOverwrite(objectPath string, objectType common.EntityType) (shouldOverwrite bool) { // only one routine can ask the question or check the saved response at a time o.lock.Lock() defer o.lock.Unlock() if o.shouldPromptUser[objectType] { shouldOverwrite = o.promptForConfirmation(objectPath, objectType) } else { shouldOverwrite = o.savedResponse[objectType] } return } func (o *overwritePrompter) promptForConfirmation(objectPath string, objectType common.EntityType) (shouldOverwrite bool) { question := fmt.Sprintf("%s already exists at the destination. "+ "Do you wish to overwrite?", objectPath) if objectType == common.EEntityType.Folder() { question = fmt.Sprintf("Folder %s already exists at the destination. "+ "Do you wish to overwrite its properties?", objectPath) } answer := common.GetLifecycleMgr().Prompt(question, common.PromptDetails{ PromptType: common.EPromptType.Overwrite(), PromptTarget: objectPath, ResponseOptions: []common.ResponseOption{ common.EResponseOption.Yes(), common.EResponseOption.No(), common.EResponseOption.YesForAll(), common.EResponseOption.NoForAll()}, }) switch answer { case common.EResponseOption.Yes(): common.GetLifecycleMgr().Info(fmt.Sprintf("Confirmed. %s will be overwritten.", objectPath)) return true case common.EResponseOption.YesForAll(): common.GetLifecycleMgr().Info(fmt.Sprintf("Confirmed. All future %s conflicts will be overwritten.", strings.ToLower(objectType.String()))) o.shouldPromptUser[objectType] = false o.savedResponse[objectType] = true return true case common.EResponseOption.No(): common.GetLifecycleMgr().Info(fmt.Sprintf("%s will be skipped", objectPath)) return false case common.EResponseOption.NoForAll(): name := strings.ToLower(objectType.String()) if objectType == common.EEntityType.Folder() { name += " properties" } common.GetLifecycleMgr().Info(fmt.Sprintf("No %s will be overwritten from now onwards.", name)) o.shouldPromptUser[objectType] = false o.savedResponse[objectType] = false return false default: common.GetLifecycleMgr().Info(fmt.Sprintf("Unrecognizable answer, skipping %s.", objectPath)) return false } } func newOverwritePrompter() *overwritePrompter { return &overwritePrompter{ lock: &sync.Mutex{}, shouldPromptUser: map[common.EntityType]bool{ common.EEntityType.Folder(): true, common.EEntityType.File(): true, }, savedResponse: map[common.EntityType]bool{ common.EEntityType.Folder(): false, common.EEntityType.File(): false, }, } }