summary history files

internal/cli/cr2dupe.go
package cli

import (
	"fmt"
	"log"
	"os"
	"path"
	"path/filepath"
	"strings"

	"github.com/spf13/cobra"
	"github.com/spf13/viper"
	"golang.org/x/sync/errgroup"
)

func deleter(c <- chan string) {
	// {filename: ext}
	type imageFile struct {
		filePath string
		fileExt string
	}
	imageFiles := map[string]imageFile{}
	for file := range c {
		filepathWithoutExt := strings.TrimSuffix(file, filepath.Ext(file))
		if existingImageFile, exists := imageFiles[filepathWithoutExt]; exists {
			existingExt := existingImageFile.fileExt
			if strings.ToLower(existingExt) == ".cr2" {
				fmt.Printf("deleting %s\n", existingImageFile.filePath)
				err := os.Remove(existingImageFile.filePath)
				if err != nil {
					log.Fatal(fmt.Sprintf("Failed deleting %s: %v", existingImageFile.filePath, err))
				}
			} else {
				fmt.Printf("need to delete %s,%s\n", existingImageFile.filePath, file)
			}
			continue
		}
		imageFiles[filepathWithoutExt] = imageFile{file, filepath.Ext(file)}
	}
}

func cr2DupeCmd(cli *cli) *cobra.Command {
	var flags struct {
		imageDir  string
	}
	var cmd = &cobra.Command{
		Use: "cr2dupe",
		PreRun: func(cmd *cobra.Command, args []string) {
			_ = viper.BindPFlag("image-dir", cmd.Flags().Lookup("image-dir"))
		},
		RunE: func(cmd *cobra.Command, args []string) error {
			g, ctx := errgroup.WithContext(cmd.Context())
			c := make(chan string)
			g.Go(func() error {
				defer close(c)
				return filepath.Walk(flags.imageDir, func(p string, info os.FileInfo, err error) error {
					if !info.Mode().IsRegular() {
						return nil
					}

					if strings.HasPrefix(path.Base(p), ".") {
						return nil
					}

					if info.Size() == 0 {
						return nil
					}

					switch strings.ToLower(filepath.Ext(p)) {
					case ".jpg", ".jpeg", ".cr2":
					default:
						return nil
					}

					select {
					case c <- p:
					case <-ctx.Done():
						return ctx.Err()
					}
					return nil
				})
			})

			deleter(c)

			// End of pipeline.
			if err := g.Wait(); err != nil {
				return err
			}

			return nil
		},
	}
	cmd.Flags().StringVar(&flags.imageDir, "image-dir", "", "Image directory")
	cmd.MarkFlagRequired("image-dir")

	return cmd
}