Repository: syncthing/syncthing
File: lib/model/folder_recvenc.go (Go)

Code before:
	"fmt"

	"github.com/syncthing/syncthing/lib/config"
	"github.com/syncthing/syncthing/lib/db"
	"github.com/syncthing/syncthing/lib/events"
	"github.com/syncthing/syncthing/lib/fs"
	"github.com/syncthing/syncthing/lib/ignore"
	"github.com/syncthing/syncthing/lib/protocol"
	"github.com/syncthing/syncthing/lib/versioner"
)

func init() {
	// A receiveEncrypted folder behaves just like send-receive folder,
	// except for scanning which is handled in folder.
	folderFactories[config.FolderTypeReceiveEncrypted] = newReceiveEncryptedFolder
}

type receiveEncryptedFolder struct {
	*sendReceiveFolder
}

func newReceiveEncryptedFolder(model *model, fset *db.FileSet, ignores *ignore.Matcher, cfg config.FolderConfiguration, ver versioner.Versioner, fs fs.Filesystem, evLogger events.Logger, ioLimiter *byteSemaphore) service {
	return &receiveOnlyFolder{newSendReceiveFolder(model, fset, ignores, cfg, ver, fs, evLogger, ioLimiter).(*sendReceiveFolder)}
}

func (f *receiveOnlyFolder) CleanEnc() {
	f.doInSync(func() error { f.revert(); return nil })
}

func (f *receiveOnlyFolder) cleanEnc() {
	l.Infof("Cleaning not encrypted items from folder %v", f.Description)

	f.setState(FolderScanning)
	defer f.setState(FolderIdle)

	batch := newFileInfoBatch(func(fs []protocol.FileInfo) error {
		f.updateLocalsFromScanning(fs)
		return nil
	})

	snap := f.fset.Snapshot()
	defer snap.Release()
	var iterErr error
	snap.WithHaveTruncated(protocol.LocalDeviceID, func(intf protocol.FileIntf) bool {
		if iterErr = batch.flushIfFull(); iterErr != nil {
			return false
		}

		fit := intf.(db.FileInfoTruncated)
		if !fit.IsReceiveOnlyChanged() || intf.IsDeleted() || protocol.IsEncryptedPath(fit.Name) {
			return true

Review comment (suggestion):
The types here should probably be receiveEncryptedFolder , which can do whatever they need to do  and then call

f.sendReceiveFolder.Revert()

to get rid of the CleanEnc madness.

Code after:
	"fmt"
	"sort"

	"github.com/syncthing/syncthing/lib/config"
	"github.com/syncthing/syncthing/lib/db"
	"github.com/syncthing/syncthing/lib/events"
	"github.com/syncthing/syncthing/lib/fs"
	"github.com/syncthing/syncthing/lib/ignore"
	"github.com/syncthing/syncthing/lib/protocol"
	"github.com/syncthing/syncthing/lib/versioner"
)

func init() {
	folderFactories[config.FolderTypeReceiveEncrypted] = newReceiveEncryptedFolder
}

type receiveEncryptedFolder struct {
	*sendReceiveFolder
}

func newReceiveEncryptedFolder(model *model, fset *db.FileSet, ignores *ignore.Matcher, cfg config.FolderConfiguration, ver versioner.Versioner, fs fs.Filesystem, evLogger events.Logger, ioLimiter *byteSemaphore) service {
	return &receiveEncryptedFolder{newSendReceiveFolder(model, fset, ignores, cfg, ver, fs, evLogger, ioLimiter).(*sendReceiveFolder)}
}

func (f *receiveEncryptedFolder) Revert() {
	f.doInSync(func() error { f.revert(); return nil })
}

func (f *receiveEncryptedFolder) revert() {
	l.Infof("Reverting unexpected items in folder %v (receive-encrypted)", f.Description)

	f.setState(FolderScanning)
	defer f.setState(FolderIdle)

	batch := newFileInfoBatch(func(fs []protocol.FileInfo) error {
		f.updateLocalsFromScanning(fs)
		return nil
	})

	snap := f.fset.Snapshot()
	defer snap.Release()
	var iterErr error
	var dirs []string
	snap.WithHaveTruncated(protocol.LocalDeviceID, func(intf protocol.FileIntf) bool {
		if iterErr = batch.flushIfFull(); iterErr != nil {
			return false
		}

		fit := intf.(db.FileInfoTruncated)
		if !fit.IsReceiveOnlyChanged() || intf.IsDeleted() {
			return true