Add explicit force replacement workflow
This commit is contained in:
@@ -292,6 +292,82 @@ func (b *Backend) DeleteManagedBundle(ctx context.Context, bundlePath string, ma
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Backend) DeletePrefix(ctx context.Context, prefix string, opts storage.DeleteOptions) error {
|
||||
if err := ctx.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := storage.ValidatePrefix(prefix); err != nil {
|
||||
return err
|
||||
}
|
||||
var entries []storage.Entry
|
||||
if prefix != "" {
|
||||
entry, err := b.Stat(ctx, prefix)
|
||||
if err != nil {
|
||||
if opts.IgnoreMissing && storage.IsNotFound(err) {
|
||||
return nil
|
||||
}
|
||||
return err
|
||||
}
|
||||
if entry.Type != storage.EntryTypeDirectory {
|
||||
return b.deleteEntry(ctx, entry, opts)
|
||||
}
|
||||
entries = append(entries, entry)
|
||||
}
|
||||
if err := b.Walk(ctx, prefix, storage.WalkOptions{Recursive: true}, func(entry storage.Entry) error {
|
||||
entries = append(entries, entry)
|
||||
return nil
|
||||
}); err != nil {
|
||||
return err
|
||||
}
|
||||
if prefix != "" && len(entries) == 1 {
|
||||
if err := b.deleteEntry(ctx, entries[0], opts); err != nil {
|
||||
return err
|
||||
}
|
||||
if opts.PruneEmptyDirs {
|
||||
b.pruneEmptyParents(parentOf(prefix))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
sort.Slice(entries, func(i, j int) bool {
|
||||
return strings.Count(entries[i].Path, "/") > strings.Count(entries[j].Path, "/")
|
||||
})
|
||||
for _, entry := range entries {
|
||||
if entry.Path == "" {
|
||||
continue
|
||||
}
|
||||
if err := b.deleteEntry(ctx, entry, storage.DeleteOptions{IgnoreMissing: true}); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if opts.PruneEmptyDirs {
|
||||
b.pruneEmptyParents(parentOf(prefix))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Backend) deleteEntry(ctx context.Context, entry storage.Entry, opts storage.DeleteOptions) error {
|
||||
if err := ctx.Err(); err != nil {
|
||||
return err
|
||||
}
|
||||
nativePath, err := b.nativePath(entry.Path, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var removeErr error
|
||||
if entry.Type == storage.EntryTypeDirectory {
|
||||
removeErr = b.client.RemoveDirectory(nativePath)
|
||||
} else {
|
||||
removeErr = b.client.Remove(nativePath)
|
||||
}
|
||||
if removeErr != nil {
|
||||
if opts.IgnoreMissing && isNotExist(removeErr) {
|
||||
return nil
|
||||
}
|
||||
return b.translateError(storage.OpDeletePrefix, entry.Path, removeErr)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *Backend) walkDirectory(ctx context.Context, logicalPrefix, nativePrefix string, opts storage.WalkOptions, emit func(storage.Entry) error) error {
|
||||
entries, err := b.client.ReadDir(nativePrefix)
|
||||
if err != nil {
|
||||
|
||||
Reference in New Issue
Block a user