func statusCheckFile(file *entities.File, report *StatusReport) error { relPath := path.Rel(file.Path()) log.Infof(2, "%v: checking file status.", file.Path()) stat, err := os.Stat(file.Path()) if err != nil { switch { case os.IsNotExist(err): log.Infof(2, "%v: file is missing.", file.Path()) report.AddRow(Row{relPath, MISSING}) return nil case os.IsPermission(err): log.Warnf("%v: permission denied.", file.Path()) case strings.Contains(err.Error(), "not a directory"): report.AddRow(Row{relPath, MISSING}) return nil default: return fmt.Errorf("%v: could not stat: %v", file.Path(), err) } } else { if stat.Size() != file.Size || stat.ModTime().UTC() != file.ModTime { log.Infof(2, "%v: file is modified.", file.Path()) report.AddRow(Row{relPath, MODIFIED}) } else { log.Infof(2, "%v: file is unchanged.", file.Path()) report.AddRow(Row{relPath, TAGGED}) } } return nil }
func findDuplicatesInDb() error { store, err := storage.Open() if err != nil { return fmt.Errorf("could not open storage: %v", err) } defer store.Close() log.Info(2, "identifying duplicate files.") fileSets, err := store.DuplicateFiles() if err != nil { return fmt.Errorf("could not identify duplicate files: %v", err) } log.Infof(2, "found %v sets of duplicate files.", len(fileSets)) for index, fileSet := range fileSets { if index > 0 { fmt.Println() } fmt.Printf("Set of %v duplicates:\n", len(fileSet)) for _, file := range fileSet { relPath := _path.Rel(file.Path()) fmt.Printf(" %v\n", relPath) } } return nil }
func listFiles(files entities.Files, dirOnly, fileOnly, topOnly, leafOnly, recursive, print0, showCount, onePerLine bool) error { tree := path.NewTree() for _, file := range files { tree.Add(file.Path(), file.IsDir) } if topOnly { tree = tree.TopLevel() } else { if recursive { fsFiles, err := path.Enumerate(tree.TopLevel().Paths()) if err != nil { return err } for _, fsFile := range fsFiles { tree.Add(fsFile.Path, fsFile.IsDir) } } } if leafOnly { tree = tree.Leaves() } if fileOnly { tree = tree.Files() } if dirOnly { tree = tree.Directories() } absPaths := tree.Paths() if showCount { fmt.Println(len(absPaths)) } else { relPaths := make([]string, len(absPaths)) for index, absPath := range absPaths { relPaths[index] = path.Rel(absPath) } sort.Strings(relPaths) if onePerLine || print0 { for _, relPath := range relPaths { if print0 { fmt.Printf("%v\000", relPath) } else { fmt.Println(relPath) } } } else { format.Columns(relPaths, terminalWidth()) } } return nil }
func findNewFiles(searchPath string, report *StatusReport, dirOnly bool) error { log.Infof(2, "%v: finding new files.", searchPath) relPath := path.Rel(searchPath) if !report.ContainsRow(relPath) { report.AddRow(Row{relPath, UNTAGGED}) } absPath, err := filepath.Abs(searchPath) if err != nil { return fmt.Errorf("%v: could not get absolute path: %v", searchPath, err) } stat, err := os.Stat(absPath) if err != nil { switch { case os.IsNotExist(err): return nil case os.IsPermission(err): log.Warnf("%v: permission denied.", searchPath) return nil default: return fmt.Errorf("%v: could not stat: %v", searchPath, err) } } if !dirOnly && stat.IsDir() { dir, err := os.Open(absPath) if err != nil { return fmt.Errorf("%v: could not open file: %v", searchPath, err) } dirNames, err := dir.Readdirnames(0) if err != nil { return fmt.Errorf("%v: could not read directory listing: %v", searchPath, err) } for _, dirName := range dirNames { dirPath := filepath.Join(searchPath, dirName) err = findNewFiles(dirPath, report, dirOnly) if err != nil { return err } } } return nil }
func findDuplicatesOf(paths []string, recursive bool) error { store, err := storage.Open() if err != nil { return fmt.Errorf("could not open storage: %v", err) } defer store.Close() fingerprintAlgorithmSetting, err := store.Setting("fingerprintAlgorithm") if err != nil { return fmt.Errorf("could not retrieve fingerprint algorithm: %v", err) } wereErrors := false for _, path := range paths { _, err := os.Stat(path) if err != nil { switch { case os.IsNotExist(err): log.Warnf("%v: no such file", path) wereErrors = true continue case os.IsPermission(err): log.Warnf("%v: permission denied", path) wereErrors = true continue default: return err } } } if wereErrors { return blankError } if recursive { p, err := _path.Enumerate(paths) if err != nil { return fmt.Errorf("could not enumerate paths: %v", err) } paths = make([]string, len(p)) for index, path := range p { paths[index] = path.Path } } first := true for _, path := range paths { log.Infof(2, "%v: identifying duplicate files.", path) fp, err := fingerprint.Create(path, fingerprintAlgorithmSetting.Value) if err != nil { return fmt.Errorf("%v: could not create fingerprint: %v", path, err) } if fp == fingerprint.Fingerprint("") { continue } files, err := store.FilesByFingerprint(fp) if err != nil { return fmt.Errorf("%v: could not retrieve files matching fingerprint '%v': %v", path, fp, err) } absPath, err := filepath.Abs(path) if err != nil { return fmt.Errorf("%v: could not determine absolute path: %v", path, err) } // filter out the file we're searching on dupes := files.Where(func(file *entities.File) bool { return file.Path() != absPath }) if len(paths) > 1 && len(dupes) > 0 { if first { first = false } else { fmt.Println() } fmt.Printf("%v:\n", path) for _, dupe := range dupes { relPath := _path.Rel(dupe.Path()) fmt.Printf(" %v\n", relPath) } } else { for _, dupe := range dupes { relPath := _path.Rel(dupe.Path()) fmt.Println(relPath) } } } return nil }